为什么 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).
所以编译器生成的代码是正确的。
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).
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).
所以编译器生成的代码是正确的。
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).