汇编学习-汇编指令与C语言


  • 一段C代码:

    int _tmain(int argc, _TCHAR* argv[])

    {

    return 0;

    }

     

     

    编译后汇编代码:

               mainret = wmain(argc, argv, envp);

    013C16C6 mov         eax,dword ptr [envp (13C7140h)] 

    013C16CB push        eax 

    013C16CC mov         ecx,dword ptr [argv (13C7144h)] 

    013C16D2 push        ecx 

    013C16D3 mov         edx,dword ptr [argc (13C713Ch)] 

    013C16D9 push        edx 

    013C16DA call        @ILT+5(_wmain) (13C100Ah)       //调用main函数

    013C16DF add         esp,0Ch                         //main函数ret指令后执行

    013C16E2 mov         dword ptr [mainret (13C7154h)],eax 

     

     

    int _tmain(int argc, _TCHAR* argv[])

    {

    013C1350 push        ebp         

    013C1351 mov         ebp,esp 

    013C1353 sub         esp,0C0h 

    013C1359 push        ebx 

    013C135A push        esi 

    013C135B push        edi 

    013C135C lea         edi,[ebp-0C0h] 

    013C1362 mov         ecx,30h 

    013C1367 mov         eax,0CCCCCCCCh 

    013C136C rep stos    dword ptr es:[edi] 

    return 0;

    013C136E xor         eax,eax 

    }

    013C1370 pop         edi 

    013C1371 pop         esi 

    013C1372 pop         ebx 

    013C1373 mov         esp,ebp 

    013C1375 pop         ebp 

    013C1376 ret 

     

    函数调用前程序各种寄存器的值:

     

     

    EAX = 00574290 EBX = 7EFDE000 ECX = 005731E0 EDX = 00000001 ESI = 00000000 EDI = 00000000 EIP = 013C1350ESP = 0037FD3C EBP = 0037FD88 EFL = 00000202

     

     

    常见汇编指令:

    1. 堆栈指令:(堆栈从高向低地址增长)

    Push:将一个32的操作数入栈,esp寄存器将被减4

    Pop:相反,esp寄存器将被加4

    Sub:减法,第一个参数被减去的寄存器,第二个参数减数

    Add:加法

    Ret:返回,返回到调用者Call指令的下一条指令

     

    1. 数据传送指令:

    Mov:数据移动,第一个目的,第二个来源

    Xor:异或,逻辑运算指令,xor eax eax指令常代替move exa 0指令,速度更快。

    xor eax eax,看见这样的指令应该明白就是清零操作

    Lea:将第二个参数的地址,放入前面寄存器中。

    lea        edi,[ebp-0C0h]   //[]表示存储器,ebp-0C0h表示存储器内容

    Rep:串存储指令,它的功能是将eax的值放入到edi所指的地址中,同时edi增加4字节。Ret指令重复ecx中填写的次数。

     

    C函数的参数传递

    1_cdcel C调用规则:(C编译器的默认规则)

    1)参数从右到左依次入堆栈

    2)调用函数

    3)函数返回后,由被调用者清理堆栈(_stdcall由调用者清理堆栈)。

    注:在Windows中,不管哪中调用方法,所有的返回值都放在eax中,然后返回。外部由eax得到返回值。

     

     

     

    2_cdcel函数调用汇编分析:

    1)保存ebpebp总是用于保存函数执行前的esp的值,函数执行完成后用ebp恢复esp的值。执行前将ebp值入栈,函数返回时弹出,恢复ebp值。

    push        ebp         

    mov         ebp,esp 

     

    2)在堆栈中预留一个区域用来保存局部变量。

    sub         esp,0C0h 

     

    3)保存ebx,esi,edi到堆栈中,调用完恢复。

    push        ebx 

    push        esi 

    push        edi 

     

    4)把局部变量区域全部初始化为0CCCCCCCCh

    lea         edi,[ebp-0C0h] 

    mov         ecx,30h 

    mov         eax,0CCCCCCCCh 

    rep stos    dword ptr es:[edi] 

     

    5ediesiex出栈,恢复espebp

    return 0;

    xor         eax,eax 

    }

    pop         edi 

    pop         esi 

    pop         ebx 

    mov        esp,ebp          //恢复esp值:0037FD40

    pop        ebp              //恢复ebp值:0037FD3C

    ret 

     

    函数调用返回后的寄存器值

     

    EAX = 00000000 EBX = 7EFDE000 ECX = 00000000 EDX = 00000001 ESI = 00000000 EDI = 00000000 EIP = 013C16DFESP = 0037FD40 EBP = 0037FD88 EFL = 00000246

     

     

    esp值恢复,ebp0037FD3C40037FD40堆栈下个地址,一个函数调用远程完成。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值