assembly - %eax 不递减? (ATT assembly )

标签 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. 调用 循环而不是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    $5, %rax
    call    loop

    movq    $0, %rax

    leave
    ret

最佳答案

这会对您有所帮助:

  • 在 64 位代码中使用 %rax 代替 %eax。
  • 您不能指望您的call _puts 会保留 %rax。所以push然后pop它。
  • 您不能指望您的call _puts 会保留这些标志。因此,请将decq %rax放在jnz循环之前。

这是循环:

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

将建议添加到调用循环:

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

关于assembly - %eax 不递减? (ATT assembly ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33173131/

相关文章:

从 size_t 到 int 的转换

c - C库如何调用内核系统调用

Python 在 Windows 8.1 64 位上错误地检测到 32 位系统

java - 通过对象数组调用构造函数

java - 编译asm字节码

assembly - 反汇编时如何对二进制arm指令进行分类

linux - 内核端页面缓存 virt <-> phys 映射如何与 TLB 交互?

c - 内联汇编 : move imm to a 64-bit register without sign-extension

c# - __c# 中的 fastcall 约定

linux - x86-64 System V ABI 记录在哪里?