学习打卡8:参数获取

督促自己:2020-9-16

学习记录:

参数获取:

#include <stdio.h>
int f (int a, int b,int c)
(
	return a*b+c;
);
int main()
{
	printf("%d\n",f(1,2,3));
	return 0;
);
  • x86

    • MSVC

      关键汇编代码:

      在这里插入图片描述

      从被调用方函数的数据栈的角度来看,外部参考的偏移量是正值,而局部变量的偏移量是负值。当需要访问栈帧(stack frame)以外的数据时,被调用方函数可把会变宏(例如_a$)与EBP寄存器的值相加,从而求得所需地址。

    • GCC

      汇编代码:

      在这里插入图片描述

      编译结果和MSVC结果相似,不同在用leave指令还原指令,而不是return 0。

  • x64

x86-64系统能够使用寄存器传递(前4个或前6个)参数,完全不需要访问栈。

  • MSVC

    在这里插入图片描述

    f()函数通过寄存器获取了全部的所需参数,此处求址的加法运算时通过lea指令实现。

  • MSVC未开启优化

    在这里插入图片描述

    位于寄存器的3个参数被推送到栈里,这种现象叫作“阴影空间/shadow space”。

    使用阴影空间有以下两个优点:

    1)通过栈传递参数,可避免浪费寄存器资源(有时可能会占用4个寄存器);

    2)便于调试器debugger在程序中断时找到函数参数。

    在使用阴影空间时,由调用方函数分配栈空间,由被调用方函数根据需要将寄存器参数转储到它们的阴影空间中。

  • GCC -x64

    在这里插入图片描述

    阴影空间只是微软的概念,GCC只有在寄存器数量容纳不下所有参数的情况下,才会使用栈传递参数。

  • ARM

  • Non-optimizing Keil 6/2013(ARM mode)

    在这里插入图片描述

    • 前4个寄存器(R0~R3)负责传递前4个参数
    • f()函数通过前3个寄存器(R0~R2)读取参数。
    • MLA(Multiply Accumulate)指令(乘法累加指令)将前两个操作数(R3和R1里的值)想乘,然后再计算第三个操作数(R2里的值)和这个积的和,并且把最终运算结果存储在零号寄存器R0之中。(R0寄存器存放返回值)
    • BL指令把程序的控制流交给LR寄存器里的地址,而且会在必要的时候切换处理器的运行模式(Thumb模式和ARM模式之间进行模式切换)。如果它被Thumb模式的代码调用,BX指令不仅会进行相应的跳转,还会把处理器模式调整为Thumb。如果它被ARM模式的指令调用,则不会进行模式切换。
  • Optimizing Keil 6/2013(ARM mode)

    在这里插入图片描述

    MLA直接使用所有寄存器的参数并把返回值保存在R0寄存器里

  • Optimizing Keil 6/2013(Thumb mode)

    在这里插入图片描述

    Thmub模式的指令集里没有MLA指令,分为了两个指令:

    • MULS指令计算R0和R1的积,结果存储在R1寄存器;
    • ADDS计算R1和R2的和,结果存在R0寄存器里。
  • ARM64

    ARM64中,MADD指令可以一次进行乘法和加法的混合算法,与MLA类似

    “寄存器保护区/Register Save Area”:与阴影空间相似,把传入的参数保存在数据栈里,以防止后期的指令占用W0~W2寄存器,防止后续指令覆盖函数参数,起到保护传入参数的作用。

  • MIPS

    在这里插入图片描述

    函数所需的前4个参数由4个A-字头寄存器传递;

    • MIPS两个特殊的寄存器:HI和LO(用来存储MULT指令的乘法计算结果,64位的积)。

    • 只有MFLO(访问积的低32位)和MFHI指令能够访问HI和LO寄存器。

    • ADDU(Add Unsigned)指令计算第三个参数与积的和

      ADD指令可以出发溢出处理机制

      ADDU不会引发溢出(因为C/C++不支持这种机制)

    • $V0寄存器存储32位的运算结果

      JAL(Jump and Link)指令:使用相对地址–偏移量

      JALR指令:跳转到寄存器存储的绝对地址里

明日任务:《逆向工程权威指南》上 第九章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值