【问题标题】:GCC compile and link raw outputGCC 编译和链接原始输出
【发布时间】:2015-05-26 21:54:15
【问题描述】:

我正在尝试获取带有函数调用的简单 C 程序的原始指令代码输出。

我已经在这里和谷歌上搜索过答案,但只能找到对单个函数正确的答案(没有函数调用)。

一个简单的例子:

int main(){
    return addition(5, 7);
}

int addition(int a, int b){
    return a + b;
}

当我在此使用gcc -c test.c -o test.o 然后objdump -d test.o 时,JAL(跳转和链接)指令显示跳转到地址0x00000000,这显然是不正确的,但是当我完全编译程序时,我得到objdump 命令中有大量垃圾

我正在使用 mips 编译器(以及相关的 mips-objdump 等)进行编译。

我正在编译的程序是自包含的(没有外部库或系统包含文件)。我想要的是指令转储,其中JAL 和等效指令指向它们调用的函数的正确地址。

【问题讨论】:

    标签: gcc assembly mips


    【解决方案1】:

    虽然您的代码未链接,但地址可能会或可能不会被解析(绝对地址肯定不会)。在后一种情况下,如果您使用objdump -dr,您应该会看到重定位条目。如果你链接你的程序,这些问题应该会消失,如果程序真的是独立的(即甚至不是 C 库),那么你看到的应该就是你的代码。您可能想使用-nostdlib 切换到 gcc。我没有可用的 mips gcc,但这里是 x86 版本的说明:

    080480d8 <addition>:
     80480d8:       8b 44 24 08             mov    0x8(%esp),%eax
     80480dc:       03 44 24 04             add    0x4(%esp),%eax
     80480e0:       c3                      ret
    
    080480e1 <main>:
     80480e1:       83 ec 08                sub    $0x8,%esp
     80480e4:       c7 44 24 04 07 00 00    movl   $0x7,0x4(%esp)
     80480eb:       00
     80480ec:       c7 04 24 05 00 00 00    movl   $0x5,(%esp)
     80480f3:       e8 e0 ff ff ff          call   80480d8 <addition>
     80480f8:       83 c4 08                add    $0x8,%esp
     80480fb:       c3                      ret
    

    这就是二进制文件中的所有代码,正如您在80480f3 看到的那样,call 已解决。我希望它对 mips 的工作方式类似。

    【讨论】:

    • 非常有趣,并且接近我想要的结果,添加 -nostdlib 选项有效(我很想知道为什么),但是我的数据从地址 0x004000d0 开始(对应于我在编译期间收到的警告消息)但是它是从该地址开始的 addition 函数,而不是 main。有没有办法 a) 强制 main 到这个地址或 b) 确定 main 所在的位置?我知道crt0.o 和类似的通常会执行此任务,但这不是我的选择
    猜你喜欢
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 2016-02-12
    • 1970-01-01
    • 2015-09-01
    • 2012-01-16
    • 1970-01-01
    相关资源
    最近更新 更多