[英]How to read a condition flag in ARMv7 Thumb-2 assembly?
我正在使用带有Thumb-2指令的ARMv7处理器。
我已经执行了ADD
, SUB
或CMP
。 现在我想将条件标志LE
移动到r2
。 在此之后, r2
应该包含0
或1
。
我一直在查看Thumb-2手册,但我没有找到条件MOV指令或读取标志的特殊指令。
最有效的方法是什么? 提前致谢!
您需要使用ite
(if-then-else)指令启动条件块,然后使用条件赋值:
ite le @ if-then-else (le)
movle r2, #1 @ if (le) then r2 = #1
movgt r2, #0 @ else r2 = #0
通常,如果在前面添加适当的IT指令,则可以在Thumb-2中使用任意条件指令。 阅读手册了解详情。
在ARM中,(几乎)可以预测任何指令。 在拇指模式下,这需要一个it
指令来编码下一个指令的否定或否定的谓词和模式。
但是在统一语法中,汇编程序可以为你做到这it
,我认为没有明确表示。
例如movle r0, #1
如果LE条件在flags中为真,则设置r0 = 1
,否则保持不变。 所以你首先需要一个mov r0, #0
。
ARM32没有像x86的setcc
那样的set-from-condition指令。
AArch64:将标志条件转换为整数只需要一个cset
指令。
这个C源:
int booleanize(int x, int y) { return x<y; }
int booleanize_u(unsigned a, unsigned b) { return a<b; }
使用clang -O3( 在Godbolt编译器浏览器上 )编译ARM32 thumb,揭示了一些愚蠢的错过优化。 gcc类似,制作没有-mcpu
分支代码,甚至比使用-mcpu=cortex-a53
更糟糕。 在简单的微控制器上,Branchy可能并非完全不合理。
@@ BAD EXAMPLE, compiler missed optimizations
@ clang7.0 -target arm -mthumb -mcpu=cortex-a53
booleanize(int, int):
movs r2, #0 @ movs is 16-bit, mov is a 32-bit instruction, I think.
cmp r0, r1
it lt
movlt r2, #1
mov r0, r2 @ wasted instruction because the compiler wanted to mov #0 before cmp
bx lr
booleanize_u(unsigned int, unsigned int):
movs r2, #0
cmp r0, r1
it lo
movlo r2, #1
mov r0, r2
bx lr
这肯定比来自@ fuz的回答的ite le
/ movle / movgt更糟糕,有2个谓词指令。
ARM模式代码或多或少都很好,其中每个32位指令字在编码中具有4位用于谓词条件。 (asm源中没有后缀的默认值是al
= always。)
@ gcc8.2 -O3 -mcpu=cortex-a53
booleanize(int, int):
cmp r0, r1
movge r0, #0 @ a simple mov without predication or flag-setting would work
movlt r0, #1
bx lr
booleanize_u(unsigned int, unsigned int):
cmp r0, r1
movcs r0, #0
movcc r0, #1
bx lr
cset
,booleanization。 @ clang and gcc make the same efficient code
booleanize(int, int):
cmp w0, w1
cset w0, lt @ signed less-than
ret
booleanize_u(unsigned int, unsigned int):
cmp w0, w1
cset w0, lo @ unsigned lower
ret
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.