当我的代码执行算术运算时,我尝试使用CPSR标志,而不是使用一系列的if语句来检查溢出,进位等,以使代码更小,更快。一个简单的例子是该加法运算:
int16_t a = 0x5000;
int16_t b = 0x4000;
int16_t result = a+b;
uint32_t flags = getFlags();
该代码将需要在各种平台上运行,因此getFlags()是该代码中唯一可以包含特定于体系结构的程序集的部分。
inline uint32_t getFlags() {
uint32_t flags = 0;
asm (“mrs %0, cpsr”
: “=r” (flags)
:
: );
return flags;
}
问题在于,编译器没有任何方法知道此示例中的加法操作应设置标志,因此它生成的指令类似于:
ldrsh r3, [r0]
ldrsh r4, [r1]
add r3, r3, r4
strh r3, [r2]
mrs r3, cpsr
为了使CPSR包含有用的内容,我需要编译器使用添加而不是添加(后缀=更新CPSR)。我可以在C代码或编译器选项中进行某些更改,以使其选择标志更新指令吗?我可以使用GCC或Clang。
答案 0 :(得分:5)
这种代码无法以有用的方式工作,因为编译器可以随意重新排列代码。甚至不能保证加法是mrs
指令运行前的最后一个标志更新指令。如果您想解决这个问题,请将标记设置附加项和mrs
指令放在一个asm
语句中。
答案 1 :(得分:4)