간단한 코드를 짜봤습니다
사용자로부터 숫자 두개를 입력 받고 그 합을 반환하는 프로그램
#include <stdio.h>
int sum(int a, int b);
int main(void) {
00B41990 push ebp //기존 ebp 값을 스택에 쌓는다
00B41991 mov ebp,esp //esp값을 ebp에 할당
00B41993 sub esp,0DCh //스택의 공간은 224만큼 공간을 늘림
00B41999 push ebx //ebx를 스택에 push
00B4199A push esi //esi를 스택에 push
00B4199B push edi //edi를 스택에 push
00B4199C lea edi,[ebp-1Ch] //ebp-1Ch를 edi에 대입
00B4199F mov ecx,7
00B419A4 mov eax,0CCCCCCCCh
00B419A9 rep stos dword ptr es:[edi]
00B419AB mov eax,dword ptr [__security_cookie (0B4A004h)]
00B419B0 xor eax,ebp
00B419B2 mov dword ptr [ebp-4],eax
00B419B5 mov ecx,offset _8486901B_소스@cpp (0B4C008h)
00B419BA call @__CheckForDebuggerJustMyCode@4 (0B4132Ah)
int a, b;
scanf_s("%d", &a);
00B419BF lea eax,[a]
00B419C2 push eax
00B419C3 push offset string "%d" (0B47B30h) //사용자가 입력한 값을 push
00B419C8 call _scanf_s (0B41285h) //scanf_s 함수 호출
00B419CD add esp,8 //push를 두번해서 디로 간 스택을 다시 앞으로
scanf_s("%d", &b);
00B419D0 lea eax,[b]
00B419D3 push eax
00B419D4 push offset string "%d" (0B47B30h)
00B419D9 call _scanf_s (0B41285h)
00B419DE add esp,8
printf("%d", sum(a, b));
00B419E1 mov eax,dword ptr [b] //eax 레지스터에 b의 주소에 저장된 데이터 복사
00B419E4 push eax
00B419E5 mov ecx,dword ptr [a] //ecx 레지스터에 a의 주소에 저장된 데이터 복사
00B419E8 push ecx
00B419E9 call sum (0B41181h) //sum 함수 호출
00B419EE add esp,8
00B419F1 push eax
00B419F2 push offset string "%d" (0B47B30h)
00B419F7 call _printf (0B410D7h)
00B419FC add esp,8
}
00B419FF xor eax,eax
00B41A01 push edx
00B41A02 mov ecx,ebp
00B41A04 push eax
00B41A05 lea edx,ds:[0B41A30h]
00B41A0B call @_RTC_CheckStackVars@8 (0B411EFh)
00B41A10 pop eax //스택 가장 위에 있는 값을 꺼내서 eax에 저장 (stack은 lifo)
00B41A11 pop edx
00B41A12 pop edi
00B41A13 pop esi
00B41A14 pop ebx
00B41A15 mov ecx,dword ptr [ebp-4]
00B41A18 xor ecx,ebp
00B41A1A call @__security_check_cookie@4 (0B4114Fh)
00B41A1F add esp,0DCh
00B41A25 cmp ebp,esp
00B41A27 call __RTC_CheckEsp (0B4124Eh)
00B41A2C mov esp,ebp
00B41A2E pop ebp
00B41A2F ret
00B41A30 add al,byte ptr [eax]
00B41A32 add byte ptr [eax],al
00B41A34 cmp byte ptr [edx],bl
00B41A36 mov ah,0
00B41A38 hlt
후.. 살펴봅시다
먼저 main 함수에서 메모리 할당을 하네요
변수를 선언하는 것으로 추정되는 부분
mov: 변수의 값을 저장
lea: 변수의 주소를 저장
이 둘의 차이로 보아 movl로 4byte의 변수(int 타입)를 선언했고
lea로 변수의 주소값을 하나 선언했습니다
그러고 다시 mov로 lea를 통해 주소값을 저장한 것을 0x10(%rbp)에 저장
sub 명령어가 있는것으로 보아 차이를 계산하고 다시 변수를 저장하는 것으로 판단됨
처음에 mov 했던 int 형 변수에서 1을 뻄
두번째 변수의 값을 rdx에 저장하고
위에서 계산했던 int형 변수의 값을 eax에 저장
마지막으로 rdx의 값을 rsi로 밀어넣고
eax의 값을 edi에 밀어넣는다
printName 함수 호출하고 main 함수 종료
역시나 printName 함수도 메모리 할당 후 시작
처음 두줄은 mov로 변수 2개 할당
마지막 mov는 2번째 줄에서 발생한 변수를 rax에 저장
주소값을 rdx에 저장함
위에서 저장한 rdx 값을 rsi로 옮기고
(위의 사진의 세번째 줄, 두번째 변수)rax에 저장한 값을 rdi에 옮겨서 저장
strcmp 함수 호출
변수 2개가 같은지 비교
jne: jump if not equal
즉 값이 다르다면 <+73>로 이동하는 것 같다 -> 밑에서 더 설명
값이 같다면 쭉쭉 실행
첫번째 변수에 0x77값 대입
eax에 두번째 변수 값 대입
rax에 0xe51(%rip)값 저장
rax 값 rdi 저장
eax에 0 저장 -> 함수가 끝나려는 듯 하다
마지막으로 printf 함수를 호출하고 끝!
여기서 <+73>이 나타나는 것을 알 수 있다
후..이제 c언어로 옮겨볼까요
#include <stdio.h>
#include <string.h>
void printName(int a, char* c);
int main(void) {
int a = 24;
char* c = "string_1";
a = a - 1;
printName(a, c);
return 0;
}
void printName(int a, char* c) {
if (strcmp(c, "string_2")) {
int b = 119;
printf("string_3", a);
};
return;
}