array 사용이 컴파일되었을 때의 모양
일반적인 local variable의 경우
mov [ebp+var_38], 0 ; i = 0
과 같이 ebp 레지스터에 대한 상대 위치를 이용하여 표현한다.
array도 마찬가지인데
mov [ebp+eax*4+var_2C], ecx ; a[i] = i;
과 같이 ebp에 대한 상대 위치로 표현한다.
MOV r/m32, r32
MOV r32, r/m32
MOV r32, imm32
같은 instruction을 사용한다.
stack guard 같은 것을 사용하려면 첫번째 argument가 r/m32인 것만 찾으면 되는 것일까?
function pointer가 컴파일되었을 때의 모양
function pointer 값을 배열에 assign할 때
fp[0] = &a; // c++
가
move [ebp+var_14], offset loc_4110F5
와 같이 컴파일되는 것을 볼 수 있다.
function을 call할 때
(*fp[i])(); // c++
가
move ecx, [ebp_eax*4+var_14]
call ecx
와 같이 컴파일되는 것을 볼 수 있다.
즉 assign할 때는 location 값이 그대로 들어가고,
call할 때는 register에 location을 넣고 그대로 jump한다.
import한 function에 대한 call이 compile되는 경우 (VS2005)
DS / SS / CS (DS:data segment / SS:stack segment / CS:code segment)
call ds:__imp__scanf
의 경우 ds는 data segment를 가르키고,
__imp__scanf가 data segment 안에 있는 주소를 가리키는 offset이 된다.
전에 VS98로 compile할 때는
prinf같은 메소드들도 embed되었던 것 같다.
switch문의 경우 switch 갯수가 몇 개 되지 않을 때는 cmp를 이용하여 그대로 compile되지만,
갯수가 많을 때는
1. default(가장 큰 숫자보가 크다면 jmp) cmp / ja 형태로 컴파일되며
2. 나머지는 table에 만들어 넣는다. 1 byte이기 때문에 많아야 255개인데, default를 빼고 나머지에 대해서만 table을 만들어서 해당되는 숫자에 대한 주소를 그대로 읽어오고 그 곳으로 jump하는 식이다. vs 2005에서는 table이 text section 뒤에 붙어 있었다. 즉 code와 data가 mix되어 text section에 있던 것이다.
.text:00413779 mov eax, [ebp+var_8]
.text:0041377C mov [ebp+var_D0], eax
.text:00413782 cmp [ebp+var_D0], 5Fh
.text:00413789 ja loc_4138C2
.text:0041378F mov ecx, [ebp+var_D0]
.text:00413795 movzx edx, ds:byte_413954[ecx]
.text:0041379C jmp ds:off_413920[edx*4]
.text:004137A3
.text:004137A3 loc_4137A3: ; DATA XREF: .text:off_413920o
.text:004137A3 mov esi, esp
.text:004137A5 push offset aA_0 ; "a"
.text:004137AA call ds:__imp__printf
.text:004137B0 add esp, 4
.text:004137B3 cmp esi, esp
.text:004137B5 call j__RTC_CheckEsp
.text:004137BA
.text:004137BA loc_4137BA: ; CODE XREF: wmain+5Cj
.text:004137BA ; DATA XREF: .text:00413924o
.text:004137BA mov esi, esp
.text:004137BC push offset aA ; "a"
.text:004137C1 call ds:__imp__printf
.text:004137C7 add esp, 4
.text:004137CA cmp esi, esp
.text:004137CC call j__RTC_CheckEsp
이정도가 예제가 될듯
virtual call이 compile되는 경우
switch ~ case와 마찬가지로 table이 만들어져서,
해당하는 function으로 jump하도록 하고 있다.