【3.26】学习笔记

因为昨天接女朋友,所以中间休息一天。下面继续学习。

1.函数调用

    保存现场-->传递参数-->返回

    调用函数时:

    将被调用函数所需参数从右至左压入栈中。(具体调用还是有区别的,后面再详细说)

    call指令调用函数,并将下一条指令当作返回值压入栈中(该操作含在call指令)

    被调用函数会先保存调用函数的栈底地址(在高地址保存即push ebp),然后将调用函数的栈顶地址(mov ebp,esp)

    被调函数的从ebp开始保存局部变量和临时变量(即先定义的变量先入栈)

                

    执行完成后将返回地址弹出,ebp弹出恢复上一个函数状态。

2.函数调用

    x86调用主要有三种:cdel(C规范调用),stdcall(win API调用),fastcall


    cdel:函数从右到左调用,调用着实现栈平衡,返回值放入EAX (即将参数压入栈后进行堆栈平衡)

 int cdecl_sum = cdecl_add(1, 2, 3, 4, 5, 6, 7);

00401138   push        7

0040113A   push        6

0040113C   push        5

0040113E   push        4

00401140   push        3

00401142   push        2

00401144   push        1

00401146   call        @ILT+5(_cdecl_add) (0040100a)

0040114B   add         esp,1Ch  # 栈平衡

0040114E   mov         dword ptr [ebp-4],eax    # 返回值



int __cdecl cdecl_add(int a, int b, int c, int d, int e, int f, int g)

4:    {

00401030   push        ebp

00401031   mov         ebp,esp

00401033   sub         esp,44h

00401036   push        ebx

00401037   push        esi

00401038   push        edi

00401039   lea         edi,[ebp-44h]

0040103C   mov         ecx,11h

00401041   mov         eax,0CCCCCCCCh

00401046   rep stos    dword ptr [edi]

5:        int sum = a+b+c+d+e+f+g;

00401048   mov         eax,dword ptr [ebp+8]

0040104B   add         eax,dword ptr [ebp+0Ch]

0040104E   add         eax,dword ptr [ebp+10h]

00401051   add         eax,dword ptr [ebp+14h]

00401054   add         eax,dword ptr [ebp+18h]

00401057   add         eax,dword ptr [ebp+1Ch]

0040105A   add         eax,dword ptr [ebp+20h]

0040105D   mov         dword ptr [ebp-4],eax


dword ptr【ebp-4】,eax 把eax值赋给偏移ebp-4的双字

6:        return sum;

00401060   mov         eax,dword ptr [ebp-4]    # 存放返回值

7:    }

00401063   pop         edi

00401064   pop         esi

00401065   pop         ebx

00401066   mov         esp,ebp

00401068   pop         ebp

00401069   ret



stdcall 参数从右至左入栈,被调用者平衡堆栈,返回值放入eax

  int stdcall_sum = stdcall_add(1, 2, 3, 4, 5, 6, 7);

00401151   push        7

00401153   push        6

00401155   push        5

00401157   push        4

00401159   push        3

0040115B   push        2

0040115D   push        1

0040115F   call        @ILT+15(_stdcall_add@28) (00401014)

00401164   mov         dword ptr [ebp-8],eax    # 返回值

 

9:    int __stdcall stdcall_add(int a, int b, int c, int d, int e, int f, int g)

10:   {

00401080   push        ebp

00401081   mov         ebp,esp

00401083   sub         esp,44h

00401086   push        ebx

00401087   push        esi

00401088   push        edi

00401089   lea         edi,[ebp-44h]

0040108C   mov         ecx,11h

00401091   mov         eax,0CCCCCCCCh

00401096   rep stos    dword ptr [edi]

11:       int sum = a+b+c+d+e+f+g;

00401098   mov         eax,dword ptr [ebp+8]

0040109B   add         eax,dword ptr [ebp+0Ch]

0040109E   add         eax,dword ptr [ebp+10h]

004010A1   add         eax,dword ptr [ebp+14h]

004010A4   add         eax,dword ptr [ebp+18h]

004010A7   add         eax,dword ptr [ebp+1Ch]

004010AA   add         eax,dword ptr [ebp+20h]

004010AD   mov         dword ptr [ebp-4],eax

12:       return sum;

004010B0   mov         eax,dword ptr [ebp-4]    # 存放返回值

13:   }

004010B3   pop         edi

004010B4   pop         esi

004010B5   pop         ebx

004010B6   mov         esp,ebp

004010B8   pop         ebp

004010B9   ret         1Ch  # 栈平衡(等价于先 add esp, 1Ch 再 ret)




