欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > 汇编语言:基于x86处理器考前笔记 | 第六章 条件处理

汇编语言:基于x86处理器考前笔记 | 第六章 条件处理

2025/1/19 1:58:25 来源:https://blog.csdn.net/everfoot/article/details/145216927  浏览:    关键词:汇编语言:基于x86处理器考前笔记 | 第六章 条件处理

以下是根据文档整理的汇编课程知识点:


重点难点概述

  1. 布尔指令与比较指令的使用方法及功能
    学习如何使用常见的布尔指令(andornotxortest)以及比较指令(cmp),并理解它们的作用和应用。
  2. 标志寄存器与各标志位的关联
    掌握各指令与标志寄存器中的标志位(如溢出标志 OF、方向标志 DF、中断标志 IF、符号标志 SF、零标志 ZF、辅助进位标志 AC、奇偶标志 PE、进位标志 CY)之间的关系,学会如何通过标志位的状态判断程序执行情况。

条件分支概念

  1. 条件分支
    条件分支是用于决策和控制程序流的机制。在高级语言中通过 ifswitchforwhile 等语句实现条件判断与流程控制,而在汇编语言中,虽然没有直接的语句支持,但可以通过条件跳转指令实现类似功能。
  2. 硬件控制中的位操作
    在硬件设备的控制中,常常需要操作数字的特定位,如测试、清除、置位等。汇编语言通过操作特定的标志位或数据位,来实现如电机启动、机器复位等硬件控制功能。

布尔指令与比较指令

  1. 布尔指令
    • and** 指令**:对两个操作数进行按位与操作。清零,交集
      示例:将字符 'a'01100001)转换为 'A'01000001),可以使用以下指令:
mov al, 01100001b  ; AL = 'a'
and al, 11011111b  ; AL = 'A'
- `or`** 指令**:对两个操作数进行按位或操作。并集  

示例:

mov al, 1110011b    ; AL = 1110011
or al, 00000100b    ; AL = 11100111
- `not`** 指令**:对操作数进行按位取反操作。补集  

示例:

mov al, 11110000b   ; AL = 11110000
not al              ; AL = 00001111
- `xor`** 指令**:对两个操作数进行按位异或操作,相同为 0,不同为 1。  

示例:

mov al, 10101010b   ; AL = 10101010
xor al, 11001100b   ; AL = 01100110
- `test`** 指令**:与 `and` 类似,但不改变目标操作数,常用于测试某些位。  

示例:

test al, 00001001b   ; 测试 AL 中的位 0 和位 3
; ZF = 1 (如果测试结果为 0),否则 ZF = 0
  1. **比较指令 **cmp
    cmp 用于比较源操作数与目标操作数。其通过将目标操作数减去源操作数,并根据结果更新标志位 ZFCFOF 来判断两者的关系。
    示例:
mov ax, 1000h      ; AX = 1000h
mov cx, 1000h      ; CX = 1000h
cmp cx, ax         ; 比较 CX 和 AX
; ZF = 1,表示两者相等

标志位操作

  1. **改变零标志位 **ZF
    使用以下指令可改变零标志位的值:
    • test al, 0(零标志位置 1)
    • and al, 0(零标志位置 1)
    • or al, 1(零标志位清零)
  2. **改变符号标志位 **SF
    • 使用 or al, 80h 可将符号标志位置为 1。
    • 使用 and al, 7Fh 可将符号标志位清零。
  3. **改变进位标志位 **CF
    • stc 指令将进位标志位置为 1。
    • clc 指令将进位标志位清零。
  4. **改变溢出标志位 **OF
    • 例如,mov al, 7Fhinc alAL80h,此时溢出标志位 OF 会被设置为 1,表示发生了溢出。
    • 使用 or eax, 0 可将溢出标志位清零。

重点难点

  • 理解条件跳转的原理及应用
    掌握不同类型条件跳转指令的使用条件和功能。学习如何通过比较指令(如 CMP)和标志位操作,结合条件跳转指令实现不同的流程控制。

条件跳转原理

  1. 高级语言与汇编语言中的条件判断
    在高级语言中,条件判断通常通过 ifswitch 等语句实现,而在汇编语言中,则通过比较指令(如 CMPANDSUB 等)先改变标志位,再通过条件跳转指令根据标志位的状态决定是否跳转。

示例

mov eax, 0        ; 将 0 赋值给 EAX
cmp eax, 0        ; 比较 EAX 和 0
jz L1             ; 如果 EAX 为 0,跳转到 L1
- **步骤**:1. 使用 `CMP`、`AND`、`SUB` 等指令改变标志位。2. 使用条件跳转指令(如 `JZ`、`JE` 等)检查标志位,根据条件决定是否跳转。

Jcond指令类型

  1. 基于特定标志位的值跳转
    根据标志位的状态决定是否跳转。常见的条件跳转指令包括:

示例

