Search code examples
assemblyx86-64calling-conventionatt

%eax does not decrement? (ATT Assembly)


I am new to AT&T assembly and I am learning to use the decrement operator, decl to create a program that prints Hello world! 5 times.

Here's the code:

.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

However, the program prints Hello world! indefinitely though it compiles with no errors. What's wrong?

EDIT

After the suggestions to:

  1. Change from %eax to %rax
  2. Add push and pop
  3. Reorder the decq call
  4. call loop instead of jmp

Here is the resulting code:

.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

Solution

  • As contributed by @Fifoernik and @Jester:

    1. Change from %eax to %rax
    2. Add push and pop
    3. Reorder the decq call

    As contributed by @rhkb, the last piece of the puzzle:

    1. Insert leave and ret into the last part of loop

    Altogether:

    .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