为什么在这段汇编代码中调用"pop"会导致分段错误? [英] Why does calling 'pop' in this piece of assembly code cause a segmentation fault?
问题描述
我正在Mac OS上使用x86-64程序集(使用NASM 2.09和2.13来捕获由NASM问题引起的错误).我现在正在尝试实现函数调用,并尝试使用push
和pop
指令,但是pop
似乎总是导致段错误:
I'm playing around with x86-64 assembly on Mac OS (using NASM 2.09 and 2.13, to catch bugs caused by NASM issues). I'm trying to implement function calls at the moment, and tried using the push
and pop
instructions, but the pop
always seems to cause a segfault:
line 10: 41072 Segmentation fault: 11 ./result
我尝试手动调整rsp
,rbp
等,但是pop
似乎是问题所在.任何帮助将不胜感激!
I've tried adjusting rsp
, rbp
etc manually, but the pop
seems to be the issue. Any help would be appreciated!
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
推荐答案
在问题所示的代码中,call
指令将返回地址放在堆栈上,而pop
指令从堆栈中删除返回地址(将其放入r12
).
In the code shown in the question, the call
instruction puts the return address on the stack and the pop
instruction removes the return address from the stack (putting it into r12
).
然后ret
指令从堆栈中弹出4
并跳转到那里.这不是有效的代码地址,从而导致故障. ret
基本上只是pop
到RIP.
The ret
instruction then pops 4
from the stack and jumps there. That isn't a valid code address, causing the fault. ret
is basically just pop
into RIP.
要访问堆栈中函数的参数,请使用[rsp + 8]
,[rsp + 16]
等,而不是pop
.
To access parameters to a function that are on the stack, use [rsp + 8]
, [rsp + 16]
, etc., instead of pop
.
x86-64的标准调用约定在寄存器中而不是在堆栈中传递整数args,被调用者可以在其中直接使用它们.并且避免了调用者在函数返回后必须清理堆栈. (有2种:Linux/MacOS/etc与Windows,使用不同的寄存器.)
The standard calling conventions for x86-64 pass integer args in registers instead of the stack, where the callee can use them directly. And avoids the caller having to clean the stack after the function returns. (There are 2: Linux/MacOS/etc. vs. Windows, using different registers.)
这篇关于为什么在这段汇编代码中调用"pop"会导致分段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!