pushad & pushfd



pushad: 将所有的32位通用寄存器压入堆栈

pusha:将所有的16位通用寄存器压入堆栈

pushfd:然后将32位标志寄存器EFLAGS压入堆栈

pushf::将的16位标志寄存器EFLAGS压入堆栈

popad:将所有的32位通用寄存器取出堆栈

popa:将所有的16位通用寄存器取出堆栈

popfd:将32位标志寄存器EFLAGS取出堆栈

popf:将16位标志寄存器EFLAGS取出堆栈

 

_asm pushad

_asm pushfd

// 处理代码

_asm popfd

_asm popad

&&**************************************************for xiao mai********************************************************&&

&&********************************************************************************************************************&&

函数调用之前pushad保存所有寄存器的值,然后在函数执行完成之后popad恢复寄存器的值。
例子:
_fun proc arg1,agr2
local @ret
pushad
执行具体的操作...
把结果赋值给@ret
popad
mov eax,@ret
ret
_fun endp

我认为最后的mov eax,@ret 在popad后面执行破坏了eax寄存器的原始状态,这个函数执行完毕eax寄存器的值和执行前的值不同。

不过在cdecl以及stdcall调用约定下,eax寄存器用于返回函数的返回值,因此是一定会被破坏的。
编译器会根据调用约定规定寄存器的使用方式,事先约定好了非易失性寄存器(non-volatile registers)和易失性寄存器。非易失性寄存器就是指在一次函数调用之后,该寄存器依然会保持原有的值,易失性寄存器自然就是在函数调用后可能会被改变的寄存器。
例如x64约定有16个通用寄存器以及16个供浮点数使用的XMM寄存器,其中rax、rcx、rdx、r8-r11,以及xmm0-xmm5是易失性寄存器,函数调用后其中的值可能会被改变,剩下的就是非易失性寄存器,函数需要在返回后保证其中的值不被改变。如果在函数内部需要用到这些非易失性寄存器,那么需要先push到栈里,在返回到caller前将其pop出来,以保证遵守约定,所以也有云:pushad是一种简单粗暴的保存方式。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值