mov ax, 5
cmp ax, 4
je L1   ; 如果 ax == 4,跳转
jl L2   ; 如果 ax < 4,跳转
- `JZ`:当零标志位(ZF)为 1 时跳转(等于 0)。
- `JNZ`:当零标志位(ZF)为 0 时跳转(不等于 0)。
- `JC`:当进位标志位(CF)为 1 时跳转(有进位)。
- `JNC`:当进位标志位(CF)为 0 时跳转(无进位)。
- `JO`:当溢出标志位(OF)为 1 时跳转(溢出)。
- `JNO`:当溢出标志位(OF)为 0 时跳转(无溢出)。
- `JS`:当符号标志位(SF)为 1 时跳转(负数)。
- `JNS`:当符号标志位(SF)为 0 时跳转(非负数)。
- `JP`:当偶校验标志位(PF)为 1 时跳转(偶校验)。
- `JNP`:当偶校验标志位(PF)为 0 时跳转(奇校验)。
  1. 基于两数是否相等,或是否等于 ECX 寄存器的值跳转
    跳转指令包括:(E 等于)

示例

mov edx, 0A523h
cmp edx, 0A523h
je L1   ; 如果相等,跳转
jne L5  ; 如果不相等,跳转
- `JE`:相等跳转(`leftOp == rightOp`)。
- `JNE`:不相等跳转(`leftOp ≠ rightOp`)。
- `JCXZ`:当 `CX = 0` 时跳转。
- `JECXZ`:当 `ECX = 0` 时跳转。
- `JRCXZ`:当 `RCX = 0` 时跳转(64 位模式)。
  1. 基于无符号操作数的比较跳转
    这些指令用于无符号数的比较:【 A 大于,B 小于】

示例

mov ax, 5
cmp ax, 4
ja L1  ; 如果 ax > 4,跳转
jb L2  ; 如果 ax < 4,跳转
- `JA`:大于跳转,若 `leftOp  > rightOp`。
- `JB`:小于跳转,若 `leftOp < rightOp`。
- `JAE`:大于或等于跳转,若 `leftOp ≥ rightOp`。
- `JBE`:小于或等于跳转,若 `leftOp ≤ rightOp`。
- `JNBE`:不小于或等于跳转,与 `JA` 相同。
- `JNAE`:不大于或等于跳转,与 `JB` 相同。
  1. 基于有符号操作数的比较跳转
    这些指令用于有符号数的比较:【G 大于,L 小于】

示例

mov al, 127   ; AL = +127
cmp al, -128  ; 比较 AL 和 -128
ja IsAbove    ; 跳转,因 +127 < -128(不跳转)
- `JG`:大于跳转,若 `leftOp > rightOp`。
- `JL`:小于跳转,若 `leftOp < rightOp`。
- `JGE`:大于或等于跳转,若 `leftOp ≥ rightOp`。
- `JLE`:小于或等于跳转,若 `leftOp ≤ rightOp`。
- `JNLE`:不小于或等于跳转,与 `JG` 相同。
- `JNGE`:不大于或等于跳转,与 `JL` 相同。

条件循环指令

类似于 while,这里需要判断 ECX 循环次数和 ZF 条件

  1. LOOPZ** / LOOPE 指令**
    执行 ECX = ECX - 1 操作,如果 ECX > 0ZF = 1,则跳转到目标地址。
    • 用于判断循环次数并且 ZF 为 1 时跳转。
  2. LOOPNZ** / LOOPNE 指令**
    执行 ECX = ECX - 1 操作,如果 ECX > 0ZF = 0,则跳转到目标地址。
    • 用于判断循环次数并且 ZF 为 0 时跳转。


条件结构概述

  1. 条件结构的作用
    条件结构用于在不同的逻辑分支中依据条件表达式做出选择。在高级语言中,通常使用 if...else 等语句来实现,而在汇编语言中,需要将这些高级语言的条件结构转化为低级语言实现。理解汇编语言中如何实现条件结构是学习汇编的重要基础。

汇编实现条件结构的方式(事例分析)

  1. 一个分支情况
    • 对于高级语言中的 if(op1 == op2) { X = 1; Y = 2; },在汇编中实现时,先将 op1 送入 eax 寄存器,然后通过 cmp eax, op2 来比较 op1op2。若相等,则执行 mov X, 1mov Y, 2;若不相等,则跳过赋值指令。
    • 使用 jne 指令表示“不相等”时跳转,或者使用 je 指令表示“相等”时跳转到特定标签进行赋值操作。

汇编实现

mov eax, op1      ; 将 op1 送入 eax 寄存器
cmp eax, op2      ; 比较 eax 和 op2
je  L1            ; 如果相等,跳转到 L1 进行赋值
; 如果不相等,跳过赋值操作
jmp L2            ; 跳过赋值操作
L1:
mov X, 1          ; 执行赋值 X = 1
mov Y, 2          ; 执行赋值 Y = 2
  1. 两个分支情况
    • 对于 if (op1 > op2) call Routine1 else call Routine2,首先将 op1 送入 eax 寄存器,使用 cmp eax, op2 比较 op1op2,若 op1 > op2jg A1),则调用 Routine1,并跳转到 A2 结束;若不满足条件,则调用 Routine2

