sup*_*owl 0 c assembly flags arm
我试图在我的代码执行算术运算时使用CPSR标志,而不是使用一系列if语句来检查溢出,进位等,以便拥有更小,更快的代码.一个简单的例子是这个加法操作:
int16_t a = 0x5000;
int16_t b = 0x4000;
int16_t result = a+b;
uint32_t flags = getFlags();
Run Code Online (Sandbox Code Playgroud)
代码需要在各种平台上运行,因此getFlags()是允许包含特定于体系结构的程序集的代码的唯一部分.
inline uint32_t getFlags() {
uint32_t flags = 0;
asm (“mrs %0, cpsr”
: “=r” (flags)
:
: );
return flags;
}
Run Code Online (Sandbox Code Playgroud)
问题是编译器没有任何方式知道此示例中的加法操作应该设置标志,因此它生成类似于以下的指令:
ldrsh r3, [r0]
ldrsh r4, [r1]
add r3, r3, r4
strh r3, [r2]
mrs r3, cpsr
Run Code Online (Sandbox Code Playgroud)
为了使CPSR包含任何有用的东西,我需要编译器使用adds而不是add(s suffix = update CPSR).我可以在我的C代码或可能的编译器选项中更改它会导致它选择标志更新指令吗?我可以使用GCC或Clang.
这种代码无法以有用的方式工作,因为编译器可以随意重新排列代码.在mrs指令运行之前,甚至没有保证添加是最后一个标志更新指令.如果要实现此目的,请将标志设置添加和mrs指令放在一个asm语句中.