为什么我会出现分段错误?

时间:2013-04-15 14:04:20

标签: assembly x86-64 gas

我编译代码

  

gcc -g3 hello3.s -o hello

.data

ssttrr:
  .string "%d\n"

.text
.globl main

main:

  mov $213, %rdx
  push %rdx
  push $ssttrr
  call printf
  add  $8, %rsp

mov  $60, %rax
xor  %rdi, %rdi
syscall

我理解错误,但我不知道如何解决它。我甚至不知道什么时候出错。 cpy:intel-64 os:debian

1 个答案:

答案 0 :(得分:1)

x86_64的默认调用约定已更改,它现在不仅使用堆栈,还使用寄存器传递参数:

  

传递

     

一旦参数被分类,寄存器就会被分配(从左到右   传递如下:

     
      
  1. 如果类是MEMORY,则在堆栈上传递参数。
  2.   
  3. 如果类是INTEGER,则序列%rdi的下一个可用寄存器,   %rsi,%rdx,%rcx,%r8和%r9用于 *   
  4. 如果类是SSE,则使用下一个可用的SSE寄存器,寄存器为   从%xmm0到%xmm7。
  5. 的顺序         

    ...

         

    *请注意,%r11既不需要保留,也不用于传递参数。使该寄存器作为临时寄存器可用意味着PLT中的代码在计算需要传输控制的地址时不需要溢出任何寄存器。 %raxis用于指示传递给需要可变数量参数的函数的SSE参数的数量。 %r10用于传递函数的静态链指针。

您可能希望分别传入%rdi和%rsi寄存器中的字符串和整数值,而不是直接将它们推送到堆栈中:

mov $213, %esi ;%d is not a 64-bit integer
mov $ssttrr, %rdi
mov $0, %rax ;no sse registers as arguments
call printf