2013-08-20 50 views
3

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

例如,对于C代码:

test.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模式的反汇编(由于推指令)。

如何显示拆卸如下:

 .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

但是,我不能按照它在那里显示的方式查看反汇编。

谢谢。

回答

2

push并不一定告诉你这是在Thumb模式下,实际上ARM的所谓unified assembly language新装配的语法,这意味着在大多数情况下,你可以编译相同的代码armthumb-2指令集。

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

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

最后一件事,你提到的有针对性的装配顺序使用ATPCS寄存器命名方案(检查objdump doc信息),它使用a1而不是r0例如。您也可以通过在objdump中设置disassembler-options-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 

另一种选择是通过使用-S开关以获得从gcc本身组件输出。如下所示;

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

那么你应该得到一个相同的文件夹名为test.s新文件。但是我不知道是否有一个选项可以设置寄存器命名。

+0

谢谢:)我明白。另外,您是否注意到我上面提到的第二个反汇编示例?在这种情况下,不是移动寄存器中的值,而是从常量CON1加载值。此外,反汇编中不提及像.global,.align,.word这些不同的关键字。 –

+0

我更新了答案,以添加另一种生成装配的方式,您可以在其中播放以获得与您共享的示例类似的输出。另一件事是,你没有注意到他们提到了TI的C/C++编译器。他们可能从该编译器获得了汇编输出。 – auselen

0

我相信默认为Thumb模式:

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

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

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