(六)羽夏看C语言——函数
2021-09-07 16:21
806 查看
写在前面
此系列是本人一个字一个字码出来的,包括示例和实验截图。本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正。 如有好的建议,欢迎反馈。码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作。如想转载,请把我的转载信息附在文章后面,并声明我的个人信息和本人博客地址即可,但必须事先通知我。
你如果是从中间插过来看的,请仔细阅读**(一)羽夏看C语言——简述** ,方便学习本教程。
前篇答疑解惑
答案:不会。 解答:我相信亲手做实验的人都会知道的。
函数
一个程序必须有一个函数,比如C语言中的
main函数,也可以实现别的函数实现功能。本篇文章将从汇编的角度介绍函数,本次实验的代码十分简单。为了防止干扰,请在项目属性中关闭
增量链接和
支持仅我的代码调试(具体作用请搜索科普,它们会生成一些汇编代码来实现相应的功能)。
int main() { int a = 5; return 0; }
得到的反汇编如下:
通过汇编可以看出,函数生成的汇编采用
ebp寻址的方式。前三句汇编进行用
ebp寻址的准备和
提栈准备缓冲区的操作,提供的缓冲区用来给函数内的局部变量用的。
有些生成的反汇编可能是这样的版本:
push ebp mov ebp,esp sub esp,0x40 push ebx push esi push edi lea edi,[ebp-0x40] mov ecx,0x10 mov eax,0xcccccccc rep stosd mov dword ptr [ebp-8],5 xor eax,eax pop edi pop esi pop ebx mov esp,ebp pop ebp ret
有些人可能看不懂以下代码:
lea edi,[ebp-0x40] mov ecx,0x10 mov eax,0xcccccccc rep stosd
上面的代码是将
0xCC填充满整个缓冲区,可帮助检测到堆栈缓冲区溢出,这是一种常见的攻击,威胁程序的安全性。
0xCC即为我们调试的普通断点,汇编为
int 3,即
VS按下
F9下断点(代码行左边的小红点)。
函数调用
int test(int a, int b) { return a + b; } int main() { int a = test(1, 2); return 0; }
然后看一下反汇编:
可以看出函数调用时会通过
push传递参数,然后
call一个地址跳转到
test函数,通过
eax作为
返回值。调用完毕后用
add esp,8平栈,这个所谓的一种
调用约定,被称为
__cdecl。当然调用约定不知这一种,你也可以自定义,不过得从汇编上实现。
调用约定
当一个函数被调用时,函数的参数会被传递给被调用的函数和返回值会被返回给调用函数。函数的调用约定就是描述参数是怎么传递和返回值,由谁平衡堆栈,这就是所谓的调用约定。 我们先给出常见的调用约定,其他的调用约定自行科普:
调用约定 | __stdcall | __cdecl | __fastcall | __pascal |
---|---|---|---|---|
参数传递顺序 | 从右到左 | 从左到右 | 从右到左 | 使用寄存器和栈 |
平栈 | 调用者 | 子程序 | 子程序 | 子程序 |
当然,在
IDA中你可能会看到其他调用约定,比如
__thiscall等。由于调用约定并不是我想重点讲述的,具体细节自行科普。C语言默认的调用约定为
__cdecl,所以在 函数调用 部分已有示例。这部分就用
__fastcall做个为
调用约定示例。
int __fastcall test(int a, int b) { return a + b; } int main() { int a = test(1, 2); return 0; }
如下是反汇编:
下一篇
(七)羽夏看C语言——模板(C++)
相关文章推荐
- c语言结构体里的函数
- 常用C语言字符串操作函数
- C语言中函数参数传递
- 用C语言来实现的类似C++函数的重载特性-----void*指针闲谈
- c语言读写函数
- C语言中不定参数函数的使用
- C语言中关于scanf函数的用法
- C语言printf函数输出表达式中的计算顺序
- C语言-学生信息管理(利用结构体、函数和指针)
- C语言的system函数
- C语言中函数传递(实参 形参)
- 【C语言】主函数的参数探幽
- c语言小函数1
- C语言字符串函数大全
- C语言文件操作函数大全
- 【C语言】04-函数
- C语言中宏定义和函数的取舍
- 【c语言】 编写一个函数reverse_string(char * string)(递归实现)
- C语言的头文件和库文件(函数库)
- 详解C语言的exp()函数和ldexp()函数以及frexp()函数