如何解决正确还原被调用方保存的寄存器
我试图正确地理解将ebx
之类的被调用者保存的寄存器压入/弹出堆栈的位置和方式,以恢复它们以供以后使用。
此代码是否正确恢复了ebx
寄存器?
global main
extern printf
section .text:
print:
mov eax,0x1
add eax,ebx
push eax
push message
call printf
add esp,8
ret
main:
mov ebx,0x1
push ebx
call print
pop ebx
ret
message db "result = %d",10,0
使用后是否应立即弹出ebx
?
global main
extern printf
section .text:
print:
push ebx
mov ebx,0x1
mov eax,8
pop ebx
ret
main:
call print
ret
message db "result = %d",0
解决方法
两种方法都可以,但是第二种则比较传统。
规则是这样的:当编译器生成代码以调用函数时,它假定ebx的内容在调用后与以前相同。在您的程序中,唯一适用的情况是调用main
的启动代码。对于您的两个版本的代码,ebx
返回时main
的值与输入时相同,因此一切正常。
如果您的程序中有一个名为print
的C函数,则第一个版本将是错误的,而第二个版本将是必需的。但是,正如第一个版本中的情况一样,print
仅从您的手动编码main
函数中调用,并且您知道print
会破坏ebx
,并且您采取了适当的措施保存和还原它的操作,就可以了。
换句话说,在代码的第一个版本中,print
不符合标准的C调用约定。但是,由于您从未真正从C代码调用过它,所以这不一定是问题。在第二个版本中,它确实符合要求,从美学上讲可能更好,而且维护起来也不太混乱。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。