Reputation: 38214
I'm trying to understand what this testb instruction (x86-64) will do.
testb $1, %al
What is the value of $1 here. is it all ones (0xFF
) or a single 1 (0x1
)?
The assembly is produced by clang for the following program:
#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();
}
}
The relevant assembly with (clang++ -s test.cpp -O3) is the following:
Lcfi2:
.cfi_def_cfa_register %rbp
movb _flag_atomic(%rip), %al
testb $1, %al ; <<<<------------
jne LBB0_2
Upvotes: 0
Views: 1347
Reputation: 126867
In AT&T syntax $
is the prefix for immediate values (see also); $1
is a plain 1, so your instruction sets the flags according to the least significant bit of al
.
is it all ones (0xFF) or a single 1 (0x1)?
All ones would be
testb $-1, %al
or (exact same machine code, just disassembly preference)
testb $0xff, %al
which incidentally would have the exact same semantic as
testb %al, %al
(as a mask of 0xff
over an 8 bit register doesn't mask anything), and in this case is also valid for your code, as for a boolean there should be no need to mask anything out to check if it's true (and indeed gcc prefers this last version for your code).
movb _flag_atomic(%rip), %al
testb $1, %al
jne LBB0_2
in Intel syntax (no prefixes, no suffixes, dest, source
operands order, explicit memory addressing syntax) this is
mov al, [rip+_flag_atomic]
test al, 1
jne LBB0_2
And, in pseudo-C:
%al = _flag_atomic;
if(%al & 1 != 0) goto LBB0_2;
(jne
is an alias of jnz
, which is probably more clear in this case).
Upvotes: 3
Reputation: 353
0x
is prefixed with hexadecimal number. 0
is prefixed with Octal number and if you do not mentioned any prefix it would be decimal number system. In your case this is 1 in decimal number system.
Upvotes: 0