%eax 不递减? (ATT 大会)

%eax does not decrement? (ATT Assembly)

我是 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    , %eax
    jmp     loop

    movl    [=10=], %eax

    leave
    ret

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

编辑

后建议到:

  1. %eax 更改为 %rax
  2. 添加 pushpop
  3. 重新排序 decq 调用
  4. call loop 而不是 jmp

这是结果代码:

.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    , %rax
    call    loop

    movq    [=11=], %rax

    leave
    ret

这对您有帮助:

  • 在 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    , %rax
  CALL    loop
  movl    [=11=], %rax
  leave
  ret

由@Fifoernik 和@Jester 提供:

  1. %eax 更改为 %rax
  2. 添加pushpop
  3. 重新排序 decq 调用

由@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    [=10=], %rax
    leave
    ret

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

    movq    , %rax
    jmp     loop