C语言函数的内存存储形态及控制指令二进制转换疑问
函数在内存中的形态与代码的二进制转换
一、函数在内存里到底是什么?
函数和int这类数据变量完全不是一回事:
- 变量是用来存数据的内存块,比如
int占2或4字节,里面放的是整数的二进制值。而函数是一段连续的可执行机器指令,被存在程序的「代码段」(也叫文本段)里。 - 函数指针指向的就是这段指令序列的起始内存地址。比如你定义
int add(int a, int b) { return a+b; },编译后会变成CPU能直接跑的机器指令(比如x86架构下的寄存器操作、加法指令),这些指令挨个儿存在代码段里,add这个函数名其实就是这段指令的起始地址。
二、if、while、malloc这些是怎么变成二进制的?
1. if、while这类控制语句
它们会被编译器转成条件跳转指令:
- 比如
if (x > 0),编译后先生成比较x和0的指令,然后根据比较结果生成跳转指令——如果x>0成立,就跳转到if块里的指令执行;不成立就直接跳到if块后面的代码。 while的逻辑类似,只不过在循环体的最后会加一条跳转回条件判断的指令,形成“判断→执行→再判断”的循环结构。
2. malloc这类库函数
malloc本身是标准库里预先写好、编译好的一段可执行代码。如果是静态链接,它会被合并到你的程序代码段里;如果是动态链接,它会在程序运行时从系统的动态链接库(比如Windows上的msvcrt.dll、Linux上的libc.so)里加载。- 当你写
malloc(1024)时,编译器会生成一条「函数调用指令」(比如x86下的call指令),这条指令会让CPU跳转到malloc函数的起始地址去执行它的逻辑,等malloc完成内存分配后,再通过ret指令跳回你原来的代码位置,同时把分配好的内存地址返回给你。
额外补充
C代码从文本变成可执行程序要经过预处理、编译、汇编、链接这几步:汇编阶段就会把C语句转换成对应的二进制机器码,链接阶段会把各个模块的代码段、数据段拼起来,确定所有函数和变量的最终内存地址。另外,代码段一般是只读的,防止程序不小心改了自己的执行指令,而存变量的数据段是可读写的。
内容的提问来源于stack exchange,提问作者roeegg
相关产品推荐
相关产品推荐

