You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

学习C编译过程:汇编器如何分配内存及确定外部函数跳转地址?

关于C编译中汇编阶段对未定义外部函数的处理

先看你给出的代码:

int add(int a, int b);

int main(){
    int tmp = add(1,2);
    return 0;
}

针对你的问题,逐个说明:

  1. 汇编器不需要知晓add函数的实际地址
    汇编阶段处理调用add的代码时,会用符号引用代替真实地址。比如x86架构下会生成call add这样的汇编指令,汇编器会把add标记为未解析的外部符号,并记录到目标文件(.o)的符号表中。它不需要知道add在哪,只需要标记出“这里有个外部符号,后面要处理”。

  2. 汇编阶段的核心操作
    汇编器的工作是把汇编代码翻译成机器码,同时维护两个关键表:

    • 符号表:记录当前目标文件里定义的符号(比如main)和引用的外部符号(比如add);
    • 重定位表:标记哪些机器指令里的地址是占位符,需要在链接阶段被替换成真实地址。比如call add对应的机器码里会有一个临时地址值,重定位表会告诉链接器“这个位置要替换成add的实际地址”。
  3. 不会为add函数预留内存
    目标文件的text段里只有main函数的代码,add函数的定义根本不在当前编译单元里,所以汇编器不会为它分配任何内存空间。内存分配和地址确定都是链接阶段的事:链接器会找到包含add定义的目标文件/库,把add的代码合并到最终可执行文件的text段,然后根据add的实际位置,修正main里call指令的地址。

另外补充:你提到的“不知道add函数的长度”其实不影响汇编阶段的工作——函数调用指令只关心目标地址,和函数本身的长度没有关系;函数长度是链接时合并段才需要考虑的,但那是链接器的职责,和汇编器无关。

内容的提问来源于stack exchange,提问作者Erinç Utku Öztürk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:03:13