(我是ARM领域的新手。请问这是一个愚蠢的问题。)
我正在使用以下命令行为C文件生成汇编代码。
CPU为arm926ej-s
,即ARMv5 architecture
。
arm-none-eabi-gcc -mcpu=arm926ej-s -mthumb -S t.c -o t_thumb.S
arm-none-eabi-gcc -mcpu=arm926ej-s -marm -S t.c -o t_arm.S
我期望-marm
和-mthumb
选项会产生不同的功能序言。但是它们给出了相似结果:
-marm:
@ args = 0, pretend = 0, frame = 72
@ frame_needed = 1, uses_anonymous_args = 0
push {fp, lr} @<========== push is used instead of stmfd
add fp, sp, #4
sub sp, sp, #72
bl uart_init
-mthumb:
@ args = 0, pretend = 0, frame = 72
@ frame_needed = 1, uses_anonymous_args = 0
push {r7, lr} @<========== push is used as expected
sub sp, sp, #72
add r7, sp, #0
bl uart_init
因此它们都使用push
指令。但是,当我检查ARMv5架构规范时,push
指令 only 属于Thumb
指令集。我原以为stmfd
选项是-marm
。
为什么选择push
呢?
如何生成纯 ARM指令?
下面是.o
文件的反汇编:
arm-none-eabi-gcc -mcpu=arm926ej-s -marm -g -c t.c -o build/t_arm.o
arm-none-eabi-objdump.exe -d build/t_arm.o > t_arm.dism
反汇编:
000002a0 <main>:
2a0: e92d4800 push {fp, lr} <=============== push is used!
2a4: e28db004 add fp, sp, #4
2a8: e24dd048 sub sp, sp, #72 ; 0x48
2ac: ebfffffe bl 0 <uart_init>
2b0: e59f3168 ldr r3, [pc, #360] ; 420 <main+0x180>
2b4: e50b300c str r3, [fp, #-12]
2b8: e59f1164 ldr r1, [pc, #356] ; 424 <main+0x184>
2bc: e51b000c ldr r0, [fp, #-12]
感谢 @Erlkoenig 。
我只是试图反汇编-mthumb
二进制文件:
arm-none-eabi-gcc -mcpu=arm926ej-s -mthumb -g -c t.c -o build/t_thumb.o
arm-none-eabi-objdump.exe -d build/t_thumb.o > t_thumb.dism
显示了完全不同的thumb
拆卸:
00000170 <main>:
170: b580 push {r7, lr} <====== though still push is shown, but the encoding is different.
172: b092 sub sp, #72 ; 0x48
174: af00 add r7, sp, #0
176: f7ff fffe bl 0 <uart_init>
17a: 4b3c ldr r3, [pc, #240] ; (26c <main+0xfc>)
17c: 643b str r3, [r7, #64] ; 0x40
17e: 4a3c ldr r2, [pc, #240] ; (270 <main+0x100>)
180: 6c3b ldr r3, [r7, #64] ; 0x40
答案 0 :(得分:1)
objdump -d
所示的原始指令的十六进制编码表示该是32位ARM(“ A32”)指令(0xe92d4800)。由.S
标志生成到-S
的{{1}}文件和GCC
输出仅使用ARM UAL(统一程序集语法),该文件使用objdump
作为push
的别名,而《 ARMv5T体系结构参考手册》使用旧语法,在A32上没有stmfd
。指令编码与push
的编码匹配,其中stmdb
是别名。编码显示在p。 《 ARMv5T参考手册》中的339。
A32(“ ARM”)代码很容易识别,因为所有指令均为4字节宽,而前4位通常为十六进制stmfd
(这意味着条件代码为E
,即指令总是无条件执行):
AL
在十六进制编辑器中查看原始二进制文件时,这很有用。 Thumb(“ T32”)代码具有许多16位指令,一些32位指令,并且没有[e]92d4800
[e]28db004
[e]24dd048
[e]bfffffe
的“堆栈”:
E
当然,对于原始二进制文件,并不能直接明确将2个字节组和4个字节组作为指令一起归类。