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

问题描述 投票:0回答:2

我试图理解这个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
c++ assembly x86 clang x86-64
2个回答
3
投票

在AT&T语法中,$是立即值的前缀(see also); $1是一个普通的1,所以你的指令根据al的最低位来设置标志。

是全部(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的别名,在这种情况下可能更清楚)。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.