为什么-marm选项仍然生成拇指指令?

时间:2019-12-18 09:05:23

标签: arm

(我是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指令?

ADD 1-15:00-12/18/2019

下面是.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]

ADD 2-2019/12/18下午5:34

感谢 @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

1 个答案:

答案 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个字节组作为指令一起归类。