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
,默认为哑。
我正在学习汇编,尤其是 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
,默认为哑。