x64函数调用:

    只使用fastcall调用

    参数1,2,3,4,5,6分别保存在RDI,RSI,RCX,RDX,R8D,R9D之中。剩下的保存到栈,被调用者平衡堆栈。返回值放入RAX之中。

    从右至左入栈,最后四个按R9D R8D顺序入栈

    如有this指针存放如RCX

    

# 该代码是 msvc 2017 x64 生成的汇编代码

    int sum = calc.thiscall_add(1, 2, 3, 4, 5, 6, 7);

00007FF602E6190F  mov         dword ptr [rsp+38h],7 

00007FF602E61917  mov         dword ptr [rsp+30h],6 

00007FF602E6191F  mov         dword ptr [rsp+28h],5 

00007FF602E61927  mov         dword ptr [rsp+20h],4 

00007FF602E6192F  mov         r9d,3 

00007FF602E61935  mov         r8d,2 

00007FF602E6193B  mov         edx,1 

00007FF602E61940  lea         rcx,[calc]              # this指针

00007FF602E61944  call        Calc::thiscall_add (07FF602E610A0h) 

00007FF602E61949  mov         dword ptr [sum],eax    # 返回值

 

int Calc::thiscall_add(int a, int b, int c, int d, int e, int f, int g)

{

00007FF602E61770  mov         dword ptr [rsp+20h],r9d 

00007FF602E61775  mov         dword ptr [rsp+18h],r8d 

00007FF602E6177A  mov         dword ptr [rsp+10h],edx 

00007FF602E6177E  mov         qword ptr [rsp+8],rcx 

00007FF602E61783  push        rbp 

00007FF602E61784  push        rdi 

00007FF602E61785  sub         rsp,0E8h 

00007FF602E6178C  mov         rbp,rsp 

00007FF602E6178F  mov         rdi,rsp 

00007FF602E61792  mov         ecx,3Ah 

00007FF602E61797  mov         eax,0CCCCCCCCh 

00007FF602E6179C  rep stos    dword ptr [rdi] 

00007FF602E6179E  mov         rcx,qword ptr [rsp+108h] 

    int sum = a + b + c + d + e + f + g;

00007FF602E617A6  mov         eax,dword ptr [b] 

00007FF602E617AC  mov         ecx,dword ptr [a] 

00007FF602E617B2  add         ecx,eax 

00007FF602E617B4  mov         eax,ecx 

00007FF602E617B6  add         eax,dword ptr [c] 

00007FF602E617BC  add         eax,dword ptr [d] 

00007FF602E617C2  add         eax,dword ptr [e] 

00007FF602E617C8  add         eax,dword ptr [f] 

00007FF602E617CE  add         eax,dword ptr [g] 

00007FF602E617D4  mov         dword ptr [sum],eax 

    return sum;

00007FF602E617D7  mov         eax,dword ptr [sum]  # 存放返回值

}

00007FF602E617DA  lea         rsp,[rbp+0E8h] 

00007FF602E617E1  pop         rdi 

00007FF602E617E2  pop         rbp 

00007FF602E617E3  ret                                 # 没做栈平衡 (注意此处)



ARM:

    参数1-4放入R0-R3,剩下参数从右至左依次入栈,被调用者平衡堆栈。返回值放入R0

    ARM x64

    (str 类似与mov)

    参数1~参数8 分别保存到 X0~X7 寄存器中 ,剩下的参数从右往左依次入栈,被调用者实现栈平衡,返回值存放在 X0 中。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
易语言汇编替换字节集源码 mov eax, dword ptr [ebp+08h] mov eax, dword ptr [eax]                取出ebp+08h地址(eax值加8后才是真实地址) add eax, 07h                            eax的值为: ebp+08h真实地址减去1(+08H是真实地址,此时+07H),少1是修正后边加替换位置超出的1字节 add eax, dword ptr [ebp+0Ch]            ebp+0Ch结合ebp+08h确定替换位置,并存放到通用寄存器eax mov edi, eax                            eax作为内存指针存放于寄存器edi ------------------------------------------------------------------------------------------------------------------------------------------ mov eax, dword ptr [ebp+10h]            计算ebp+10h字节集指针 mov eax, dword ptr [eax]                计算ebp+10h字节集指针 add eax, 08h                            计算ebp+10h字节集指针 mov esi, eax                            ebp+10h字节集指针存放于esi ------------------------------------------------------------------------------------------------------------------------------------------ mov ecx, dword ptr [ebp+10h]            计算ebp+10h字节集长度 mov ecx, dword ptr [ecx]                计算ebp+10h字节集长度 mov ecx, dword ptr [ecx+04h]            ebp+10h字节集长度值存放到计数存储器ecx rep movsb                               重复操作,重复次数为ecx值,也就是用作替换的字节集长度值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值