我使用 clang 编译了以下代码:
#include <stdint.h>
int f(int32_t a, int32_t b) {
int32_t result;
if (a < 10) {
result = a + b;
} else {
result = a * b;
}
return result;
}
int main() {;
int res = f(5, 9);
if (res > 5) {
return res;
}
return 0;
}
现在为if (a < 10)
生成的程序集如下:
subs w8, w8, #10
cset w8, ge
tbnz w8, #0, .LBB0_2
...
.LBB0_1:
...
add w8, w8, w9
...
.LBB0_2:
...
mul w8, w8, w9
我们可以看到,当w8 = 0
时,分支将前往加法块。当
w8
指令不满足条件
0
时,
ge
设置为
cset
。当标志
ge
(负数)和
N
(溢出)相等时,满足
V
条件。两个标志均由最后一个标志设置指令(即
subs
指令)设置。现在我不明白这个编译后的程序集输出是为什么要在
ge
指令中使用
cset
条件而不使用类似
pl
条件之类的东西。为什么我们需要额外检查 is
w8
是否小于最小有符号 32 int,它如何转换为我们提供的原始高级编译代码?
-O3
)。