2011-05-15 2 views
2
  
long getesp() { 
    __asm__("movl %esp,%eax"); 
    } 

    void main() { 
    printf("%08X\n",getesp()+4); 
    } 

스택 프레임이 설정되기 전에 esp가 값을 가리키는 이유는 무엇이며 아래 코드와 어떤 차이가 있습니까?C++의 함수 내에서 어셈블리 실행

 
void main() {  
    __asm__("movl %esp,%eax");  
    } 

답변

3

나는 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 

getespesp를 조작하고 ebp에서뿐만 아니라 인라인으로 eax의 조작 esp을 가져오고 pushl을 가지고있었습니다.

스택 포인터를 가져오고 main 안에 가져 오는 함수 호출을 만드는 것은 분명히 다르며 12 바이트 (이 경우)마다 다릅니다. 그 이유는 call을 실행할 때 eip (내부 세그먼트가 아니고 Linux/UNIX 일반 프로그램 실행의 경우에만 eip) (인용이 필요함)을 수행하고 getesp 함수 내부에 pushebp이 있고 그 다음에 스택 포인터는 4를 뺍니다. eipebp은 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 

도움이 되었기를 바랍니다.