只能push16位或者32位的寄存器或者内存。
栈顶在push或者pop之后加几,取决于指令之后是多少位的寄存器或者内存,比如push eax ,ac转为a8,之后pop ax,a8转为aa
pushad指令
ebp(栈底)esp(栈顶)的值不能乱改,因为里面的内存是系统分配的。
将六个寄存器的值改的明显一点,使用pushad指令
pushad指令就将八个寄存器的值存入了堆栈中。然后我们就可以更改寄存器里的值,改完之后,通过popad还原原本寄存器里的值
标志寄存器
1、进位标志CF
如果运算结果的最高位产生了一个进位或者借位,那么,其值为1,否则其值为0.
EFL转化为二进制:0000001000010010(能看到AF为1)
2、奇偶标志PF
用于反映运算结果中“1”的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则其值为0.
现在总数为6二进制就是0110,两个“1”是偶数,所以右边的p为1.
3、辅助进位标志AF
在发生下列情况时,辅助进位标志AF的值变为1,否则为0
(1)在字操作时,发生低字节向高字节进位或借位时;
(2)在字节操作时,发生低4位向高4位进位或借位时;
FFFFFFFF FFFF FF(也就是加粗的位置发生进位,AF就会变为1)
4、零标志位ZF
用来反映运算结果是否为0。为0则ZF=1,反之为0
XOR:异或,用XOR EAX,EAX 可以达到清零的作用
MOV EAX,0也可以
但是区别在于:MOV指令不修改寄存器的值,且不影响标志寄存器
5、符号表示SF
反映运算结果的符号位,它与运算结果的最高位相同
6、溢出标志OF
有符号数的溢出用OF,无符号数的溢出用CF
溢出主要给有符号运算使用的,在有符号运算中,规律如下:
正 + 正 = 正 如果结果有负数,说明溢出。
负 + 负 = 负 如果结果有正数,说明溢出。
正 + 负 永远都不会溢出
ADC指令(带进位加法)
格式:ADC R/M,R/M/IMM(R是寄存器M是内存IMM是立即数,两边不能都是内存,且宽度要一样)
也就是ADC X,Y结果为:X=X+Y+CF
执行指令之后为B也就是9+1+1(CF)=B
SBB指令(带借位减法)
格式:SBB R/M,R/M/IMM(两边不能都是内存,且宽度要一样)
SBB X,Y结果为X=X-Y-CF
XCHG指令(交换指令)
格式:XCHG R/M,R/M(两边不能都是内存,且宽度要一样)
MOVS指令(移动数据)
MOVS BYTE PTR DS:[EDI],BYTE PTR DS:[ESI] 简写:MOVSB
MOVS WORD PTR DS:[EDI],WORD PTR DS:[ESI] 简写:MOVSW
MOVS DWORD PTR DS:[EDI],DWORD PTR DS:[ESI] 简写:MOVSD
7、方向标志DF
当DF为0的时候:MOVS WORD PTR DS:[EDI],WORD PTR DS:[ESI],这两个寄存器的值各自加2。
当DF为1的时候:MOVS WORD PTR DS:[EDI],WORD PTR DS:[ESI],这两个寄存器的值各自减2.(DWORD的时候是-4或者+4)
STOS指令
将AL/AX/EAX的值存储到[EDI]指定的内存单元
STOS BYTE PTR ES:[EDI] 简称为STOSB
STOS WORD PTR ES:[EDI] 简称为STOSW
STOS DWORD PTR ES:[EDI] 简称为STOSD
REP指令
按计数寄存器(ECX)中指定的次数重复执行字符串命令
REP STOSD(不停的向EDI中存储EAX的值,+4或者-4,取决于DF的值)