汇编实现

mov eax, op1      ; 将 op1 送入 eax 寄存器
cmp eax, op2      ; 比较 op1 和 op2
jg  Routine1      ; 如果 op1 > op2,跳转调用 Routine1
call Routine2     ; 否则调用 Routine2
  1. 分支嵌套情况
    • 对于 if op1 == op2 { if X > Y call Routine1 else call Routine2 } else call Routine3,首先比较 op1op2,若不相等则跳转到调用 Routine3;如果相等,则进一步比较 XY,根据比较结果调用 Routine1Routine2

汇编实现:对于嵌套可以使用不符合条件跳转(跳过{}中执行逻辑),符合条件往下执行{}。

mov eax, op1
cmp eax, op2
jne  Routine3        ; 如果 op1 不等于 op2,跳转调用 Routine3
; 如果 op1 == op2,继续判断 X 和 Y
mov eax, X
cmp eax, Y
jg  Routine1         ; 如果 X > Y,调用 Routine1
call Routine2        ; 否则调用 Routine2
  1. while 循环情况
    • 对于 while(val1 < val2) { val1++; val2--; },首先将 val1 复制到 eax,在循环中通过 cmp eax, val2 判断 val1 是否小于 val2,若不小于则退出循环。否则执行 val1++val2-- 操作,跳转到循环的起始位置继续判断。

汇编实现:对于循环用不符合条件跳转(跳过{}中执行逻辑),符合条件往下执行{}。同时在{}最后执行一个 jmp 无条件跳转回判断处

beginwhile:
mov eax, val1        ; 将 val1 赋值给 eax
cmp eax, val2        ; 比较 val1 和 val2
jnl endwhile         ; 如果 val1 >= val2,跳出循环
inc eax              ; val1++
mov val1, eax        ; 更新 val1
dec val2             ; val2--
mov eax, val2        ; 更新 val2
jmp beginwhile       ; 跳转回循环开始处
endwhile:

符合表达式与短路求值

  1. 短路求值
    对于复杂的条件表达式,如 if (al > b1) AND (b1 > c1),采用短路求值的方式。首先判断第一个条件 al > b1,若为假(即 cmp al, b1 不成立),则跳过后续的判断操作。若第一个条件为真,则继续判断第二个条件 b1 > c1,只有两个条件都为真时才执行后续操作(如 mov X, 1)。

汇编实现

cmp al, b1            ; 比较 al 和 b1
jna L1                ; 如果 al <= b1,跳过后续操作
cmp b1, c1            ; 如果 al > b1,继续比较 b1 和 c1
jna L1                ; 如果 b1 <= c1,跳过后续操作
mov X, 1              ; 执行后续操作
L1:

表驱动选择【没掌握】

  1. 表驱动方法
    使用查表方式代替多路选择。首先建立一个查找表,包含查询值(如字符)及对应的子程序偏移量。通过查找表中对应项来确定执行的子程序。可以通过计算表项大小(EntrySize = ($ - CaseTable))和表项数量来遍历和操作表。

汇编实现

INCLUDE Irvine32.inc
.data
CaseTable BYTE 'A'         ;查询值DWORD  Process_A ;过程地址
EntrySize = ($ - CaseTable)BYTE 'B'DWORD  Process_BBYTE 'C'DWORD  Process_CBYTE 'D'DWORD  Process_D
NumberOfEntries = ($ - CaseTable) / EntrySize
prompt BYTE "Press capital A,B,C,or D :",0

有限状态机(FSM)【没掌握】

  1. 概念
    有限状态机(FSM)是根据输入改变状态的机器或程序,包含状态节点和状态之间的转换边。FSM 结构类似于有向图,状态之间的转换由输入控制。
  2. 应用示例(验证输入字符串)
    假设输入字符串规则为:第一个和最后一个字符之间可以有多个字母(a...y),输入字符 x 可以使 A 状态转换为 B 状态;输入非 z 字母时 B 状态保持;输入 z 时,B 状态转换为 C 状态。若输入流结束时未处于 C 状态,则生成错误。

汇编实现

; 假设初始状态为 A
mov state, A; 遍历输入字符
check_input:
cmp char, 'x'           ; 检查字符是否为 'x'
je  A_to_B              ; 如果是 'x',从 A 状态转换到 B 状态
cmp char, 'z'           ; 检查字符是否为 'z'
je  B_to_C              ; 如果是 'z',从 B 状态转换到 C 状态
jmp check_inputA_to_B:
mov state, B
jmp check_inputB_to_C:
mov state, C
jmp check_input; 如果最终不在 C 状态,则报错
cmp state, C
jne error

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com