x86 NOT http://felixcloutier.com/x86/NOT.html是按位运算;它只是分别反转每个位,就像xor reg, -1
但不影响标志。
NOT
实施C's ~操作员 http://en.cppreference.com/w/c/language/operator_arithmetic,并且完全不同于!
(逻辑非 http://en.cppreference.com/w/c/language/operator_logical).
以下是 C 编译器如何实现这些运算符(用于 x86-64 System V 调用约定的 gcc8.1 和 clang6.0,在 Godbolt 编译器资源管理器上 https://gcc.godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(j:1,lang:c%2B%2B,source:'int+bitnot(int+a)+%7B+return+~a%3B+%7D%0D%0Aint+logical_not(int+a)+%7B+return+!!a%3B+%7D%0D%0Aint+booleanize(int+a)+%7B+return+!!!!a%3B+%7D%0D%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:37.18061674008811,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:g81,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',trim:'1'),lang:c%2B%2B,libs:!(),options:'-xc+-O3+-std%3Dgnu11+-Wall+-march%3Dskylake',source:1),l:'5',n:'0',o:'x86-64+gcc+8.1+(Editor+%231,+Compiler+%231)+C%2B%2B',t:'0')),k:32.64490422214522,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang600,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',trim:'1'),lang:c%2B%2B,libs:!(),options:'-xc+-O2+-std%3Dgnu11+-Wall+-march%3Dhaswell+-mno-avx512f+-mno-avx',source:1),l:'5',n:'0',o:'x86-64+clang+6.0.0+(Editor+%231,+Compiler+%232)+C%2B%2B',t:'0')),k:30.174479037766666,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)。两个编译器生成相同的代码,正确地选择现代 Intel/AMD CPU 的最有效的实现。
int bitnot(int a) { return ~a; }
mov eax, edi
not eax
ret
int logical_not(int a) { return !a; }
xor eax, eax
test edi, edi
sete al
ret
int booleanize(int a) { return !!a; }
xor eax, eax
test edi, edi
setne al
ret