0

So i am trying to make a simple assembly program, and i am getting a seg fault, the print function does indeed print out what i want, but than it crashes.

test.s:

.global _start

msg1:
        .string "Hello, World!\n"
msg2:
        .string "Goodbye, World !\n"

_start:
        PUSHQ   %rbp
        MOVQ    %rsp, %rbp
        MOVQ    $msg1, %rax
        CALL    print
        MOVQ    $msg2, %rax
        CALL    print
        POPQ    %rbp
        RET

# void print(char * x[%rax])
print:
print_init:
        PUSHQ   %rbp
        MOVQ    %rsp, %rbp
        SUBQ    $32,  %rsp
        MOVQ    %rax, -32(%rbp)
print_loop:
        MOVL    $1, %edx
        MOVL    -32(%rbp), %ecx
        CMPB    $0, (%ecx)
        JE      print_exit
        MOVL    $1,   %ebx
        MOVL    $4,   %eax
        INT     $0x80
        ADDQ    $1, -32(%rbp)
        JMP     print_loop
print_exit:
        POPQ    %rbp
        RET

thanks for helping guys!

  • `CMPB $0, (%ecx)` you know you're writing 64-bit code, right? You stored a 64-bit pointer to the stack (for no apparent reason), then reloaded and dereffed the low 32 bits. Also you're trying to use `int $0x80` in 64-bit code, so that might crash e.g. if you're on WSL1 on Windows. ([What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/q/46087730)). – Peter Cordes Jul 21 '21 at 07:23
  • @PeterCordes alright thanks! let me try to fix this... edit: wait, but if this was the error, wouldn't it crash before even printing anything? – wannastacksmash Jul 21 '21 at 07:24
  • And then you try to `ret` from `_start` which isn't function: RSP on process entry doesn't point at a return address. – Peter Cordes Jul 21 '21 at 07:25
  • The `(%ecx)` probably isn't actually the cause of the segfault: if the program linked and ran at all, then `MOVQ $msg1, %rax` was able to represent the absolute address as a signed 32-bit immediate, so truncating it shouldn't actually change it. A 32-bit address-size override is inefficient but probably didn't cause the crash. Use a debugger to see exactly what happened. (And write 32-bit code if you want to copy/paste from 32-bit examples that use int 0x80 instead of syscall. – Peter Cordes Jul 21 '21 at 07:27
  • @PeterCordes alright thanks a lot – wannastacksmash Jul 21 '21 at 07:29
  • Yes, you're right, it would crash before printing anything if that was the problem. I initially just read the question title, which said it crashed **in** the print function. (i.e. before print itself even returns). So your question title doesn't match what you said in the question body. – Peter Cordes Jul 21 '21 at 07:30
  • Err wait, looks like you don't restore RSP at the bottom of `print`, so it probably crashes there when you `ret` with RSP pointing at garbage instead of its return address. There's no reason to do anything with RSP or RBP in `print`, just registers. Also, it would be *much* more efficient to make one system call with the total length of the string, instead of `write(1, ptr, 1)` for every char separately, so sink the system call out of the loop and just do a strlen loop. – Peter Cordes Jul 21 '21 at 07:32

0 Answers0