我正在使用 arm-linux-gnueabi-gcc 来为Linux中的ARM处理器编译C程序。但是,我不确定它编译的默认ARM模式是什么。
例如,对于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
但是,我无法按照它在那里显示的方式查看反汇编。
感谢。
答案 0 :(得分:2)
push并不一定告诉你它处于拇指模式,实际上是ARM的新汇编语法unified assembly language
,这意味着在大多数情况下你可以将相同的代码编译为arm
或thumb-2
指令集。
其他问题是,您正在-O0
模式下进行编译,这会添加一些额外的指令以便于调试。试试-O2
,你应该得到你想要的指令流。
gcc
开关的{p> -v
应该会显示它是如何构建的,它还会告诉您在编译源代码时使用的总体默认选项。
最后一件事,您提到的目标汇编序列使用arm-linux-gnueabi-gcc -v
寄存器命名方案(检查objdump doc获取信息),例如,它使用ATPCS
而不是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
本身获取程序集输出。如下所示;
-S
然后你应该在同一个文件夹中获得一个名为$ arm-linux-gnueabihf-gcc -S test.c
的新文件。但是我不知道是否有一个选项可以设置寄存器命名。
答案 1 :(得分:0)
我认为默认是拇指模式:
arm-linux-gnueabi-gcc -S -mthumb test.c
可以使用-marm标志生成完整的ARM指令:
arm-linux-gnueabi-gcc -S -marm test.c