1
; print_row(10, '<')     Prints character N-times - this case 10x '<'
print_row:
    mov ecx, edi     ; num
    push rbx         ; preserving callee-saved register value
    mov ebx, esi     ; using callee-saved register for the char value
    sub ecx, 1
loop_print:
    mov edi, ebx
    mov al, 0
    push rcx         ; preserving rcx register value (number), because its caller-saved register
    call putchar     ; calling putchar func
    pop rcx          ; retrieving rcx value, which was preserved by stack
    sub ecx, 1       
    jns loop_print   ; we loop untill ecx has negative value
    
    mov edi, 10      ; '\n' at the end
    mov al, 0
    call putchar     
    pop rbx          ; setting rbx to its original value before calling print_row func
    ret

I think the problem is in the push pop rcx, but I really dont understand why as the code makes logical sense to me. I tried searching for answer, but unfortunately couldn't find anything.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    Why not run this code in a debugger and step through instruction by instruction? We have no idea what your inputs and expected outputs look like. – Botje Apr 07 '23 at 10:19
  • 1
    Your first call to `putchar` has the stack misaligned; you did 2 total pushes after entering the function, moving RSP by an even multiple of 8, not an odd multiple. So it might be [glibc scanf Segmentation faults when called from a function that doesn't align RSP](https://stackoverflow.com/q/51070716) – Peter Cordes Apr 07 '23 at 19:48
  • BTW, there are lots of call-preserved registers besides RBX (RBP and R12-R15), use one of those for your loop counter so you don't have to push/pop inside the loop (but you would still need to push it at the top of your function so stack-alignment considerations don't change.) Also, `putchar` doesn't take a variable number of args, so `mov al,0` is not necessary before it. – Peter Cordes Apr 07 '23 at 19:49
  • Calling `putchar` n times is much less efficient than making a small buffer on the stack and repeating your character into it, and calling `puts`. Every I/O function has to lock/unlock some `stdout` data structure in case multiple threads try to output at the same time. It's not nearly as bad as making a `write` system call for each character, though. Anyway, this is fine, but you don't need a loop. You could make it more efficient by calling `putchar_unlocked` if you cared about performance. (Which is normally one of the main reasons for learning about asm.) – Peter Cordes Apr 07 '23 at 19:52
  • I have to use putchar this way as it is school assignment. Also I am very thankfull for your help guys. – Tomislav 12 Apr 08 '23 at 10:08
  • 1
    @PeterCordes That was it, thank you for your help Mr. Cordes – Tomislav 12 Apr 08 '23 at 10:56

0 Answers0