汇编大作业

写一个简单的c语言程序并用反汇编工具得到其汇编代码,对其汇编代码进行注释解释。

要求:程序中要包含加减乘除基本运算。

以下是我选取的C语言程序


#include

int solve(int a,int b,int c)
{
    int result = 0;
    a = 4*a;
    b = 7+b;
    c = c / 2;
    if (result < a){
        result = a;
    }
    if(result < b){
        result = b;
    }
    if (result < c){
        result = c;
    }
    return result;
}

int main(void)
{
    printf("请输入三个数据(a,b,c):\n");
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    a = solve(a,b,c);
    printf("4*a,7+b,c/2中最大是:%d\n",a);
    return 0;
}

以下是我认为的汇编代码的意思。

注释即为我对代码的理解。希望大家认真思考,不到最后一刻不要放弃。

1:
2:    #include
3:
4:    int solve(int a,int b,int c)
5:    {
00401020   push        ebp    ;保存ebp的值,在这个函数中要用这个寄存器
00401021   mov         ebp,esp  ;获得栈顶指针的位置
00401023   sub         esp,44h   ;腾出位置在这个函数中使用
00401026   push        ebx   ;保护现场
00401027   push        esi  ;保护现场
00401028   push        edi  ;保护现场
00401029   lea         edi,[ebp-44h]  ;获得刚才分配的空间的栈顶指针
0040102C   mov         ecx,11h   ;将要循环填充的次数
00401031   mov         eax,0CCCCCCCCh  ;要循环填充的数值
00401036   rep stos    dword ptr [edi]   ;循环填充刚才分配的空间
6:        int result = 0;
00401038   mov         dword ptr [ebp-4],0  ;保存临时变量
7:        a = 4*a;
0040103F   mov         eax,dword ptr [ebp+8]  ;取出第一个参数
00401042   shl         eax,2   ;参数左移两位,即乘以四
00401045   mov         dword ptr [ebp+8],eax  ;保存结果
8:        b = 7+b;
00401048   mov         ecx,dword ptr [ebp+0Ch]  ;取出计算参数
0040104B   add         ecx,7  ;参数加7
0040104E   mov         dword ptr [ebp+0Ch],ecx  ;保存结果
9:        c = c / 2;
00401051   mov         eax,dword ptr [ebp+10h]   ;取出计算参数
00401054   cdq        
00401055   sub         eax,edx   ;eax-edx
00401057   sar         eax,1     ;右移一位,相当于除以二
00401059   mov         dword ptr [ebp+10h],eax  ;保存结果
10:       if (result < a){
0040105C   mov         edx,dword ptr [ebp-4]  ;取出临时变量
0040105F   cmp         edx,dword ptr [ebp+8]  ;比较大小
00401062   jge         solve+4Ah (0040106a)  ;如果大于等于就跳转
11:           result = a;
00401064   mov         eax,dword ptr [ebp+8]   ;小于就取出a的值
00401067   mov         dword ptr [ebp-4],eax  ;赋值给临时变量,入栈
12:       }
13:       if(result < b){
0040106A   mov         ecx,dword ptr [ebp-4]  ;取出临时变量
0040106D   cmp         ecx,dword ptr [ebp+0Ch]  ;比较大小
00401070   jge         solve+58h (00401078)  ;如果大于等于就跳转
14:           result = b;
00401072   mov         edx,dword ptr [ebp+0Ch]  ;小于就取出b的值
00401075   mov         dword ptr [ebp-4],edx   ;赋值给临时变量,入栈
15:       }
16:       if (result < c){
00401078   mov         eax,dword ptr [ebp-4]  ;取出临时变量
0040107B   cmp         eax,dword ptr [ebp+10h]  ;比较大小
0040107E   jge         solve+66h (00401086)  ;如果大于等于就跳转
17:           result = c;
00401080   mov         ecx,dword ptr [ebp+10h]  ;小于就取出c的值
00401083   mov         dword ptr [ebp-4],ecx  ;赋值给临时变量,入栈
18:       }
19:       return result;
00401086   mov         eax,dword ptr [ebp-4]  把结果保存到eax中
20:   }
00401089   pop         edi   ;恢复现场
0040108A   pop         esi    ;恢复现场
0040108B   pop         ebx   ;恢复现场
0040108C   mov         esp,ebp  ;恢复现场
0040108E   pop         ebp   ;恢复现场
0040108F   ret   ;返回主函数
21:


