long getesp() { __asm__("movl %esp,%eax"); } void main() { printf("%08X\n",getesp()+4); }
스택 프레임이 설정되기 전에 esp가 값을 가리키는 이유는 무엇이며 아래 코드와 어떤 차이가 있습니까?C++의 함수 내에서 어셈블리 실행
void main() { __asm__("movl %esp,%eax"); }
long getesp() { __asm__("movl %esp,%eax"); } void main() { printf("%08X\n",getesp()+4); }
스택 프레임이 설정되기 전에 esp가 값을 가리키는 이유는 무엇이며 아래 코드와 어떤 차이가 있습니까?C++의 함수 내에서 어셈블리 실행
void main() { __asm__("movl %esp,%eax"); }
나는 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
getesp
가 esp
를 조작하고 ebp
에서뿐만 아니라 인라인으로 eax
의 조작 esp
을 가져오고 pushl
을 가지고있었습니다.
스택 포인터를 가져오고 main
안에 가져 오는 함수 호출을 만드는 것은 분명히 다르며 12 바이트 (이 경우)마다 다릅니다. 그 이유는 call
을 실행할 때 eip
(내부 세그먼트가 아니고 Linux/UNIX 일반 프로그램 실행의 경우에만 eip
) (인용이 필요함)을 수행하고 getesp
함수 내부에 push
과 ebp
이 있고 그 다음에 스택 포인터는 4를 뺍니다. eip
과 ebp
은 4 바이트이므로 총 차이는 이제 12 바이트가됩니다. 실제로 우리는 함수 호출 버전에서 볼 수 있습니다.
eip
및 기타 esp
조작이 없기 때문에 기본 설정 후에 esp
값을 얻습니다.
저는 AT & T가 마음에 들지 않으므로 아래 코드는 Intel 구문과 Intex 구문 asm dump 아래에 있습니다. 주요 값 내부의 __asm__
에 대한 printf
호출에 더 푸시 또는 다른 esp
수정 그래서, 주요 내부의 __asm__
가 sub esp, 20
선으로 메인에서 설정 한 esp
값을 가져가없는 a
에 도착합니다. 위에서 설명한대로 getesp
을 호출하여 얻을 수있는 값은 (예상 한 것) - 12입니다.
는 C 코드
#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);
}
출력은 특정 실행에 대한 내 경우입니다 :
BF855D00
BF855CF4
인텔 구문 덤프는 다음과 같습니다
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
도움이 되었기를 바랍니다.