[스택 프레임 전체 흐름]
[어셈블리 수준에서의 설명]
//원래 소스 코드
void Swap(int *parm_a, int *parm_b)
{
int temp = 0;
// temp 변수를 이용하여 parm_a와 parm_b의 포인터 값을 바꾼다.
temp = *parm_a;
*parm_a = *parm_b;
*parm_b = temp;
}
void main()
{
int a = 5, b = 7;
// 변수 a와 b의 값을 바꾼다.
Swap(&a, &b);
a += 3;
b += 4;
}
//어셈 코드
void Swap(int *parm_a, int *parm_b)
{
00FA16A0 push ebp //main의 스택 베이스 포인터를 저장한다, swap 함수가 끝나면 다시 main 함수의 스택주소
// 구간으로 이동하기 위함 여기 까지 하면 EIP, 이전 EBP 가 스택에 싸여 있게 되고
00FA16A1 mov ebp,esp //ebp 를 현재 함수의 스택 주소 구간으로 변경하기 위해서 현재 스택포인터 값을 베이스 포인터 값으로 바꿔준다
00FA16A3 sub esp,0CCh
00FA16A9 push ebx //edx,esi,edi 빽업
00FA16AA push esi
00FA16AB push edi
00FA16AC lea edi,[ebp-0CCh]
00FA16B2 mov ecx,33h
00FA16B7 mov eax,0CCCCCCCCh // 변수 공간으로 사용할 해당 구간을 CCCCCCCC 값으로 초기화 해준다
00FA16BC rep stos dword ptr es:[edi] //
int temp = 0;
00FA16BE mov dword ptr [temp],0
temp = *parm_a;
00FA16C5 mov eax,dword ptr [parm_a]
00FA16C8 mov ecx,dword ptr [eax]
00FA16CA mov dword ptr [temp],ecx
*parm_a = *parm_b;
00FA16CD mov eax,dword ptr [parm_a]
00FA16D0 mov ecx,dword ptr [parm_b]
00FA16D3 mov edx,dword ptr [ecx]
00FA16D5 mov dword ptr [eax],edx
*parm_b = temp;
00FA16D7 mov eax,dword ptr [parm_b]
*parm_b = temp;
00FA16DA mov ecx,dword ptr [temp]
00FA16DD mov dword ptr [eax],ecx
}
00FA16DF pop edi //함수가 끝때날 edi,esi,edx 를 pop한다
00FA16E0 pop esi
00FA16E1 pop ebx
00FA16E2 mov esp,ebp //스택포인터를 main 의 스택 포인터 구간으로 되돌려주어 main 함수를 계속 수행해나갈 준비를 한다
00FA16E4 pop ebp //swap 함수가 끝났음으로 swap 에 대한 스택공간이 필요 없됐음으로 swap 에 대한 pop ebp을 수행
//pop 명령어는 ebp 에 현재 스택 상단의 내용을 ebp 에 넣고 스택을 줄인다는 것인데, 이것은
//이전 main 함수의 스택 포인터 기준 영역으로 되돌아 간다는 의미가 된다
00FA16E5 ret //이 함수가 콜 되면서 저장해 놓았던 이전 EIP 즉 main 의 다음 실행 주소로 복귀한다(해당 번지로 점프 하는 효과가 발생)
.......
void main()
{
00FA1700 push ebp
00FA1701 mov ebp,esp
00FA1703 sub esp,0DCh
00FA1709 push ebx
00FA170A push esi
00FA170B push edi
00FA170C lea edi,[ebp-0DCh]
00FA1712 mov ecx,37h
00FA1717 mov eax,0CCCCCCCCh
00FA171C rep stos dword ptr es:[edi]
00FA171E mov eax,dword ptr [__security_cookie (0FA8004h)]
00FA1723 xor eax,ebp
00FA1725 mov dword ptr [ebp-4],eax
//메모리 할당은 작은 주소 순으로 주소가 배열되며 지역변수는 ebp 주소를 기준으로 상대적으로 변수를 할당/사용한다
int a = 5, b = 7;
00FA1728 mov dword ptr [a],5
00FA172F mov dword ptr [b],7
Swap(&a, &b);
00FA1736 lea eax,[b] //swap 에 담길 인자를 스택에 넣는다
00FA1739 push eax
00FA173A lea ecx,[a]
00FA173D push ecx
00FA173E call Swap (0FA10F5h) // swap 을 call 하면서 다음 실행 주소 EIP:00FA1743 를 스택에 push 한다
00FA1743 add esp,8
a += 3;
00FA1746 mov eax,dword ptr [a]
a += 3;
00FA1749 add eax,3
00FA174C mov dword ptr [a],eax
b += 4;
00FA174F mov eax,dword ptr [b]
00FA1752 add eax,4
00FA1755 mov dword ptr [b],eax
}
00FA1758 xor eax,eax
00FA175A push edx
00FA175B mov ecx,ebp
00FA175D push eax
00FA175E lea edx,ds:[0FA178Ch]
00FA1764 call @_RTC_CheckStackVars@8 (0FA1253h)
00FA1769 pop eax
00FA176A pop edx
00FA176B pop edi
00FA176C pop esi
00FA176D pop ebx
반응형
'프로그래밍(Programming) > 어셈블리어(asm)' 카테고리의 다른 글
VisualStudio2015 어셈블러 하이라이트 설정 (0) | 2017.03.01 |
---|---|
_asm{ lea 와 mov 에서 [] 의 의미의 차이 } (0) | 2017.03.01 |
loop 명령어 조건 정리 ECX (0) | 2017.02.25 |
상태 레지스터 플래그 (0) | 2017.02.24 |
_asm {점프 할때의 플래그들 정리} (0) | 2017.02.21 |