我在Mac OS上玩x86-64程序集(使用NASM 2.09和2.13,以捕获由NASM问题引起的错误)。我目前正在尝试实现函数调用,并尝试使用push
和pop
指令,但pop
始终似乎会导致段错误:
line 10: 41072 Segmentation fault: 11 ./result
我尝试手动调整rsp
,rbp
等等,但这pop
似乎是问题所在。任何帮助,将不胜感激!
section .data default rel global start section .text start: mov r12, 4 push r12 call label_0_print_digit (some stuff to exit program) label_0_print_digit: pop r12 (some stuff to print the digit - the issue persists even without this) ret
prl.. 5
在问题所示的代码中,call
指令将返回地址放在堆栈上,pop
指令从堆栈中删除返回地址(放入r12
)。
ret
然后,该指令4
从堆栈弹出并跳转到那里。这不是有效的代码地址,从而导致故障。 ret
基本上只是pop
进入RIP。
访问参数的函数,是在堆栈上,使用[rsp + 8]
,[rsp + 16]
而不是等pop
。
x86-64的标准调用约定在寄存器而不是堆栈中传递整数args,而被调用者可以在其中直接使用它们。并且避免了调用者在函数返回后必须清理堆栈。(有2种:Linux / MacOS / etc与Windows,使用不同的寄存器。)
在问题所示的代码中,call
指令将返回地址放在堆栈上,pop
指令从堆栈中删除返回地址(放入r12
)。
ret
然后,该指令4
从堆栈弹出并跳转到那里。这不是有效的代码地址,从而导致故障。 ret
基本上只是pop
进入RIP。
访问参数的函数,是在堆栈上,使用[rsp + 8]
,[rsp + 16]
而不是等pop
。
x86-64的标准调用约定在寄存器而不是堆栈中传递整数args,而被调用者可以在其中直接使用它们。并且避免了调用者在函数返回后必须清理堆栈。(有2种:Linux / MacOS / etc与Windows,使用不同的寄存器。)