linux - arm-linux-gnueabi 编译器选项

标签 linux gcc arm objdump

我正在使用 arm-linux-gnueabi-gcc 在 Linux 中为 ARM 处理器编译 C 程序。但是,我不确定它编译的默认 ARM 模式是什么。

例如,对于 C 代码:

测试.c

unsigned int main()
{
    return 0x1ffff;
}

arm-linux-gnueabi-gcc -o test test.c

现在,当我使用 objdump 查看 main() 函数的反汇编时,我可以看到:

arm-linux-gnueabi-objdump -d test

<main>:

    push    {r7}
    add r7, sp, #0
    movw    r3, #65535  ; 0xffff
    movt    r3, #1
    mov r0, r3
    mov sp, r7
    pop {r7}
    bx  lr

看来这是对 ARM 的 Thumb 模式的反汇编(因为 push 指令)。

如何显示反汇编如下:

      .sect ".text"
      .global _fn
_fn:  MOVW A1,#65535
      MOVT A1,#1

      BX LR

或者这个

      .sect ".text"
      .global _fn
_fn:  LDR A1, CON1
      BX LR

      .sect ".text"
      .align 4
CON1: .word 0x1ffff

我在这里看到了这个例子:

http://e2e.ti.com/support/development_tools/compiler/f/343/t/40580.aspx

但是,我无法按照显示的方式查看反汇编。

谢谢。

最佳答案

push不一定告诉你它处于拇指模式,事实上 ARM 的新汇编语法称为 unified assembly language 这意味着在大多数情况下你可以将相同的代码编译到 armthumb-2 指令集。

另一个问题是,您在 -O0 模式下编译,这会添加一些额外的指令以便于调试。试试 -O2,你应该得到你想要的指令流。

gcc-v 开关如 arm-linux-gnueabi-gcc -v 应该向您展示它是如何构建的,这也告诉您编译源代码时它使用的总体默认选项。

最后一件事,您提到的目标装配序列使用 ATPCS 寄存器命名方案(查看 objdump doc 了解信息),它使用 a1 而不是 r0 例如。您还可以通过在 objdump 中使用 -M 开关设置 disassembler-options 来获得此信息。如下所示;

$ arm-linux-gnueabihf-gcc -c -O2 -o test test.c
$ arm-linux-gnueabihf-objdump -M reg-names-special-atpcs -d test

test:     file format elf32-littlearm


Disassembly of section .text.startup:

00000000 <main>:
   0:   f64f 70ff   movw    a1, #65535  ; 0xffff
   4:   f2c0 0001   movt    a1, #1
   8:   4770        bx  LR
   a:   bf00        nop

另一种选择是使用 -S 开关从 gcc 本身获取程序集输出。如下所示;

$ arm-linux-gnueabihf-gcc -S test.c

那么你应该在同一个文件夹中得到一个名为 test.s 的新文件。不过不知道有没有设置寄存器命名的选项。

关于linux - arm-linux-gnueabi 编译器选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18328060/

相关文章:

c++ - 嵌套 C++ 模板的一个例子

c++ - 对嵌套结构单链和双链进行排序

ARM64 缓冲区溢出 - 无法覆盖 $pc

php - 将 Linux Curl 命令转换为 PHP

c - Mac 和 Linux 的 Authenticode 或其他代码签名

python - 如何找到 Python 生成的进程的名称?

java - 如何从 Java 卸载 Linux 文件夹

c++ - static_cast 转换构造函数 vs 转换运算符

arm - ARM 汇编语言指令中的排列说明符(.16b,.8b) 是什么?

Linux DMA API 问题