1

My OS: Linux debian 4.19.0-9-amd64 #1 SMP Debian x86_64 GNU/Linux Compiler: NASM version 2.14

I try play with conditional jumps, function calling and comparing expressions. I wrote something simple, and it seems to by work, but i don't understand what cause error: EnSegmentation fault

For compilation purpose i'm use: nasm -f elf64 sample_file.asm -o sample_file.o and: ld sample_file.o -o sample_file

section .data msg: db 'Hello world',10 end: db 'Ending program', 10 section .text global _start hello_world: mov rax, 1 mov rdi, 1 mov rsi, msg mov rdx , 14 syscall ret exit: mov rax, 1 mov rdi, 1 mov rsi, end mov rdx, 20 syscall mov rax, 60 xor rdi, rdi syscall ret _start: mov rax, 10 mov rdx, 10 cmp rax, rdx je hello_world jne exit call hello_world mov rax, 60 xor rdi,rdi syscall call exit 

But the output is :

Hello world EnSegmentation fault 
7
  • 2
    The je hello_world jump is taken, so you jump to that label. As you did not call it, the ret instruction will try to pop a return address off the stack that was never initialised. This may jump to an invalid address, or fault from a stack underflow already. Commented Aug 7, 2020 at 19:56
  • 1
    Unrelated to your question, you can add the line msg_length: equ $ - msg right after the msg: db ... line, then later use msg_length where you want to put the message's length into a register. Commented Aug 7, 2020 at 19:59
  • 1
    @ecm: The x86-64 System V ABI says that rsp points at argc on entry to _start. You don't need to "initialize the stack" in a user-space process, but it's essentially guaranteed that what's there is not a valid return address. The actual problem is a duplicate of Nasm segmentation fault on RET in _start, but the real problem is thinking that je is a call. I think I've seen that problem before in SO questions, but stackoverflow.com/tags/x86/info only has links to the opposite problem (call without ret / falling off the end) Commented Aug 7, 2020 at 20:30
  • 2
    @reg3x: Note that the extra line of En output is from the first write system call, which writes 14 bytes, including the first 2 of the string at end:. If you didn't want that, let the assembler calculate the length for you as @ecm showed using $ - msg, instead of hard-coding the wrong number. Use strace ./sample_file to see the system calls, and single-step with a debugger like GDB to see the path of execution. Commented Aug 7, 2020 at 20:47
  • 2
    Your mistake is je hello_world. Remove that instruction so execution falls through to call hello_world. Jumping to hello_world (instead of calling) ends up reaching ret without a return address on the stack. Also, if you want someone to see a reply, use @username to notify them. Commented Aug 8, 2020 at 20:42

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.