I wrote some simple assembly code like below:
.global _start
.text
_start:
call _sum
subq $0x8, %rsp
popq %rax
ret
_sum:
ret
In order to get the value of %rax after 'popq' instruction,
I assembled that code using 'as' and 'ld' command. and I started gdb debugger by putting break point at '_start'
and the result comes like below:
B+> │0x400078 <_start> callq 0x400083 <_sum>
│ │0x40007d <_start+5> sub $0x8,%rsp
│ │0x400081 <_start+9> pop %rax
│ │0x400082 <_start+10> retq
│ │0x400083 <_sum> retq
However, before going into pop instruction, There comes an error message saying that
Program received signal SIGSEGV, Segmentation fault. Cannot access memory at address 0x1
(when I changed the $0x8 into $0x0~$0x7, it all worked.)
It seems like at the first stage the sum function might be the problem. because It literally does nothing but return.
So, How can I modify this code to get the value of %rax after the popq instruction?
Thanks.
I think probably this question is a duplicate, but anyway, there is one problem in your code.
.global _start
.text
_start:
call _sum
subq $0x8, %rsp
popq %rax
ret # <-- return to where?
_sum:
ret
A main
in C has to can return because _start
eventually calls main
, but here, you are writing _start
directly. It returns to nowhere if you put a ret
.
In place of ret
, put this instead.
movl $60, %eax # syscall number for sys_exit
movl $0, %edi # or whatever value you want your process
# to return with from 0 to 255;
# xor %edi, %edi is usually better if you want 0
syscall
Leave a comment if it still crashes.
BTW, I was assuming your platform is Linux (because of the AT&T syntax..). The syscalls can be different for a different platform.