为什么在这段汇编代码中调用“ pop”会导致分段错误?

时间:2019-09-28 23:45:12

标签: assembly x86-64 nasm

我正在Mac OS上使用x86-64程序集(使用NASM 2.09和2.13来捕获由NASM问题引起的错误)。我目前正在尝试实现函数调用,并尝试使用pushpop指令,但是pop似乎总是造成段错误:

  

line 10: 41072 Segmentation fault: 11 ./result

我尝试手动调整rsprbp等,但是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 

1 个答案:

答案 0 :(得分:5)

在问题所示的代码中,call指令将返回地址放入堆栈中,而pop指令从堆栈中删除返回地址(将其放入r12中)

然后ret指令从堆栈中弹出4并跳转到那里。这不是有效的代码地址,从而导致故障。 ret基本上只是pop进入RIP。


要访问堆栈中函数的参数,请使用[rsp + 8][rsp + 16]等,而不是pop

x86-64的标准调用约定在寄存器中而不是在堆栈中传递整数args,被调用者可以在其中直接使用它们。并且避免了调用者在函数返回后必须清理堆栈。 (有2种:Linux / MacOS / etc。vs. Windows,使用不同的寄存器。)