Question

I'm currently working on assembly code. I wrote a program which genererate the following code. The generated code is exactly what I expect, but when I read it, the normal behaviour to me is that the assembly code will write to stdout an infinite number of '1' (in an infinite loop). The problem is that it writes only one '1' character and close without seg fault.

So, what I really missed from this code ? I wrote some comments to help me understand it, but after read and read again I don't see where is the problem. Is there a side effect in my code that I don't understand ?

Thanks.

.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

EDIT

Solution : write syscall modify r11 register

Was it helpful?

Solution

The System V Application Binary Interface AMD64 Architecture Processor Supplement section A.2 AMD64 Linux Kernel Conventions says, among other things, that:

A system-call is done via the syscall instruction. The kernel destroys registers %rcx and %r11.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top