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
je hello_worldjump is taken, so you jump to that label. As you did not call it, theretinstruction 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.msg_length: equ $ - msgright after themsg: db ...line, then later usemsg_lengthwhere you want to put the message's length into a register.rsppoints atargcon 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 thatjeis acall. 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)Enoutput is from the firstwritesystem call, which writes 14 bytes, including the first 2 of the string atend:. 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. Usestrace ./sample_fileto see the system calls, and single-step with a debugger like GDB to see the path of execution.je hello_world. Remove that instruction so execution falls through tocall hello_world. Jumping tohello_world(instead of calling) ends up reachingretwithout a return address on the stack. Also, if you want someone to see a reply, use @username to notify them.