3

我正在使用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

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

谢谢。

4

2 回答 2

2

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

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

gccwith -vswitch as inarm-linux-gnueabi-gcc -v应该向您展示它是如何构建的,它还告诉您它在编译源代码时使用的整体默认选项。

最后一件事,您提到的目标汇编序列使用ATPCS寄存器命名方案(有关信息,请查看objdump 文档),它使用a1而不是r0例如。您也可以通过使用开关进行设置disassembler-options来获得此功能。如下所示;objdump-M

$ 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

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

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

那么你应该得到一个test.s在同一个文件夹中调用的新文件。但是我不知道您是否可以设置寄存器命名。

于 2013-08-20T06:20:51.370 回答
0

我相信默认是拇指模式:

arm-linux-gnueabi-gcc -S -mthumb test.c

可以使用 -marm 标志生成完整的 ARM 指令:

arm-linux-gnueabi-gcc -S -marm test.c
于 2014-03-09T08:58:12.643 回答