2013-12-16 3 views
0
#include <stdio.h> 

static void my_func(char *text) { 
    //printf("hello again\n"); 
    __asm__(
     "push %%ebp\n\t" 
     "mov %0, %%ebx\n\t" 
     "push %%ebx\n\t" 
     "call strlen\n\t" 
     "movb (%%ebx), %%al" 
    : : "r"(text)); 
} 

int main() { 
    int i; 
    for(i = 0; i < 3; ++i) 
     my_func("hello"); 
} 

시운전로 시작하지 않는 :프로그램 함수 호출

$ gcc -v 
(...) 
gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9) 
$ gcc test.c 
$ ./a.out 
Segmentation fault (core dumped) 

왜 내 프로그램 충돌이 나는 printf 전화 주석을 제거 않습니다 않는? (printf 전화/w)

OK 버전 :

0804844d <my_func>: 
804844d: 55      push %ebp 
804844e: 89 e5     mov %esp,%ebp 
8048450: 83 ec 18    sub $0x18,%esp 
8048453: c7 04 24 30 85 04 08 movl $0x8048530,(%esp) 
804845a: e8 b1 fe ff ff   call 8048310 <[email protected]> 
804845f: 8b 45 08    mov 0x8(%ebp),%eax 
8048462: 89 c3     mov %eax,%ebx 
8048464: 53      push %ebx 
8048465: e8 c6 fe ff ff   call 8048330 <[email protected]> 
804846a: 8a 03     mov (%ebx),%al 
804846c: c9      leave 
804846d: c3      ret 

충돌 버전 (NO printf 전화) :

0804841d <my_func>: 
804841d: 55      push %ebp 
804841e: 89 e5     mov %esp,%ebp 
8048420: 8b 45 08    mov 0x8(%ebp),%eax 
8048423: 89 c3     mov %eax,%ebx 
8048425: 53      push %ebx 
8048426: e8 d5 fe ff ff   call 8048300 <[email protected]> 
804842b: 8a 03     mov (%ebx),%al 
804842d: 5d      pop %ebp 
804842e: c3      ret  
+0

먼저 모든 레지스터를 스택으로 푸시하고 있습니까? –

답변

1
"push %%ebx\n\t" 
"call strlen\n\t" 
다음

는 두 가지 기능에 대한 분해의

PUSH 무언가를 스택에. POP에 누가 스택에서 벗어날 것으로 예상합니까 (통화 매개 변수 정리)?

리눅스는 "caller cleanup"호출 규칙을 사용하며 호출 스택을 정리하지 않으면 my_func이 가짜 주소 (즉, SIGSEGV)로 돌아갑니다.

+0

허, 나는 피 호출자가 정리 될 거라고 생각했다. 감사! –