testb $ 1,%al的语义是什么

时间:2018-05-02 12:49:21

标签: c++ assembly x86 clang x86-64

我正在试图理解这个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

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;

jnejnz的别名,在这种情况下可能更清楚。)

答案 1 :(得分:0)

0x以十六进制数为前缀。 0以八进制数为前缀,如果您没有提到任何前缀,则它将是十进制数字系统。在你的情况下,这是十进制数字系统中的1。