我正在试图理解这个testb指令(x86-64)会做什么。
testb $1, %al
这里$ 1的价值是多少?是全部(0xFF
)还是单个1(0x1
)?
该程序集由clang生成,用于以下程序:
#include <atomic>
std::atomic<bool> flag_atomic{false};
extern void f1();
extern void f2();
void foo() {
bool b = flag_atomic.load(std::memory_order_relaxed);
if (b == false) {
f1();
} else {
f2();
}
}
与(clang ++ -s test.cpp -O3)相关的程序集如下:
Lcfi2:
.cfi_def_cfa_register %rbp
movb _flag_atomic(%rip), %al
testb $1, %al ; <<<<------------
jne LBB0_2
答案 0 :(得分:3)
在AT&amp; T语法$
中是立即值的前缀(see also); $1
是普通的1,因此您的指令根据al
的最低有效位设置标志。
是全1(0xFF)还是单1(0x1)?
所有人都是
testb $-1, %al
或(完全相同的机器代码,只是反汇编偏好)
testb $0xff, %al
顺便说一下,它的语义与
完全相同testb %al, %al
(作为8位寄存器上0xff
的掩码并不掩盖任何东西),在这种情况下对你的代码也有效,对于布尔值,不需要掩盖任何东西检查它是否正确(事实上,gcc更喜欢这个代码的最后一个版本)。
movb _flag_atomic(%rip), %al
testb $1, %al
jne LBB0_2
在Intel语法中(没有前缀,没有后缀,dest, source
操作数顺序,显式内存寻址语法)这是
mov al, [rip+_flag_atomic]
test al, 1
jne LBB0_2
并且,在伪C:
%al = _flag_atomic;
if(%al & 1 != 0) goto LBB0_2;
(jne
是jnz
的别名,在这种情况下可能更清楚。)
答案 1 :(得分:0)
0x
以十六进制数为前缀。 0
以八进制数为前缀,如果您没有提到任何前缀,则它将是十进制数字系统。在你的情况下,这是十进制数字系统中的1。