1
extern puts
extern printf


section .rodata
    format db "%u ", 0
    puts_format db "", 0


section .data
    arr1 dd 10, 20, 30, 40, 50, 60, 70, 80
    len1 equ 8
    arr2 dd 11, 22, 33, 44, 55, 66, 77, 88, 99
    len2 equ 9
    int_fmt db "%d ", 0
    newline_fmt db 10, 0


section .bss
    dest resd 10


section .text
global main

print_arr:
    push ebp
    mov ebp, esp

    ; TODO a: Implement array printing function:
    ; print_arr(unsigned int *arr, unsigned int len);
    mov eax, [ebp + 8]  ; eax = len
    mov ebx, [ebp + 12] ; ebx = arr
    mov ecx, 0 

    print_loop: 
        cmp ecx, eax
        jge print_end
        mov edx, ecx
        imul edx, 4

        push dword [ebx + edx]
        push format
        call printf
        add esp, 8
        inc ecx
        jmp print_loop

    print_end: 
        push newline_fmt
        call printf
        add esp, 4


    leave
    ret

main:
    push ebp
    mov ebp, esp


    ; Print arr1 using print_arr.
    push dword len1
    push arr1
    call print_arr
    add esp, 8


    ; Return 0.
    xor eax, eax
    leave
    ret

After using the DBG, the SEGFAULT occurs at this line: push dword [ebx + edx]

I don't know where the issue may come from or how to fix it. I'm thinking that one of the registers goes in an unallocated space in memory, but I don't know the cause of it.

fuz
  • 88,405
  • 25
  • 200
  • 352
  • 1
    Calling the `printf` function trashes the contents of various registers, including `ecx` and `edx`. Refer to the calling convention for details. You must save data you want to keep in a caller-saved register or on the stack. – fuz Aug 29 '23 at 16:14
  • Where do you recommend saving the data on these registers? I'm a newbie with asm and I don't know if I save them on other registers such as `edi` or `esi` if it stills interferes with something. – tudor_cretu Aug 29 '23 at 16:21
  • Yes, edi, esi, and ebx are all caller-saved. To use them, you must however in turn preserve their old values. So at the beginning of your function, push these registers, then use them during the function, then pop them back off at the end to restore their old contents. – fuz Aug 29 '23 at 16:24
  • So it is a good practice to use `pusha` and `popa` in every function that i use? Thus I preserve the values and reset the registers after it? – tudor_cretu Aug 29 '23 at 16:28
  • 3
    @tudor_cretu: It would work, but it's not good practice. `pusha/popa` are very slow because they save and restore *all* the registers. The better practice is to keep track of the registers that you actually need to save and restore, and push/pop those only. – Nate Eldredge Aug 29 '23 at 16:35
  • 2
    Also, you only have to preserve callee-saved registers (ebx, ebp, esi, edi), and only if you use them. – fuz Aug 29 '23 at 16:46
  • If it is crashing (seg fault) in your own code, you should be able to inspect why the address is bad, and work backward to see who supplied the bad values (or who/what ruined what should have been good values). – Erik Eidt Aug 29 '23 at 17:59
  • @fuz: "caller-saved" registers are volatile, aka call-clobbered. You want a call-preserved register (aka "callee-saved" in that confusing terminology). The fact that you were able to mix up the terminology without noticing is a clear sign that it's terrible, and [we should be calling them call-preserved and call-clobbered](https://stackoverflow.com/questions/9268586/what-are-callee-and-caller-saved-registers/56178078#56178078) which are self-explanatory and easy to think about from the perspective of either the caller or callee. – Peter Cordes Aug 29 '23 at 18:35
  • @fuz: I was looking at your first comment, where unfortunately you didn't: "*You must save data you want to keep in a caller[sic]-saved register or on the stack.*" Another practical downside to the unfortunate callee vs. caller-saved terminology is that they're within typo range (same length, and differing only by one letter that's adjacent on qwerty keyboards.) – Peter Cordes Aug 29 '23 at 18:46
  • @PeterCordes Ah sucks, you got me indeed! – fuz Aug 29 '23 at 18:51
  • 1
    @fuz: :P English slang idiom note: I think you might mean "[aw shucks](https://idioms.thefreedictionary.com/Aw+shucks!)" which would fit better in the context you used it. – Peter Cordes Aug 29 '23 at 19:10
  • Not an exact duplicate, but [What registers must be preserved by an x86 function?](https://stackoverflow.com/q/9603003) describes the calling convention. I'm sure there are duplicates, still looking. – Peter Cordes Aug 29 '23 at 19:12
  • Thank you for your answers, not being a native speaker it's hard for me to search for a duplicate to my problem, because I don't know how to form the technical questions I have in the most general way :) – tudor_cretu Aug 29 '23 at 20:38

0 Answers0