x86_64汇编代码的意外行为

时间:2014-02-02 21:53:39

标签: assembly code-generation x86-64

我目前正在处理汇编代码。 我写了一个程序,它生成了以下代码。 生成的代码正是我所期望的,但是当我读到它时,我的正常行为是汇编代码将写入stdout无限数量的'1'(在无限循环中)。问题是它只写一个'1'字符并关闭而没有seg错误。

那么,我真的错过了这段代码?我写了一些评论来帮助我理解它,但在阅读并再次阅读之后,我看不出问题出在哪里。 我的代码中是否存在我不理解的副作用?

感谢。

.text
.globl main
main:   

    push    %rbx
    push    %rbp
    mov     %rsp,%rbp
    mov     $208,%r10
    push    %rdi
    mov     %r10,%rdi
    call    test
    pop     %rdi
    mov     %rbp,%rsp
    pop     %rbp
    mov     %r9,%rax
    pop     %rbx
    ret

test:
    push    %rbp
    mov     %rsp,%rbp

    mov     $9,%rax     # Reserve memory slot for var i
    push    %rax        #

    mov     $9,%rax     # Reserve memory slot for var p
    push    %rax        #

    mov     $196,%r10   # 196 -> r10
    mov %r10,8(%rsp)    # r10 -> i

    jmp loop

loop:
    mov     $512,%r10   # 512 -> r10
    mov     8(%rsp),%r11    # i -> r11
    cmp     %r10,%r11   # CMP 512 i
    mov     %r11,8(%rsp)    # r11 -> i

    jl      less
    jmp     end

less:
    #mov     $40,%r10   # 40 -> r10
    push    %rdi        # Save rdi (fs+1)
    mov     16(%rsp),%r11   # i -> r11
    mov     %r11,%rdi   # r11 -> rdi
    call    putchar     # call putchar
    pop     %rdi        # Restore rdi (fs-1)
    #mov     %r10,(%rsp)    # r10 -> p
    mov     %r11,8(%rsp)    # r11 -> i
    jmp     loop

end:
    mov     %rbp,%rsp
    pop     %rbp
    ret

putchar:
    mov     %rdi,%rax
    sar     $2,%rax
    push    %rax
    mov     %rsp,%rsi
    mov     $1,%rdx
    mov     $1,%rdi
    mov     $1,%rax
    syscall
    pop     %rax
    mov     $9,%rax
    ret

修改

解决方案:编写系统调用修改r11寄存器

1 个答案:

答案 0 :(得分:1)

System V应用程序二进制接口AMD64架构处理器补充部分 A.2 AMD64 Linux内核约定除其他外,还说:

  

系统调用通过syscall指令完成。内核   销毁寄存器%rcx和%r11。