我试图了解在OS X机器上调用子程序时究竟发生了什么(因为这就是我面前的情况)。我正在使用nasm
版本0.98.40。
我阅读了一些主要针对其他平台的教程,并注意到其中一些有定义
_syscall:
int 0x80
ret
所以,我尝试了一个简单的hello世界,有或没有那个子程序,但在其他方面相同。
我很难理解为什么call
子例程在这种情况下不直接使用它的“等效”。我不认为我打扰了系统调用所需的任何寄存器。
以下是两个汇编文件。
; without_subr.asm
section .text
global start
start:
push dword msg.len
push dword msg
push dword 1
mov eax,4
sub esp,4
int 0x80
add esp,16
push dword 0
mov eax, 1
sub esp, 12
int 0x80
section .data
msg: db 'Hello, world!',10
msg.len: equ $ - msg
并使用子程序:
; with_subr.asm
section .text
global start
_syscall:
int 0x80
ret
start:
push dword msg.len
push dword msg
push dword 1
mov eax,4
sub esp,4
call _syscall
add esp,16
push dword 0
mov eax, 1
sub esp, 12
int 0x80
section .data
msg: db 'Hello, world!',10
msg.len: equ $ - msg
当我汇编,链接和运行without_subr.asm
时,一切都按预期工作:
$ nasm -f macho without_subr.asm
$ ld -o without_subr without_subr.o
$ ./without_subr
Hello, world!
但是,with_subr.asm
不产生任何异常退出
$ nasm -f macho with_subr.asm
$ ld -o with_subr with_subr.o
$ ./with_subr
Exit 1
答案 0 :(得分:2)
当您call
子程序时,返回地址被压入堆栈。堆栈上的额外值会将您push
预先设置的值保留在错误的位置。