已编译二进制文件中的预初始化函数指针?

时间:2018-04-15 14:45:43

标签: c assembly compilation binary clang

我目前正在尝试通过clang编译器将一些简单的C-Code转换为汇编。但是,以下行为让我感到困惑:

int a(void);
int b(void);

int a() {
    return 1;
}

int b() {
    return 2;
}
int c(){
    return 3;
}

int main(int argc, char **argv) {
     int (*procs[])(void) = {a,b};
     int (*procs2[])(void) = {c,b};
...

被翻译为:

enter image description here 我发现地址0x4006XX的值保存了函数a,b和c的相应地址。但是我想知道为什么使用0x4006XX地址的额外步骤是必要的(为什么不使用文字地址?)。甚至更好奇为什么它使用两个不同的地址作为b的地址。  我知道这可能是一个模糊的问题,但任何帮助都表示赞赏:)

1 个答案:

答案 0 :(得分:0)

您的编译器似乎生成位置无关代码。位置无关代码可以在运行时加载到任意地址,使得函数和静态变量的地址在编译时不可预测。可预测的一件事是从变量或函数到当前指令的距离。编译器使用lea指令将指令指针rip的内容添加到此距离以获取实际地址。这就是你所看到的。