long getesp() { __asm__(\"movl %esp,%eax\"); } void main() { printf(\"%08X\\n\",getesp()+4); }
why does esp points to value be
After i did a gcc -S file.c
getesp:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
#APP
# 4 "xxt.c" 1
movl %esp,%eax
# 0 "" 2
#NO_APP
leave
ret
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $20, %esp
call getesp
addl $4, %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
addl $20, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
The getesp
has a pushl
which manipulates the esp
and gets the manipulated esp
in eax
with the inline and as well as in ebp
.
Making a function call to fetch the stack pointer and getting it inside the main
is definitely different, and it differs by 12 bytes (in this specific case). This is because when you execute the call
pushes the eip
(if not intersegment, and for linux/unix normal program execution it is only eip
) (need citation), next inside the getesp
function there is another push
with ebp
and after that the stack pointer is subtracted by 4. Because the eip
and ebp
are of 4 bytes, so the total difference is now 12 bytes. Which actually we can see in the function call version.
Without the function call there is no pushing of eip
and other esp
manipulation, so we get the esp
value after the main setup.
I am not comfortable with AT&T so here is the same code in Intel syntax and an Intex syntax asm dump below. Note that in the printf
call for the __asm__
inside the main value got into a
there is no push or other esp
modification so, the __asm__
inside main gets the esp
value which was set in the main by the sub esp, 20
line. Where as the value we get by calling getesp
is the (what you are expecting) - 12 , as described above.
The C Code
#include <stdio.h>
int a;
long getesp() {
__asm__("mov a, esp");
}
int main(void)
{
__asm__("mov a,esp");
printf("%08X\n",a);
getesp ();
printf("%08X\n",a);
}
The output is in my case for the specific run:
BF855D00
BF855CF4
The intel syntax dump is:
getesp:
push ebp
mov ebp, esp
sub esp, 4
#APP
# 7 "xt.c" 1
mov a, esp
# 0 "" 2
#NO_APP
leave
ret
main:
lea ecx, [esp+4]
and esp, -16
push DWORD PTR [ecx-4]
push ebp
mov ebp, esp
push ecx
sub esp, 20
#APP
# 12 "xt.c" 1
mov a,esp
# 0 "" 2
#NO_APP
mov eax, DWORD PTR a
mov DWORD PTR [esp+4], eax
mov DWORD PTR [esp], OFFSET FLAT:.LC0
call printf
call getesp
mov eax, DWORD PTR a
mov DWORD PTR [esp+4], eax
mov DWORD PTR [esp], OFFSET FLAT:.LC0
call printf
add esp, 20
pop ecx
pop ebp
lea esp, [ecx-4]
ret
I hope this helps.