1、push和pop指令演示入栈出栈,对内存,寄存器,立即数三种情况模拟
push
内存
push dword ptr ds:[0x12FFDC] |
[0x12FFDC]地址与对应的值

原始堆栈

运行后,栈顶地址减小,数值和地址 [0x12FFDC] 的数值相同

寄存器
push ebx |
EBX的值

原始堆栈

运行结果,栈顶地址减小,数值和寄存器 EBX 的数值相同

立即数
push 0x12345678 |
原始堆栈(注意栈顶)

运行后,栈顶地址减小,数值与输入的立即数的数值相同

pop
内存
pop dword ptr ds:[0x12FFF0] |
地址[0x12FFF0]

原始堆栈

运行后,地址[0x12FFF0]值改变为弹出的堆栈中的值

栈顶指针地址增加

寄存器
pop EAX |
EAX

原始堆栈

运行后,弹出数据,EAX寄存器值改变为弹出的堆栈中的值

栈顶指针地址增加

立即数
pop 不支持直接操作立即数
2、使用mov,lea,sub,add等指令模拟push和pop的行为
模拟push
push eax |
sub esp,0x4 |
EAX

栈顶

执行命令后,栈顶指针减小,且 eax 寄存器的值被压入栈

模拟pop
pop ebx |
EBX

栈顶

执行命令后,栈顶指针大小增加,数据弹出到 ebx 寄存器


3、演示六种标志寄存器发生变化的情况
进位标志CF
(主要记录无符号数)CF = 1 表示有进位或借位,CF = 0 表示没有进位或借位
原始 CF 位

EAX

运行
add al, 44h |

奇偶标志PF
运算结果中 1 个数为偶数时 PF = 1,反之(只计算最低的一个字节)
EAX

原 PF 位

计算
add ax, 11h |

辅助进位标志AF
进行字节(byte)操作时,低 4 位发生进位或借位时 AF = 1,反之
进行字(word)操作时,低 8 位发生进位或借位时 AF = 1,反之
EAX

AF 位

执行
add al, 15h |

零标志ZF
运算结果为 0 时 ZF = 1,反之 ZF = 0
EAX 和 EBX 寄存器

原始 ZF

运行
sub EAX, EBX |

符号标志SF
(针对有符号数)运算结果为负 SF = 1,反之 SF = 0
EAX

SF 标志位

执行
sub ax, 3h |

溢出标志OF
(主要针对有符号数)运算结果超过当前位数所表示的数的范围,则为溢出 OF = 1,反之 OF = 0
例如:16 位有符号数最大 32767,最小 - 32768,计算 32767 + 1 时,由于表示的最大的数为 32767 (7FFF),+ 1 后就是 8000 符号位为 1 变成负数了,但却是两个正数相加,这种情况就叫溢出
EAX

OF 标志位

执行
add ax, 1h |

方向标志DF
标识移动移动方向,0 增加,1 减少
