GNU ARM 汇编程序在错误消息中给出看似无关的寄存器
GNU ARM assembler giving a seemingly irrelevant register in error message
目标
我正在使用 LDREX 和 STREX 指令为 CortexM7 目标使用 gcc 内联汇编构建互斥基元,遵循 ARM 的 Barrier Litmus Tests and Cookbook 文档。
代码
static inline void testAcquireLock(unsigned int *lock) {
unsigned int tempStore1 = 0;
unsigned int tempStore2 = 0;
__asm__ volatile(
"Loop%=: \n\t" // "%=" generates unique #
"LDREX %[ts1], %[lock] \n\t" // exclusive read lock
"CMP %[ts1], #0 \n\t" // check if 0
"ITT EQ \n\t" // block for below conds.
"STREXEQ %[ts1], %[ts2], %[lock] \n\t" // attempt to ex. store new value
"CMPEQ %[ts1], #0 \n\t" // test if store suceeded
"BNE Loop%= \n\t" // retry if not
"DMB \n\t" // mem barrier for subsequent reads
: [lock] "+l"(*lock), [ts1] "=l"(tempStore1), [ts2] "=l"(tempStore2)
: // inputs
: "memory");
}
错误信息
唯一显示的错误如下。汇编程序正在引用 R15,生成的程序集中似乎没有使用它?错误消息中的第 191 行对应于上面看到的第一条 LDREX
指令。
[build] /tmp/ccEU4dXd.s: Assembler messages:
[build] /tmp/ccEU4dXd.s:191: Error: r15 not allowed here -- `ldrex r1,r3'
[build] /tmp/ccEU4dXd.s:194: Error: r15 not allowed here -- `strexeq r1,r2,r3'
Build/Compiler 选项
该项目使用以下编译器设置通过 CMake 配置:
target_compile_options(testing
PRIVATE
-mcpu=cortex-m7
-mfpu=fpv5-d16
-mfloat-abi=hard
-mthumb
-Wall
-fdata-sections
-ffunction-sections
)
导致错误的编译命令:
[build] /usr/bin/arm-none-eabi-gcc -DSTM32F777xx -DUSE_HAL_DRIVER -I<removed> -g -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -Wall -fdata-sections -ffunction-sections -std=gnu11 -o <removed>.c.obj -c <removed>.c
研究/我尝试过的
阅读后我意识到 armv7 有两个(指令集?语法解析器?),并且处理器可以处于这些(ARM 和 THUMB)的两种模式之一。但是我不是很明白这一点,以及它如何影响手写汇编的解析。
我怀疑是因为处理器是thumb模式(-mthumb),跟我的inline alias constraints有关系? Per documentation 我尝试在“+l”、“+r”、“+h”之间切换,但似乎没有任何改变。
我尝试使用硬编码寄存器“r3、r4、r5”而不是内联别名,但出现了同样的错误。
根据@jester 的帮助,我意识到我对锁的 GCC-inline 变量别名有错误的约束。它应该是“+m”,指定内存地址而不是寄存器。
我也是 de-referencing 锁的地址,而我本应将其作为指针保留。
我将 [lock] "+l"(*lock)
更改为 [lock] "+m"(lock)
,现在可以构建了。
目标
我正在使用 LDREX 和 STREX 指令为 CortexM7 目标使用 gcc 内联汇编构建互斥基元,遵循 ARM 的 Barrier Litmus Tests and Cookbook 文档。
代码
static inline void testAcquireLock(unsigned int *lock) {
unsigned int tempStore1 = 0;
unsigned int tempStore2 = 0;
__asm__ volatile(
"Loop%=: \n\t" // "%=" generates unique #
"LDREX %[ts1], %[lock] \n\t" // exclusive read lock
"CMP %[ts1], #0 \n\t" // check if 0
"ITT EQ \n\t" // block for below conds.
"STREXEQ %[ts1], %[ts2], %[lock] \n\t" // attempt to ex. store new value
"CMPEQ %[ts1], #0 \n\t" // test if store suceeded
"BNE Loop%= \n\t" // retry if not
"DMB \n\t" // mem barrier for subsequent reads
: [lock] "+l"(*lock), [ts1] "=l"(tempStore1), [ts2] "=l"(tempStore2)
: // inputs
: "memory");
}
错误信息
唯一显示的错误如下。汇编程序正在引用 R15,生成的程序集中似乎没有使用它?错误消息中的第 191 行对应于上面看到的第一条 LDREX
指令。
[build] /tmp/ccEU4dXd.s: Assembler messages:
[build] /tmp/ccEU4dXd.s:191: Error: r15 not allowed here -- `ldrex r1,r3'
[build] /tmp/ccEU4dXd.s:194: Error: r15 not allowed here -- `strexeq r1,r2,r3'
Build/Compiler 选项
该项目使用以下编译器设置通过 CMake 配置:
target_compile_options(testing
PRIVATE
-mcpu=cortex-m7
-mfpu=fpv5-d16
-mfloat-abi=hard
-mthumb
-Wall
-fdata-sections
-ffunction-sections
)
导致错误的编译命令:
[build] /usr/bin/arm-none-eabi-gcc -DSTM32F777xx -DUSE_HAL_DRIVER -I<removed> -g -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -Wall -fdata-sections -ffunction-sections -std=gnu11 -o <removed>.c.obj -c <removed>.c
研究/我尝试过的
阅读后我意识到 armv7 有两个(指令集?语法解析器?),并且处理器可以处于这些(ARM 和 THUMB)的两种模式之一。但是我不是很明白这一点,以及它如何影响手写汇编的解析。
我怀疑是因为处理器是thumb模式(-mthumb),跟我的inline alias constraints有关系? Per documentation 我尝试在“+l”、“+r”、“+h”之间切换,但似乎没有任何改变。
我尝试使用硬编码寄存器“r3、r4、r5”而不是内联别名,但出现了同样的错误。
根据@jester 的帮助,我意识到我对锁的 GCC-inline 变量别名有错误的约束。它应该是“+m”,指定内存地址而不是寄存器。
我也是 de-referencing 锁的地址,而我本应将其作为指针保留。
我将 [lock] "+l"(*lock)
更改为 [lock] "+m"(lock)
,现在可以构建了。