Printf causes Segment fault

1.3k views Asked by At

I am trying to compile an assembly code in linux ubuntu 32-bit. But when I compile it with nasm -felf32 assembly.asm && gcc assembly.o && ./a.out I face with Segmentation fault (core dumped). I understood that the problem is with printf.

I have searched a lot on the internet, there were several questions like this. But none of the answers worked for me.

    global  main
    extern  printf

    section .text
    main:
    push    ebx                     ; we have to save this since we use it

    mov     ecx, 90                 ; ecx will countdown to 0
    xor     eax, eax                ; rax will hold the current number
    xor     ebx, ebx                ; rbx will hold the next number
    inc     ebx                     ; rbx is originally 1
    print:
    ; We need to call printf, but we are using rax, rbx, and rcx.  printf
    ; may destroy rax and rcx so we will save these before the call and
    ; restore them afterwards.

    push    eax                     ; caller-save register
    push    ecx                     ; caller-save register

    mov     edi, format             ; set 1st parameter (format)
    mov     esi, eax                ; set 2nd parameter (current_number)
    xor     eax, eax                ; because printf is varargs

    ; Stack is already aligned because we pushed three 8 byte registers
    call    printf                ; printf(format, current_number)

    pop     ecx                     ; restore caller-save register
    pop     eax                     ; restore caller-save register

    mov     edx, eax                ; save the current number
    mov     eax, ebx                ; next number is now current
    add     ebx, edx                ; get the new next number
    dec     ecx                     ; count down
    jnz     print                   ; if not done counting, do some more

    pop     ebx                     ; restore rbx before returning

    ret
    format:
    db  "%20ld", 10, 0

*** source code is copied from Nasm tutorial site. It is for printing Fibonacci numbers.

1

There are 1 answers

0
Frank Kotler On

This is too easy a question for all this fuss. You've found a 64-bit tutorial, and converting it to 32-bit is not as simple as changing rax to eax. Here's how you call printf in 32-bit code.

 print:
    ; We need to call printf, but we are using rax, rbx, and rcx.  printf
    ; may destroy rax and rcx so we will save these before the call and
    ; restore them afterwards.

; comment does not match code!

    push    eax                     ; caller-save register
    push    ecx                     ; caller-save register

    push eax ; (current number)
    push format             ; set 1st parameter (format)
    call    printf                ; printf(format, current_number)
    add esp, 4 * 2 ; "remove" 2 parameters - 4 bytes each

    pop     ecx                     ; restore caller-save register
    pop     eax                     ; restore caller-save register
; etc...

That's untested. With only 32-bits, I don't think you'll get the full 90 numbers. You may need to alter your format string. You can get a 64-bit result with 32-bit code by using two registers, but you don't have code for that...