ARM 汇编 - "Expression too complex" 或 "lo register required" with stmfd sp!, [lr]

ARM Assembly - "Expression too complex" or "lo register required" with stmfd sp!, [lr]

我正在学习汇编,尤其是 ARM 处理器。

这是我的非常简单的汇编代码:

            .data
integer:    .long   25

        .text
        .global main
main:   stmfd sp!, [lr]
        ldr r0, =integer
        ldr r1, [r0]
        add r1, #2
        str r1, [r0]
        ldmfd sp!, [lr]
        mov pc, lr

我遇到的错误是:

test.s: Assembler messages:
test.s:6: Error: expression too complex -- `stmfd sp!,[lr]'
test.s:11: Error: expression too complex -- `ldmfd sp!,[lr]'

我不知道为什么会出现此错误..搜索了很多,但找不到任何东西..

STore Multiple / LoaD Multiple 指令采用 list 寄存器,包含在 {} 而不是 [].

在ARM模式下,stmfd sp!, {lr}汇编就好,反汇编回
e92d4000 stmfd sp!, {lr}arm-none-eabi-objdump -d


在 Thumb 模式下,push/pop 是具有自己的助记符和操作码的独立指令。
例如b500 push {lr}。使用它是因为它更有效(当您的寄存器列表仅包含 r0..r7, lr. 中的寄存器时)

stmfd 存在于 Thumb-2 中,但显然 GAS 只能在 .syntax unified 模式下正确处理它。没有它,stmfd sp!,{lr} 给出 Error: lo register required.

但是使用 .syntax unified 我们得到 f84d ed04 str.w lr, [sp, #-4]!,结合其他寄存器我们可以做类似 e929 4803 stmdb r9!, {r0, r1, fp, lr} 的事情,它显然使用非 lo 寄存器作为地址和register-list,反汇编为 stmdb 助记符。 (对于商店,FD = 完全降序与 DB = Decrement Before 相同。)

例如我把它放到 foo.s 这样我就可以 运行 arm-none-eabi-gcc -c 了。 (gcc -mthumb 似乎对汇编无关紧要,只编译 C)。

.syntax unified
.cpu cortex-m3
.thumb_func

  stmfd r3!, {r0, r1}             @ different error message, but still only unified syntax
  stmfd r9!, {r0, r1, r11, lr}    @ only in unified
  stmfd sp!, {lr}                 @ only in unified
  push {lr}

没有.syntax unified,我们得到

foo.s: Assembler messages:
foo.s:5: Error: Thumb-2 instruction only valid in unified syntax -- `stmfd r3!,{r0,r1}'
foo.s:6: Error: lo register required -- `stmfd r9!,{r0,r1,r11,lr}'
foo.s:7: Error: lo register required -- `stmfd sp!,{lr}'

第一条错误信息可能是GAS其他错误信息之谜的关键:Thumb-2指令仅在统一语法中有效.

也许 GAS 在拆分解析模式模式下只是检查寄存器编号是否为 lo,然后再验证助记符是否对该模式有效。 所以我们可能会收到基于将 Thumb 1 规则应用于 Thumb2-only 指令的错误消息。

TL:DR: 始终使用 .syntax unified,默认为哑。