为什么 if( !A && !B ) 不能优化为单个 TEST 指令?

Why can't if( !A && !B ) optimize to a single TEST instruction?

if( !A && !B ) 似乎应该编译成

mov    eax, dword ptr[esp + A_offset]
test   eax, dword ptr[esp + B_offset]
jne    ~~~~~~~~~~

编译器实际生成

mov    eax, dword ptr[esp + A_offset]
test   eax, eax
jne    ~~~~~~~~~~
mov    eax, dword ptr[esp + B_offset]
test   eax, eax
jne    ~~~~~~~~~~

在此处查看转储

8B 45 F8             mov         eax,dword ptr [b]  
83 7D FC 00          cmp         dword ptr [a],0  
75 04                jne         main+32h (0A71072h)  
85 C0                test        eax,eax  
75 00                jne         main+32h (0A71072h)   

为什么不使用单个 TEST 指令来保存分支和指令?

没有。 test 指令执行操作数的按位与并根据结果设置标志,参见 https://en.wikipedia.org/wiki/TEST_(x86_instruction).

所以编译器生成的代码是正确的。

因为 short-circuit evaluation.

if(!A && !B)

大家注意上面的代码

如果 A 为真(非 0), !A && !B 变为 0(FALSE)。 对,你不必检查 B 的值。 它应该跳过(跳转)if 语句的代码块。

mov eax, dword ptr[esp + A_offset]
test eax, eax   ; If `A & A`
jne ~~~~~~~~~~  ; is not 0(If A is not 0), skip this if-codeblock.
mov eax, dword ptr[esp + B_offset] ; Otherwise,
test eax, eax   ; If `B & B`
jne ~~~~~~~~~~  ; is not 0(If B is not 0), skip this if-codeblock.
......          ; Both A and B are 0, and `!A && !B` is `1(TRUE)`! Run the if-codeblock.

加上:

看来你的代码有误..?

mov eax, dword ptr[esp + A_offset]
mov ebx, dword ptr[esp + B_offset]
test eax, ebx  ; `A & B`
jne ~~~~~~~~~~ ; If `A & B != 0`, skip this code-block for the if statement.
...... ; In other words, this code-block will be run when `A & B == 0`,
       ; which will be `TRUE` when A is 1(0b00000001) and B is 2(0b00000010).