简单的C程序 汇编分析
//源代码
typedef struct
{
int i;
char c;
}S;
int fun(int i, char c, S * s)
{
s->i = i;
s->c = c;
return 0;
}
int main()
{
S s;
fun(1, 'C', &s);
return 0;
}
//汇编分析
main 函数
堆栈(注:栈的增长方向 从大到小 4字节对齐):
栈顶
...
s.i ← 变量s的地址 [ebp-8]
s.c
ebp
...
栈底
14: int main()
15: {
00401060 push ebp
00401061 mov ebp,esp
00401063 sub esp,48h
00401066 push ebx
00401067 push esi
00401068 push edi
00401069 lea edi,[ebp-48h]
0040106C mov ecx,12h
00401071 mov eax,0CCCCCCCCh
00401076 rep stos dword ptr [edi]
16: S s;
17: fun(1, 'C', &s); //函数调用过程 从右到左压栈
00401078 lea eax,[ebp-8]
0040107B push eax //s的地址入栈
0040107C push 43h //参数'C'入栈
0040107E push 1 //参数1入栈
00401080 call @ILT+0(_fun) (00401005) //调用fun函数
00401085 add esp,0Ch
18: return 0;
00401088 xor eax,eax //返回值 存在eax中
19: }
0040108A pop edi
0040108B pop esi
0040108C pop ebx
0040108D add esp,48h
00401090 cmp ebp,esp
00401092 call __chkesp (004010b0)
00401097 mov esp,ebp
00401099 pop ebp
0040109A ret
Main函数 将参数压栈后 通过 call 00401005 调用fun 函数
00401005 jmp fun (00401020) //00401020是fun函数的入口地址
fun 函数
堆栈:
栈顶
...
ebp
eip
i ← 参数i: ebp+8
c ← 参数c: ebp+0C
&s ← 参数s的地址: ebp+10
...
栈底
7: int fun(int i, char c, S * s)
8: {
00401020 push ebp
00401021 mov ebp,esp
00401023 sub esp,40h
00401026 push ebx
00401027 push esi
00401028 push edi
00401029 lea edi,[ebp-40h]
0040102C mov ecx,10h
00401031 mov eax,0CCCCCCCCh
00401036 rep stos dword ptr [edi]
9: s->i = i;
00401038 mov eax,dword ptr [ebp+10h] //s的地址 → eax
0040103B mov ecx,dword ptr [ebp+8] // i → ecx
0040103E mov dword ptr [eax],ecx // ecx → [eax]: s->i = i
10: s->c = c;
00401040 mov edx,dword ptr [ebp+10h] //s的地址 → eax
00401043 mov al,byte ptr [ebp+0Ch] //c → al char 占一个字节
00401046 mov byte ptr [edx+4],al // al → [edx+4]: s->c = c
11: return 0;
00401049 xor eax,eax
12: }
0040104B pop edi
0040104C pop esi
0040104D pop ebx
0040104E mov esp,ebp
00401050 pop ebp
00401051 ret