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指令来保存分支和指令?
答案 0 :(得分:2)
没有。 test
指令对操作数执行按位AND并根据结果设置标志,请参阅https://en.wikipedia.org/wiki/TEST_(x86_instruction)。
因此编译器生成的代码是正确的。
答案 1 :(得分:2)
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).