标志寄存器_JCC
标志寄存器
自己学会拆EFL
- 进位标志CF(Carry Flag): 如果运算结果的最高位产生了一个进位或借位,要确定数据宽度,比如add al,1 只要al进位了,就会改变标志位
无符号关注CF位
- 奇偶标志位PF(Parity Flag): 奇偶标志位PF用于反映运算结果中’1’的个数的奇偶性,如果为偶数,则为1, 反之为0
mov al,3 011
add al,3 110 #P为1
add al,2 1000 #P为0
- 辅助进位标志AF(Auxiliary Carry Flag):
以下情况,AF为1,否则为0
1) 在字操作时,发生低字节向高字节进位或借位时
2) 在字节操作时,发生低4位向高四位进位或借位时
mov eax,55eeffff
add eax,2
低四位+2进位了,所以AF为1
mov ax,5efe
add ax,2
就看fe进位没,进位了,所以AF为1
注意这里要看bit
- 零标志位ZF(Zero Flag):零标志ZF用来反映运算结果是否为0
xor eax,eax 清0同时还会影响标志位
mov eax,0 清0 不影响标志位
- 符号标志SF(Sign Flag): 运算结果的符号位,与运算结果最高位相同
mov al,7f
add al,2
- 溢出标志OF(Overflow Flag)
进位标志表示无符号数运算结果是否超出范围
溢出主要是给有符号运算使用
- 正+正=正 如果结果是负数,则说明溢出了
- 负+负=负 如果结果是整数,则说明溢出了
- 正+负 永远不会溢出
理解那个圈,那个圈挺有用的
1. 无符号,有符号都不溢出
mov al,8
add al,8
2. 无符号溢出,有符号不溢出
mov al,0ff
add al,2
无符号超过了,溢出,有符号,-1+2 = 1肯定不溢出
3. 无符号不溢出,有符号溢出
mov al,7f
add al,2
有符号,7f和2都是正数,+过后变成负数了,所以溢出了
4. 无符号,有符号都溢出
mov al,0fe
add al,80
fe负数,80负数 加起来是正数,
无符号,也溢出了,超过最大的ff了
- 方向标志DF(Direction Flag)
指令
ADC指令带进位加法
ADC R/M,R/M/IMM 两边不能同时为内存,宽度要一样
SBB带借位减法
SBB R/M,R/M/IMM 两边不能同时为内存,宽度要一样
XCHG 交换数据
XCHG R/M, R/M 不能为立即数啊,想想变量a跟1交换是什么鬼
MOVS 移动数据 内存-内存
都是内存
只有edi跟esi能用
movs byte ptr es:[edi],byte ptr ds:[esi]
简写
- movsb byte
- movsw word
- movsd dword
D标志为1,esi跟edi减,D标志为0,+
STOS 将AL/AX/EAX的值存储到[edi]指定的内存单元
stos byte ptr es:[edi]
简写
- stosb
- stosw
- stosd
方向由D位决定
REP 按ecx指定的次数重复执行
mov ecx,10
rep movsd
就是重复movsd 16次
课后练习
熟练记住CF/PF/AF/ZF/SF/OF的位置
汇编练习:
- 只影响CF
mov ax,0xff
shr ax,1
shr会将最低位移入cf
mov ax,0xff00
add ax,0x101
要使得最高位进位,低位不进位
只影响PF
mov ax,1
xor ax,2只影响AF
mov al,0x8
add al,0x8只影响SF
mov ah,0x71
xor ah,0x80
mov ah,0xf8
add ah,0x5
- 只影响OF
mov al,0x80
sub al,0x10
mov ax,0x7f00
add ax,0x201
加法只能让S先为1,然后才不会影响标志位的值,负数+负数=正数必定进位
MOVS移动5个字节,5个字,5个双字
mov edi,0x18FF8C
mov esi,0x18FFB4
movs byte ptr es:[edi],byte ptr ds:[esi]
movs byte ptr es:[edi],byte ptr ds:[esi]
movs byte ptr es:[edi],byte ptr ds:[esi]
movs byte ptr es:[edi],byte ptr ds:[esi]
movs byte ptr es:[edi],byte ptr ds:[esi]
…
…
…STOS指令存储5个字节,5个字,5个双字
stos byte ptr es:[edi]
…
…
…
- 使用REP指令重写7,8题
mov ecx,0x5
rep movs byte ptr es:[edi],byte ptr ds:[esi]
jcc
修改eip
jmp 影响eip的值 jmp reg/imm
call 也影响eip的值 call imm/reg
push 当前指令地址+指令长度地址,mov eip,imm/reg
retn 相当于pop eip
cmp指令
cmp只修改标志寄存器,相当于sub,
作用比较大小,看sf
是否等于0,看zf
test指令
test R/M,R/M/IMM
实质是&
test eax,eax 判断eax是不是0
jcc跳转
jcc指令 | 说明 | 条件 |
---|---|---|
JE, JZ | 结果为零则跳转(相等时跳转) | ZF=1 |
JNE, JNZ | 结果不为零则跳转(不相等时跳转) | ZF=0 |
JS | 结果为负则跳转 | SF=1 |
JNS | 结果为非负则跳转 | SF=0 |
JP, JPE | 结果中1的个数为偶数则跳转 | PF=1 |
JNP, JPO | 结果中1的个数为偶数则跳转 | PF=0 |
JO | 结果溢出了则跳转 | OF=1 |
JNO | 结果没有溢出则跳转 | OF=0 |
JB, JNAE | 小于则跳转 (无符号数) | CF=1 |
JNB, JAE | 大于等于则跳转 (无符号数) | CF=0 |
JBE, JNA | 小于等于则跳转 (无符号数) | CF=1 or ZF=1 |
JNBE, JA | 大于则跳转(无符号数) | CF=0 and ZF=0 |
JL, JNGE | 小于则跳转 (有符号数) | SF≠ OF |
JNL, JGE | 大于等于则跳转 (有符号数) | SF=OF |
JLE, JNG | 小于等于则跳转 (有符号数) | ZF=1 or SF≠ OF |
JNLE, JG | 大于则跳转(有符号数) | ZF=0 and SF=OF |
本文作者:NoOne
本文地址: https://noonegroup.xyz/posts/21d61358/
版权声明:转载请注明出处!