这个我们写个稍微复杂一些的.
- #include <iostream>
- using namespace std;
- int Add(int a,int b)
- {
- return (a+b);
- }
- int main()
- {
- int c=Add(3,5);
- return 0;
- }
带有两个参数.
进入Add函数的汇编
- 00401030 push ebp
- 00401031 mov ebp,esp
- 00401033 sub esp,40h
- 00401036 push ebx
- 00401037 push esi
- 00401038 push edi
- 00401039 lea edi,[ebp-40h]
- 0040103C mov ecx,10h
- 00401041 mov eax,0CCCCCCCCh
- 00401046 rep stos dword ptr [edi]
- 5: return (a+b);
- 00401048 mov eax,dword ptr [ebp+8] //仍然是EAX做为中介
- 0040104B add eax,dword ptr [ebp+0Ch]
- 6: }
- 0040104E pop edi
- 0040104F pop esi
- 00401050 pop ebx
- 00401051 mov esp,ebp//这句释放了40h的内存块
- 00401053 pop ebp
- 00401054 ret
退出到 C=Add(3,5);
- 00401081 add esp,8 //为了堆栈平衡.
- 00401084 mov dword ptr [ebp-4],eax//把返回值放到主函数的局部变量中
下面我们看整个的全貌
- 1: #include <iostream>
- 2: using namespace std;
- 3: int Add(int a,int b)
- 4: {
- 00401030 push ebp
- 00401031 mov ebp,esp
- 00401033 sub esp,40h
- 00401036 push ebx
- 00401037 push esi
- 00401038 push edi
- 00401039 lea edi,[ebp-40h]
- 0040103C mov ecx,10h
- 00401041 mov eax,0CCCCCCCCh
- 00401046 rep stos dword ptr [edi]
- 5: return (a+b);
- 00401048 mov eax,dword ptr [ebp+8]
- 0040104B add eax,dword ptr [ebp+0Ch]
- 6: }
- 0040104E pop edi
- 0040104F pop esi
- 00401050 pop ebx
- 00401051 mov esp,ebp
- 00401053 pop ebp
- 00401054 ret
- --- F:/1/2.cpp ----------------------------------------------------------------------------------------------------------
- 7:
- 8: int main()
- 9: {
- 00401060 push ebp
- 00401061 mov ebp,esp
- 00401063 sub esp,44h //注意多分配了4个字节
- 00401066 push ebx
- 00401067 push esi
- 00401068 push edi
- 00401069 lea edi,[ebp-44h]
- 0040106C mov ecx,11h
- 00401071 mov eax,0CCCCCCCCh
- 00401076 rep stos dword ptr [edi]
- 10: int c=Add(3,5);
- 00401078 push 5
- 0040107A push 3
- 0040107C call @ILT+0(Add) (00401005)
- 00401081 add esp,8
- 00401084 mov dword ptr [ebp-4],eax
- 11: return 0;
- 00401087 xor eax,eax
- 12: }
- 00401089 pop edi
- 0040108A pop esi
- 0040108B pop ebx
- 0040108C add esp,44h
- 0040108F cmp ebp,esp
- 00401091 call __chkesp (00408180)
- 00401096 mov esp,ebp
- 00401098 pop ebp
- 00401099 ret
这是int类型,那如果是char类型,float类型,double类型呢
代码类似,我写出重要的部分.
char类型
5: return (a+b);
00401048 movsx eax,byte ptr [ebp+8] //注意指令用 movsx.
0040104C movsx ecx,byte ptr [ebp+0Ch]
00401050 add eax,ecx
10: int c=Add('c','a');
00401088 push 61h
0040108A push 63h
0040108C call @ILT+0(Add) (00401005)
00401091 add esp,8 //Add函数执行完,跳到这
00401094 movsx eax,al//注意又是movsx
00401097 mov dword ptr [ebp-4],eax
movsx 将有符号数符号位扩展再传送
movzx 无论有符号还是无符号高位全部置0扩展
float 类型
用了80387指令.
5: return (a+b);
00401048 fld dword ptr [ebp+8]
0040104B fadd dword ptr [ebp+0Ch]
1.浮点数操作
fld指令从内存中将一个4字节(single)、8字节(double)、10字节(double extended)的浮点数压入FPU的浮点寄存器栈中
FLD src
装入实数到st(0)
st(0) <- src (mem32/mem64/mem80)
加法
FADD
加实数
st(0) <-st(0) + st(1)
到了 c=Add(3.0,5.0);
0040108A fstp dword ptr [ebp-4]
FSTP dest
dest <- st(0) (mem32/mem64/mem80);然后再执行一次出栈操作
double 类型
5: return (a+b);
00401048 fld qword ptr [ebp+8] //注意用qword
0040104B fadd qword ptr [ebp+10h]
到了c=Add(3.0,5.0);
0040108B add esp,10h
0040108E fstp dword ptr [ebp-4]
总结:
char , int 类型照样用EAX.
float ,double类型有st(0).