PUSHA/PUSHAD,POPA/POPAD它们配合使用,用于8个16位/32位通用寄存器与堆栈之间的数据传送。
PUSHAD指令压入32位寄存器,使他们按照EDI,ESI,EBP,ESP,EBX,EDX,ECX,最后是EAX的顺序出现在堆栈中,POPAD使弹出的顺序正好相反。
PUSHA/PUSHAD,POPA/POPAD从80286处理器开始使用.执行PUSHA/PUSHAD,POPA/POPAD时,其堆栈指针SP将分别需要减16/32和加16/32.
POPAD不会影响ESP ,但是会影响EBP。
#include <iostream>
using namespace std;
typedef unsigned long ULONG;
//该程序只为调使用,无法正确返回。
typedef struct __REGISTERS_
{
ULONG EDI; //0
ULONG ESI; //4
ULONG EBP; //8
ULONG ESP; //12
ULONG EBX; //16
ULONG EDX; //20
ULONG ECX; //24
ULONG EAX; //28
ULONG EFlags; //32
}REGISTERS,*pREGISTERS;
int main()
{
REGISTERS Regs={0};
Regs.ESP=0x12345678;
// __asm mov esp,Regs.ESP //修改ESP可以利用直接赋值的方式解决。
__asm
{
PUSH DWORD PTR Regs.EAX
PUSH DWORD PTR Regs.ECX
PUSH DWORD PTR Regs.EDX
PUSH DWORD PTR Regs.EBX
PUSH DWORD PTR Regs.ESP
PUSH DWORD PTR Regs.EBP
PUSH DWORD PTR Regs.ESI
PUSH DWORD PTR Regs.EDI
POPAD //调试在此处设置断点,所有的通用寄存器均被设置为0,除了ESP。注意,EBP也被赋值。
}
return 0;
}