C code와 nasm 코드의 argument 전달 방식에 대해서..
글쓴이: revival4u / 작성시간: 화, 2007/12/04 - 1:40오전
아까전에 올렸던 내용인데
ndisasm -b 32를 통해 disassemble한 내용을 토대로 다시 작성하였습니다.
C code :
int func(int a, int b, char c, char d, int e, double f, char g){ a = 1+1; b = 2+2;
c = 'c'; d = 'd';
e = 1+2;
f = 1.0+1.0;
g = 'g';
}
int main(void){ func(1, 2, 'a', 'b', 3, 1.0, 'c');} nasm code
00000000 55 push ebp 00000001 89E5 mov ebp,esp 00000003 83EC18 sub esp,byte +0x18 ; 8*4byte의 stack을 사용하겠다... 00000006 8B4510 mov eax,[ebp+0x10] ; 스텍의 세번째(c)를 eax로 00000009 8B5514 mov edx,[ebp+0x14] ; 스텍의 네번째(d)를 edx로 0000000C 8B4D24 mov ecx,[ebp+0x24] ; 스텍의 여덟번째(g)를 ecx로(double이 qword를 차지하므로) 0000000F 8845FC mov [ebp-0x4],al ; char형 변수 c, d를 [ebp-0x4]및 00000012 8855F8 mov [ebp-0x8],dl ; [ebp-0x8]로 복사 00000015 8B451C mov eax,[ebp+0x1c] ; double형 변수 f를 두번에 거쳐 복사 00000018 8945F0 mov [ebp-0x10],eax ; - 0000001B 8B4520 mov eax,[ebp+0x20] ; - 0000001E 8945F4 mov [ebp-0xc],eax ; - 00000021 884DEC mov [ebp-0x14],cl ; char형 변수 g를 복사 00000024 C7450802000000 mov dword [ebp+0x8],0x2 ; a = 1+1; 0000002B C7450C04000000 mov dword [ebp+0xc],0x4 ; b = 2+2; 00000032 C645FC63 mov byte [ebp-0x4],0x63 ; c = 'c'; 00000036 C645F864 mov byte [ebp-0x8],0x64 ; d = 'd'; 0000003A C7451803000000 mov dword [ebp+0x18],0x3 ; e = 1+2; 00000041 DD05A8000000 fld qword [dword 0xa8] ; ?무슨명령어? 00000047 DD5DF0 fstp qword [ebp-0x10] ; ?무슨명령어? 0000004A C645EC67 mov byte [ebp-0x14],0x67 ; g = 'g'; 0000004E C9 leave0000004F C3 ret ...
위와같이 asm과 c가 매칭이 된다.
여기서 질문이..
1. int형 a, b, e는 return address와 push ebp 로 인해 [ebp+0x8]이 첫번째 인자를 가리키므로제가아는것과 같이 인자들을 접근합니다. 하지만 char형과 double형은 왜 ebp 위쪽에 위치한 argument들을 '-'를 통해 아래쪽으로 복사를 하는데 왜 그런 작업을 하는지 이해가 안됩니다.
2. double형은 왜 두번에 나누어 저렇게 복사하게 되는지 또한 구음하구요
3. fld, fstp 명령어들은 무슨역할을 하는지 궁금하네요
읽어주셔서 감사하고
같이 고민해주실분 구합니다~~
Forums:


