当我调用printf时,为什么这个汇编程序是segfaulting?

时间:2017-02-14 21:05:11

标签: assembly segmentation-fault printf x86-64

以下代码因为调用printf:

而给我一个分段错误
            .text
    .global main
main:    
    push %r13
    push %r14
    push %r15
    jmp rest
f:
    pop %rbx
    movq $0, %rax
    push %rbx
    movq $1, %r9
    pushq %r9
    mov $format,%rdi
    popq %rsi
    movq %rsi, %r15
    pop %rbx
    call printf
    push %rbx
    movq $1, %r9
    pushq %r9
    mov $format,%rdi
    popq %rsi
    movq %rsi, %r15
    pop %rbx
    call printf
    push %rbx
    ret
func:
    pop %rbx
    movq $0, %rax
    push %rbx
    call f
    push %rax
    popq %rsi
    movq %rsi, %r15
    .data
    xfunc:    .quad   0
    .text
    mov %r15,xfunc
    ret
rest:
    call func
    push %rax
    mov $format,%rdi
    popq %rsi
    movq %rsi, %r15
    call printf
    mov $0,%rax
    pop %r15
    pop %r14
    pop %r13
    ret
    .data
format:    .string "%lu\n"

如果在标签f中取出打印变量的第二次调用printf,则没有分段错误。此外,如果我直接从休息中调用标签f,则没有分段错误。

1 个答案:

答案 0 :(得分:4)

根据X86_64 ABI:

Register    Usage
%rax        temporary register; with variable arguments
            passes information about the number of vector
            registers used; 1st return register

对于printf的情况,向量寄存器的数量为0。

您第一次拨打printf会将您的%rax注册设置为2(它用作返回值)。

请确保在第二次通话之前将其设置回$0,就是这样......