22:   int main(void)
23:   {
004010B0   push        ebp   ;保存ebp寄存器的值,保护现场
004010B1   mov         ebp,esp  ;取出esp中的值给ebp调用
004010B3   sub         esp,4Ch  ;esp地址减少4cH个字节,用来临时存放数据
004010B6   push        ebx  ;保存ebx寄存器的值,保护现场
004010B7   push        esi  ;保护现场
004010B8   push        edi  ;保护现场
004010B9   lea         edi,[ebp-4Ch]  ;找到存放临时数据的栈顶位置
004010BC   mov         ecx,13h  ;循环次数
004010C1   mov         eax,0CCCCCCCCh  ;临时空间中数据的默认值
004010C6   rep stos    dword ptr [edi]  ;重复往栈中填入默认值
24:       printf("请输入三个数据(a,b,c):\n");
004010C8   push        offset string "\xc7\xeb\xca\xe4\xc8\xeb\xc8\xfd\xb8\xf6\xca\xfd\xbe\xdd(a,b,c)\xa3\xba\n
;把字符串的首地址入栈
004010CD   call        printf (004011b0)  ;调用printf函数
004010D2   add         esp,4  ;栈指针下移四个字节,跳过上一个函数的传入参数
25:       int a, b, c;
26:       scanf("%d %d %d", &a, &b, &c);
004010D5   lea         eax,[ebp-0Ch]  ;分配一个临时空间给变量,取得其首地址
004010D8   push        eax   ;寄存器将取得的地址入栈
004010D9   lea         ecx,[ebp-8]  ;同上
004010DC   push        ecx
004010DD   lea         edx,[ebp-4];同上
004010E0   push        edx
004010E1   push        offset string "%d %d %d" (00425028)  ;将要用的字符串首地址入栈
004010E6   call        scanf (00401150) ;调用输入函数
004010EB   add         esp,10h  ;跳过之前用栈传递的参数
27:       a = solve(a,b,c);
004010EE   mov         eax,dword ptr [ebp-0Ch]  ;把之前保存在栈中的结果取出来
004010F1   push        eax  ;入栈
004010F2   mov         ecx,dword ptr [ebp-8]  ;同上
004010F5   push        ecx
004010F6   mov         edx,dword ptr [ebp-4];同上
004010F9   push        edx
004010FA   call        @ILT+0(solve) (00401005)  ;调用自己写的求最大值的函数
004010FF   add         esp,0Ch  ;跳过函数参数
00401102   mov         dword ptr [ebp-4],eax  ;将返回值保存起来
28:       printf("4*a,7+b,c/2中最大是:%d\n",a); 
00401105   mov         eax,dword ptr [ebp-4]  ;把要输出的数取出来
00401108   push        eax  ;入栈
00401109   push        offset string "4*a,7+b,c/2\xd6\xd0\xd7\xee\xb4\xf3\xca\xc7\xa3\xba%d\n" (00426028)  ;要输出的字符串
0040110E   call        printf (004011b0)  ;调用打印函数
00401113   add         esp,8  ;跳过函数参数
29:       return 0;
00401116   xor         eax,eax  ;eax清零
30:   }
00401118   pop         edi
00401119   pop         esi
0040111A   pop         ebx
0040111B   add         esp,4Ch
0040111E   cmp         ebp,esp
00401120   call        __chkesp (00401230)
00401125   mov         esp,ebp
00401127   pop         ebp
00401128   ret

你可能感兴趣的:(汇编)