1번은 잘
1번은 잘 모르겠구요..
2번은 더블형이 64비트이기 때문에 32비트 레지스터에 한번에 못들어가니까 그런것 같습니다.
3번은 f가 앞에 붙어있는건 실수연산용 명령어라고 알고 있습니다. f = 1.0+1.0; 를 연산하는 것일겁니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
상수 계산
아닙니다. 이 경우 식의 모든 부분이 상수이기 때문에 "f = 2.0;"과 같은 결과이고 덧셈은 없습니다.
"연산"이라고 해서 좀
"연산"이라고 해서 좀 애매하긴 했군요.
전 대입(=)을 연산이라고 생각해서 그렇게 답을 했었네요:)
아마 0xa8에 상수 2.0이 저장되어있을 겁니다.
00000041 DD05A8000000 fld qword [dword 0xa8] ; 상수 2.0을 실수레지스터 스택에 로드
00000047 DD5DF0 fstp qword [ebp-0x10] ; 실수레지스터 스택의 st(0)를 스택의 ebp-0x10에 저장
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
음. 아래걸 참고
음. 아래걸 참고 하시는것이
어떠실지.
$ gcc -g -c b.c $ objdump -S b.o b.o: file format elf32-i386 Disassembly of section .text: 00000000 <func>: int func(int a, int b, char c, char d, int e, double f, char g) { 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 ec 18 sub $0x18,%esp 6: 8b 45 10 mov 0x10(%ebp),%eax 9: 8b 55 14 mov 0x14(%ebp),%edx c: 8b 4d 24 mov 0x24(%ebp),%ecx f: 88 45 fc mov %al,-0x4(%ebp) 12: 88 55 f8 mov %dl,-0x8(%ebp) 15: 8b 45 1c mov 0x1c(%ebp),%eax 18: 89 45 f0 mov %eax,-0x10(%ebp) 1b: 8b 45 20 mov 0x20(%ebp),%eax 1e: 89 45 f4 mov %eax,-0xc(%ebp) 21: 88 4d ec mov %cl,-0x14(%ebp) a = 1+1; 24: c7 45 08 02 00 00 00 movl $0x2,0x8(%ebp) b = 2+2; 2b: c7 45 0c 04 00 00 00 movl $0x4,0xc(%ebp) c = 'c'; 32: c6 45 fc 63 movb $0x63,-0x4(%ebp) d = 'd'; 36: c6 45 f8 64 movb $0x64,-0x8(%ebp) e = 1+2; 3a: c7 45 18 03 00 00 00 movl $0x3,0x18(%ebp) f = 1.0+1.0; 41: dd 05 00 00 00 00 fldl 0x0 47: dd 5d f0 fstpl -0x10(%ebp) g = 'g'; 4a: c6 45 ec 67 movb $0x67,-0x14(%ebp) } 4e: c9 leave 4f: c3 ret 00000050 <main>: int main(void) { 50: 8d 4c 24 04 lea 0x4(%esp),%ecx 54: 83 e4 f0 and $0xfffffff0,%esp 57: ff 71 fc pushl -0x4(%ecx) 5a: 55 push %ebp 5b: 89 e5 mov %esp,%ebp 5d: 51 push %ecx 5e: 83 ec 24 sub $0x24,%esp func(1, 2, 'a', 'b', 3, 1.0, 'c'); 61: c7 44 24 1c 63 00 00 movl $0x63,0x1c(%esp) 68: 00 69: d9 e8 fld1 6b: dd 5c 24 14 fstpl 0x14(%esp) 6f: c7 44 24 10 03 00 00 movl $0x3,0x10(%esp) 76: 00 77: c7 44 24 0c 62 00 00 movl $0x62,0xc(%esp) 7e: 00 7f: c7 44 24 08 61 00 00 movl $0x61,0x8(%esp) 86: 00 87: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp) 8e: 00 8f: c7 04 24 01 00 00 00 movl $0x1,(%esp) 96: e8 fc ff ff ff call 97 <main+0x47> return 0; 9b: b8 00 00 00 00 mov $0x0,%eax } a0: 83 c4 24 add $0x24,%esp a3: 59 pop %ecx a4: 5d pop %ebp a5: 8d 61 fc lea -0x4(%ecx),%esp a8: c3 ret-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.
고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"
답변 감사합니다.
죄송한데 마지막분께서 AT&T형식 assembly language로
올려주셨는데...
의도파악이 잘...
어떤점에서 그렇게 올려주셨는지 좀..알려주세요
제가보기엔 비슷해보이는데...
objdump -S
제가 생각하기에, objdump의 -S (--source) 옵션을 쓰면 어셈블리와 C 코드를 알아서 맞춰주니까 ndisasm보다 좋다는 뜻일 듯 합니다.
AT&T 문법이 싫으시면 objdump -M intel -S 로 하시면 인텔 문법으로 나옵니다.
감사합니다
넵 감사합니다~
댓글 달기