分段故障调用printf

时间:2016-02-13 23:17:54

标签: assembly x86

.text
    .global main
main:
  pushq $10
  popq %rdx
  movq $formatString, %rdi
  call printf
    mov $0,%rax
    ret
.data
 formatString:
.string "%d\n"

此代码给我一个分段错误。 这很简单。将10推入堆栈。从堆栈中弹出10并将其放入rdx。将我的formatString移动到rdi。打电话给printf。那就是它。

为什么它会给我一个分段错误?

谢谢!

1 个答案:

答案 0 :(得分:1)

此代码可以工作:

.text
    .global main
main:
  add $-8, %rsp             # Stack is misaligned by 8 after call to main
                            # Subtract 8 to align it on 16-byte boundary
  xor %rax, %rax            # RAX = 0 since no vector registers used for calling printf 
                            # This is important for functions that take variable 
                            # number of arguments
  movq $formatString, %rdi  # First parameter (format) in RDI
  movq $10, %rsi            # second parameter in RSI not RDX
  call printf

  add $8, %rsp              # Restore stack to proper state
  ret

.data
 formatString:
.string "%ld\n"             # If printing longs use %ld

而不是add $-8, %rspadd $8, %rsp用于堆栈对齐,您可以使用任何可以将堆栈调整8个字节的内容。 push %rbxpop %rbx也会有效。

或者你可以替换:

 movq $formatString, %rdi  # First parameter (format) in RDI

使用:

leaq formatString(%rip), %rdi

后者使用RIP相对寻址而不是绝对寻址。

有关Linux 64位System V ABI的更多信息,请参阅此document