汇编指令retn用来结束当前过程返回到上一调用过程
当retn指令执行时是将esp指向地址得值弹出到EIP指令指针寄存器
实际就是执行了一次pop eip 然后esp+4 紧接着开始执行eip指向的地址
rern指令执行前esp指向0041FC9C ,EIP指向002225c7
堆栈中0041fc9c保存的是00222714
retn指令执行后ESP指向0041FCA0,EIP指向00222714
也就是说retn指令执行后把esp指向地址保存的数据弹出到eip
然后esp+0x4 相当于执行了pop eip
EIP指向00222714 准备从这个地址开始执行指令 add esp,0x4
(add esp,0x4是为了平衡堆栈,因为调用这个函数之前push了一个参数当过程调用完毕需要把esp恢复到调用过程之前的位置,这叫外部平栈,是_cdcal的平栈方式 _cdcal为函数调用约定,其它调用约定有_stdcal _fastcal)
add esp,0x4执行完之后esp指向0041FCA4
再看另一种retn方式
retn 0x4执行前 esp指向 001AFDF4,EIP指向00129253D
ESP指向地址保存的是 0129270A
retn 0x4指令执行后 esp指向001AFDFC,EIP指向00129270A
ESP加了0x8
因为push了一个参数
retn0x4 相当于执行了pop,eip add esp,0x4
相当于直接在过程内部平衡了堆栈
这是_stdcal 的调用方式