一:指令学习
1. push 指令
push m16/m32 esp=esp-m的内存宽度
push [立即数] esp=esp-4
push r16/r32
2. pop 指令
pop r16/r32 esp=esp+[寄存器数据宽度]
pop m16/m32 esp=esp+[容器宽度](word=2,dword=4)
3. pushad :把8个通用寄存器的值保存到堆栈。
popad:恢复到寄存器中
二:EFLAGS寄存器
1.进位标志位CF(Carry Flag):如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则为0.
MOV AL,0xEF MOV AL,0xFE
MOV AL,2 ADD AL,2
2.奇偶标志PF(Parity Flag):奇偶标志PF用于反映运算结果中最低字节包含“1”的个数的奇偶性。
如果“1”的个数为偶数,则PF=1,否则为PF=0
mov al,3 (0011) PF=1
add al,3 (0110) PF=1
add al,2 (1000) PF=0
3.辅助进位标志AF(Auxiliary Carry Flag):
在发生下列情况时,辅助标志位AF的值被置为1,否则为0
(1)在字(16位)操作时,发生低字节(低8位)向高字节(高8位)进位或者借位
(2)在字节操作时,发生低4位向高4位进位或者借位
mov eax,0x55EEFFFF mov ax,5EFE mov al,4e
add eax,2 add ax,2 add al,2
(F产生了进位,AF=1) (FE+2 产生了进位 AF=1) (E+2 产生了进位 AF=1)
4、零标志ZF(Zero Flag):零标志ZF用来反映运算结果是否为 0
如果运算结果为0,则其值为1,否则其值为 0。 在判断运算结果是否为0时,可以使用此标志位。
xor eax,eax
mov eax,2
sub eax,2
5、符号标志SF(Sign Flag):符号标志位用来反映运算结果的符号位,它与运算结果的最高位相同。
mov al,7f
add al,2 (CF=0,PF=1,AF=1,ZF=0,SF=1)
6、溢出标志位OF(Overflow Flag):溢出标志位OF用于反映有符号数加减运算所得结果是否溢出。
如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值为0
最高位进位与溢出的区别:
进位标志表示的是无符号运算结果时候超出了范围。
溢出标志表示的是有符号运算结果是否超出了范围。
溢出主要是给有符号运算使用的,有符号有如下的规律:
正 + 正 = ? 如果结果是负数,则说明有溢出
负 + 负 = ? 结果是正数,则说明有溢出
正 + 负 永远不会有溢出
1、无符号,有符号都不溢出
mov al,8
add al,8 (CF=0,PF=0,AF=1,ZF=0,SF=0,OF=0)
2、无符号溢出,有符号不溢出
mov al,off
add al,2 (CF=1,PF=0,AF=1,ZF=0,SF=0,OF=0)
3、无符号不溢出,有符号溢出
mov al,7f
add al,2
4、无符号,有符号都溢出
mov al,ofe
mov al,80
三、指令补充
1.ADC指令:带进位加法
格式: ADC R/M,R/M/IMM 两边不能同时为内存,宽度要一样
ADC AL,CL
ADC BYTE PTR DS:[12FFC4],2
ADC BYTE PTR DS:[12FFC4],AL
2.SBB指令:带借位减法
格式:SBB R/M,R/M 两边不能同时为内存 宽度要一样
SBB AL,CL
SBB BYTE PTR DS:[12FFC4],2
SBB BYTE PTR DS:[12FFC4],AL
3. XCHG指令:交换数据。 格式:XCHG R/M 两边不能同时为内存 宽度要一样
XCHG AL,CL
XCHG DWORD PTR DS:[12FFC4],EAX
XCHG BYTE PTR DS:[12FFC4],AL
4.MOVS指令:移动数据 内存-内存 BYTE/WORD/DWORD
MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 简写为:MOVSB
MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI] 简写为:MOVSW
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 简写为:MOVSD
MOV EDI,12FFD8
MOV ESI,12FFD0
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 观察EDI的值 (si与di的变化与方向标志位有关,DF=1,减去数据宽度
DF=0,加上数据宽度)
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
修改标志寄存器中D位的值,然后在执行下面的指令:
MOV EDI,12FFD8
MOV ESI,12FFD0
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 观察EDI的值
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
5.STOS指令:将Al/AX/EAX的值存储到[EDI]指定的内存单元 (存完之后,EDI的值是加还是减,是由方向标志位决定的)
STOS BYTE PTR ES:[EDI] 简写为STOSB
STOS WORD PTR ES:[EDI] 简写为STOSW
STOS DWORD PTR ES:[EDI] 简写为STOSD
MOV EAX,12345678
MOV EDI,12FFC4
STOS BYTE PTR ES:[EDI] 观察EDI的值
STOS WORD PTR ES:[EDI]
STOS DWORD PTR ES:[EDI]
修改标志寄存器中D位的值,然后在执行下面的指令:
MOV EAX,12345678
MOV EDI,12FFC4
STOS BYTE PTR ES:[EDI] 观察EDI的值
STOS WORD PTR ES:[EDI]
STOS DWORD PTR ES:[EDI]
6.REP指令:按计数寄存器 (ECX) 中指定的次数重复执行字符串指令
MOV ECX,10
REP MOVSD
REP STOSD