前言:进出堆栈中的数据的长度需要满足规定:必须是字(16位)或双字(32位)
进栈与出栈指令一般成对使用
通用进栈指令
- 格式:PUSH 源操作数
- 操作数:源操作数可以是字长为16位或32位的立即数、寄存器操作数或内存操作数。当源操作数是内存操作数时,注意是否需要加上PTR运算符
通用出栈指令
- 格式:POP 目标操作数
- 操作数:目标操作数可以是字长为16位或32位的寄存器或内存单元,除CS外的段寄存器。当源操作数是内存操作数时,注意是否需要加上PTR运算符
16位标志寄存器进/出栈指令
- 格式:PUSHF / POPF
- 功能:PUSHF将16位标志寄存器的内容压入堆栈,POPF从堆栈中弹出一个字装入16位标志寄存器中。多用于保护现场和恢复现场。
- 操作数:无显式操作数,隐式操作数是16位标志寄存器(FLAGS)
32位标志寄存器进/出栈指令
- 格式:PUSHFD / POPFD
- 功能:PUSHFD将32位标志寄存器的内容压入堆栈,POPFD从堆栈中弹出一个双字装入32位标志寄存器中。多用于保护现场和恢复现场。
- 操作数:无显式操作数,隐式操作数是32位标志寄存器(EFLAGS)
16位通用寄存器进/出栈指令
- 格式:PUSHA / POPA
- 功能:PUSHA执行时先保存当前堆栈指针中的地址值,然后调整堆栈指针,依次将AX、CX、DX、BX、SP(之前保存的值)、BP、SI、DI的内容压入堆栈,PUSHA执行完后,SP指向当前栈顶。POPA依次弹出3个字送入DI、SI、BP,相应地调整堆栈指针,然后再次调整堆栈指针:(SP)+2→(SP)以跳过堆栈中保存的SP值,接着继续从堆栈中弹出4个字依次送入BX、DX、CX、AX,最后相应地调整堆栈指针。因此,POPA执行完后,SP指针仍然指向当前栈顶,该栈顶位置与PUSHA指令执行前相同,其余7个寄存器的值恢复为PUSHA指令执行前的值。
- 操作数:无显式操作数,隐式操作数是AX、CX、DX、BX、SP、BP、SI、DI共8个16位通用寄存器
32位通用寄存器进/出栈指令
- 格式:PUSHAD / POPAD
- 功能:PUSHAD执行时先保存当前堆栈指针ESP中的地址值,然后调整堆栈指针,依次将EAX、ECX、EDX、EBX、ESP(之前保存的值)、EBP、ESI、EDI的内容压入堆栈。POPAD依次弹出3个双字送入EDI、ESI、EBP,相应地调整堆栈指针,然后再次调整堆栈指针:(ESP)+4→(ESP)以跳过堆栈中保存的SP值,接着继续从堆栈中弹出4个双字依次送入EBX、EDX、ECX、EAX,最后相应地调整堆栈指针。因此,POPAD执行完后,ESP指针仍然指向当前栈顶,该栈顶位置与PUSHAD指令执行前相同,其余7个寄存器的值恢复为PUSHAD指令执行前的值。
- 操作数:无显式操作数,隐式操作数是EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI共8个32位通用寄存器