吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3709|回复: 4
收起左侧

[其他转载] [谬]C语言函数传参底层汇编实现原理

[复制链接]
君子谬 发表于 2016-12-2 08:47
1.给函数传递参数
/****************************************************************/
#include<stdio.h>
int Add(int x, int y)
{
                int sum;
                sum = x + y ;
                return sum;
}
int main()
{
                int z;
                z = Add(1, 2);
                printf( "z = %d\n", z);
}
/**************************************************************/
013F182E 6A 02                        push        2
013F1830 6A 01                        push        1
013F1832 E8 20 FB FF FF       call        013F1357
013F1837 83 C4 08                   add         esp,8  
/***************************************************************/
c语言的参数传递是从右到左的
在执行 z = Add(1, 2);的时候
先push了2,esp = 0028F89C
然后push了1,esp = 0028F898
最后call了01341357 esp = 0028F894
0028F894 中保存的地址是函数的返回地址37 18 3f 01,也就是013f1837
01341357 是一个跳转地址,jmp         013F16D0
跳转至 函数的入口地址 013F16D0

2.函数获取参数
/**************************************************************/
#include<stdio.h>
int Add(int x, int y)
{
                int sum;
                sum = x + y ;
                return sum;
}
int main()
{
                int z;
                z = Add(1, 2);
                printf( "z = %d\n", z);
}
/**************************************************************/
在函数执行之前,首先push了两个参数,
然后call到了跳转语句,每次esp-4
所以1的存储地址就是esp+4,2的存储地址就是esp+8
但是由于ESP随栈的变化而变化,所以为了计算简便,可以将该值存储到另一个寄存器,如EBP
那么刚才的两个地址就是EBP+4和EBP+8了
不过由于EBP本身是有值的,如果直接赋值修改它,那么当需要使用EBP的原值得时候,就没办法了
例如函数A调用后返回,如果不还原EBP,函数B用EBP作为基点就会出错,因此需要一个保存和灰度EBP值得过程,
下面的代码完成了这一过程,将EBP压栈,最后pop出来,赋值给ebp,从而还原
push ebp
...
pop ebp

所以在函数开始的地方存在如下代码:
push ebp       //将ebp压栈
mov ebp,esp  //将esp的值给ebp

因为在栈里又压入了ebp的缘故,所以esp将再减少4字节
此时再计算参数1和2的存储地址,存储1的地址是ebp+8,存储2的地址是ebp+0ch(12)
/**********************************************************************/
sum = x + y;
013F16EE 8B 45 08             mov         eax,dword ptr [ebp+8]
013F16F1 03 45 0C             add         eax,dword ptr [ebp+0Ch]
/**********************************************************************/
注释:
mov 将ebp + 8的值给eax,ebp + 8是1,也就是把1给eax
然后ebp + 0ch的值加上eax的值,ebp+0ch的值是2,eax的值是1,1+2 = 3,将结果保存在eax中
Image.png


免费评分

参与人数 1热心值 +1 收起 理由
daxingshen + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

abc123one 发表于 2016-12-2 09:08
补充几句
在子程序获取参数的值时,esp+n,其中n为参数的偏移量,此偏移量的大小取决于参数大小,不一定为4.例如如果一个结构体占12字节,那么应该是esp+4+12,即esp+16.
在子函数返回时,将返回值放入EAX中.若返回值为Qword或real8,那么将高位放入EDX,低位放入EAX.
main函数返回值用xor eax,eax使eax置0,实现return 0.
daxingshen 发表于 2016-12-2 09:21
对味 发表于 2016-12-2 09:34
安宁冠希 发表于 2017-9-27 22:29
买卖 看了就是没有看懂
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-15 07:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表