반응형

+)설명이 굉장히 잘되어있어서 도움이 많이되었다(디버깅할떄도 아래링크의 예제를 사용하였다)

 http://channelofchaos.tistory.com/55


[exec() source]

#include<sys/types.h>

#include<unistd.h>


main()

{

printf("executing ls\n");

execl("/bin/ls", "ls", "-1", (char*)0);

perror("execl failed to run ls");

exit(1);

}


[exec() debugging]

(gdb) disas main

Dump of assembler code for function main:

0x8048470 <main>: push   %ebp

0x8048471 <main+1>: mov    %esp,%ebp // 프롤로그 

0x8048473 <main+3>: push   $0x8048510// printf()'s string 

0x8048478 <main+8>: call   0x8048394 <printf>// printf() call 

0x804847d <main+13>: add    $0x4,%esp // calling convention 

0x8048480 <main+16>: push   $0x0  //char* 0 

0x8048482 <main+18>: push   $0x804851e // -1 

0x8048487 <main+23>: push   $0x8048521 //ls 

0x804848c <main+28>: push   $0x8048524// /bin/ls 

0x8048491 <main+33>: call   0x8048344 <execl>//execl() call 

0x8048496 <main+38>: add    $0x10,%esp// calling convention 

0x8048499 <main+41>: push   $0x804852c // perror's string

0x804849e <main+46>: call   0x8048364 <perror> //perror's call 

0x80484a3 <main+51>: add    $0x4,%esp//calling convention 

0x80484a6 <main+54>: push   $0x1 // exit's parameter 

0x80484a8 <main+56>: call   0x80483a4 <exit> // exit() call 

0x80484ad <main+61>: add    $0x4,%esp //calling convention 

0x80484b0 <main+64>: leave  // 에필로그 

0x80484b1 <main+65>: ret    


exec()는 딱히 특이사항이 보이지 않는다.

==========================================================================================================================================================================


[fork() source]#include <sys/types.h>

#include <unistd.h>


main()

{

pid_t pid;

pid=fork();

switch(pid)

{

case -1:

printf("fork failed");

break;

case 0:

execl("/bin/ls", "ls", "-1", (char*)0);

printf("exec failed");

break;

default:

wait((int *)0);

printf("ls complete\n");

exit(0);

}


}


[fork() debugging ] 

(gdb) disas main

Dump of assembler code for function main:

0x80484a0 <main>: push   %ebp

0x80484a1 <main+1>: mov    %esp,%ebp // 프롤로그 

0x80484a3 <main+3>: sub    $0x4,%esp // pid 

0x80484a6 <main+6>: call   0x8048388 <fork> // fork () call

0x80484ab <main+11>: mov    %eax,%eax  // NOP ,switch()를 사용하기 이전에 pid를 초기화 해준다 

0x80484ad <main+13>: mov    %eax,0xfffffffc(%ebp) //ebp - 4 에 eax값(case's parameter) 

0x80484b0 <main+16>: mov    0xfffffffc(%ebp),%eax

0x80484b3 <main+19>: cmp    $0xffffffff,%eax // eax 와 -1 을 비교 , case 문 

0x80484b6 <main+22>: je     0x80484c0 <main+32> // 같을경우 main +32로 이동된다 

0x80484b8 <main+24>: test   %eax,%eax  //  NULL check. cmp는 한값에서 다른 한값을 빼고, test 는 두 값을 and 한다 대신 이 두명령은 계산한 값을 저장하지 않는다. flag 레지스터에만 그 흔적이 남는다 .여기서는 case 0 에서 파라미터 0인가를 체크하는 부분이다 

0x80484ba <main+26>: je     0x80484d0 <main +48> // 따라서 같으면 case 0: 으로 jmp 

0x80484bc <main+28>: jmp    0x80484f8 <main+88>// 아닐경우 default 문으로 점프한다 

0x80484be <main+30>: mov    %esi,%esi // NOP 

0x80484c0 <main+32>: push   $0x8048580 // fork failed 문 

0x80484c5 <main+37>: call   0x80483b8 <printf> // printf () call 

0x80484ca <main+42>: add    $0x4,%esp//calling convention 

0x80484cd <main+45>: jmp    0x8048520 <main+128> //에필로그 

0x80484cf <main+47>: nop     

0x80484d0 <main+48>: push   $0x0 // (char*) 0 

0x80484d2 <main+50>: push   $0x804858c// -1 

0x80484d7 <main+55>: push   $0x804858f // ls 

0x80484dc <main+60>: push   $0x8048592 /// /bin/ls

---Type <return> to continue, or q <return> to quit---

0x80484e1 <main+65>: call   0x8048368 <execl> //execl call

0x80484e6 <main+70>: add    $0x10,%esp//calling convention 

0x80484e9 <main+73>: push   $0x804859a//printf's string ]

0x80484ee <main+78>: call   0x80483b8 <printf>// printf() call 

0x80484f3 <main+83>: add    $0x4,%esp// calling convention

0x80484f6 <main+86>: jmp    0x8048520 <main+128>  // 에필로그로 jmp 

0x80484f8 <main+88>: push   $0x0// wait's parameter 

0x80484fa <main+90>: call   0x80483d8 <wait> // wait()call 

0x80484ff <main+95>: add    $0x4,%esp//calling convention 

0x8048502 <main+98>: push   $0x80485a6// printf() 's string 

0x8048507 <main+103>: call   0x80483b8 <printf> // printf() call 

0x804850c <main+108>: add    $0x4,%esp // calling convention 

0x804850f <main+111>: push   $0x0 //exit's parameter

0x8048511 <main+113>: call   0x80483c8 <exit> //exit call 

0x8048516 <main+118>: add    $0x4,%esp //calling convention 

0x8048519 <main+121>: lea    0x0(%esi,1),%esi //nop 

0x8048520 <main+128>: leave // 에필로그   

0x8048521 <main+129>: ret    

0x8048522 <main+130>: nop    



0x80484ab <main+11>: mov    %eax,%eax  // NOP 

0x80484be <main+30>: mov    %esi,%esi // NOP 

0x80484cf <main+47>: nop 

반응형

'과거의 컴퓨터 공부 > C 디버깅' 카테고리의 다른 글

fflush()  (0) 2014.09.20
gets() v.s scanf()  (0) 2014.09.20
if else  (0) 2014.09.19
for()  (0) 2014.09.19
main함수 옆에 파라메터 넣어보기  (0) 2014.09.18
,