您的位置:首页 > 其它

pushad & pushfd

2016-01-11 11:20 169 查看

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是一种简单粗暴的保存方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: