%eax不减少? (ATT大会)

时间:2015-10-16 14:37:36

标签: assembly x86-64 calling-convention att

我是AT& T程序集的新手,我正在学习使用减量运算符decl来创建一个打印Hello world! 5次的程序。

以下是代码:

.data

hello:
    .ascii  "Hello world!"

   .text
loop:
    decl    %eax
    leaq    hello(%rip), %rdi
    call    _puts
    jnz     loop
    leave
    ret

.globl _main
_main:
    pushq   %rbp
    movq    %rsp, %rbp

    movl    $5, %eax
    jmp     loop

    movl    $0, %eax

    leave
    ret

但是,程序无限期地打印Hello world!虽然它编译没有错误。怎么了?

修改

建议后:

  1. %eax更改为%rax
  2. 添加pushpop
  3. 重新排序decq来电
  4. call loop代替jmp
  5. 以下是生成的代码:

    .data
    
    hello:
        .asciz  "Hello world!"
    
       .text
    loop:
        leaq    hello(%rip), %rdi
        pushq   %rax
        call    _puts
        popq    %rax
        decq    %rax
        jnz     loop
    
    .globl _main
    _main:
        pushq   %rbp
        movq    %rsp, %rbp
    
        movq    $5, %rax
        call    loop
    
        movq    $0, %rax
    
        leave
        ret
    

2 个答案:

答案 0 :(得分:2)

这将对您有所帮助:

  • 在64位代码中使用%rax而不是%eax。
  • 您不能指望call _puts保留%rax。所以pushpop
  • 您不能指望call _puts保留标志。请将decq %rax放在jnz loop之前。

这是循环:

loop:
  leaq    hello(%rip), %rdi
  pushq   %rax
  call    _puts
  popq    %rax
  decq    %rax
  jnz     loop
  RET

将建议添加到call loop

.globl _main
_main:
  pushq   %rbp
  movq    %rsp, %rbp
  movl    $5, %rax
  CALL    loop
  movl    $0, %rax
  leave
  ret

答案 1 :(得分:0)

由@Fifoernik和@Jester提供:

  1. %eax更改为%rax
  2. 添加pushpop
  3. 重新排序decq来电
  4. 由@rhkb提供,最后一块拼图:

    1. leaveret插入loop
    2. 的最后一部分

      共:

      .data
      
      hello:
          .asciz  "Hello world!"
      
          .text
      loop:
          leaq    hello(%rip), %rdi
          pushq   %rax
          call    _puts
          popq    %rax
          decq    %rax
          jnz     loop
          movq    $0, %rax
          leave
          ret
      
      .globl _main
      _main:
          pushq   %rbp
          movq    %rsp, %rbp
      
          movq    $5, %rax
          jmp     loop