[英]Meaning of “The sign is ignored” in _InterlockedCompareExchange documentation
The documentation for _InterlockedCompareExchange
says for every parameter _InterlockedCompareExchange
的文档说明了每个参数
The sign is ignored.
该标志被忽略。
So does it mean that numbers like 0xffff
and 0x7fff
(for 16-bit version) will be considered equal by _InterlockedCompareExchange16
etc. by other width intrinsics? 那么它是否意味着像其他宽度内在函数的
_InterlockedCompareExchange16
等对像0xffff
和0x7fff
(对于16位版本)这样的数字会被认为是相等的? Or does this mean that the intrinsics accept both signed and unsigned integers? 或者这是否意味着内在函数接受有符号和无符号整数? Or something else?
或者是其他东西?
If it's not a bug in the documentation, it seems at least ambiguous. 如果它不是文档中的错误,那么它似乎至少是模棱两可的。
The sign bit is not ignored, it is compared just like the other bits. 符号位不被忽略,它与其他位进行比较。
The ..CompareExchange..
functions only care about the equality of the bits and does not interpret them in any special way. ..CompareExchange..
函数只关心位的相等性,并不以任何特殊方式解释它们。 On x86 based systems they are implemented with the CMPXCHG
/ CMPXCHG8B
instruction and it compares a CPU register against a memory location. 在基于x86的系统上,它们使用
CMPXCHG
/ CMPXCHG8B
指令实现,并将CPU寄存器与存储器位置进行比较。 The sign issue becomes a question about types and parameter passing, not the comparison itself. 符号问题成为关于类型和参数传递的问题,而不是比较本身。
Because most of the interlocked functions also exist as Windows API functions we can take a look at those first. 因为大多数互锁函数也作为Windows API函数存在,所以我们可以先看看它们。 The basic version takes 32-bit parameters with a
LONG
type. 基本版本采用
LONG
类型的32位参数。 Smaller signed types will be sign extended to 32-bits: 较小的签名类型将符号扩展为32位:
__declspec(noinline) void WINAPI Number(LONG val)
{
printf("Number: %5d %#.8x (%d bit)\n", val, val, sizeof(void*) * 8);
}
__declspec(noinline) INT16 WINAPI GetI16(INT16 num)
{
return num;
}
...
Number(0xffff); // Not sign extended
const INT16 numi16 = -42;
Number(numi16); // Optimized to 32-bit parameter by the compiler
Number(GetI16(-42)); // Use a helper function to prevent compiler tricks
and this prints: 这打印:
Number: 65535 0x0000ffff (64 bit)
Number: -42 0xffffffd6 (64 bit)
Number: -42 0xffffffd6 (64 bit)
32-bit x86: 32位x86:
; 1040 : Number(0xffff);
00022 68 ff ff 00 00 push 65535 ; 0000ffffH
00027 e8 00 00 00 00 call ?Number@@YGXJ@Z ; Number
; 1041 : const INT16 numi16 = -42;
; 1042 : Number(numi16);
0002c 6a d6 push -42 ; ffffffd6H
0002e e8 00 00 00 00 call ?Number@@YGXJ@Z ; Number
; 1047 : Number(GetI16(-42));
00033 6a d6 push -42 ; ffffffd6H
00035 e8 00 00 00 00 call ?GetI16@@YGFF@Z ; GetI16
0003a 0f bf c0 movsx eax, ax
0003d 50 push eax
0003e e8 00 00 00 00 call ?Number@@YGXJ@Z ; Number
64-bit x86_64/AMD64: 64位x86_64 / AMD64:
; 1040 : Number(0xffff);
00027 b9 ff ff 00 00 mov ecx, 65535 ; 0000ffffH
0002c e8 00 00 00 00 call ?Number@@YAXJ@Z ; Number
; 1041 : const INT16 numi16 = -42;
; 1042 : Number(numi16);
00031 b9 d6 ff ff ff mov ecx, -42 ; ffffffffffffffd6H
00036 e8 00 00 00 00 call ?Number@@YAXJ@Z ; Number
; 1047 : Number(GetI16(-42));
0003b 66 b9 d6 ff mov cx, -42 ; ffffffffffffffd6H
0003f e8 00 00 00 00 call ?GetI16@@YAFF@Z ; GetI16
00044 0f bf c8 movsx ecx, ax
00047 e8 00 00 00 00 call ?Number@@YAXJ@Z ; Number
We can see that the generated code uses MOVSX
to sign extend the 16-bit number. 我们可以看到生成的代码使用
MOVSX
来签名扩展16位数。 This is required by the Windows ABI. 这是Windows ABI所要求的。
When you use #pragma intrinsic(_InterlockedCompareExchange)
things are a little less clear. 当你使用
#pragma intrinsic(_InterlockedCompareExchange)
事情就不那么清楚了。 I could not find a definitive statement in the documentation regarding the ABI of intrinsic functions but we can assume it follows the Windows ABI when it comes to sign extension. 我在文档中找不到关于内在函数的ABI的明确声明,但我们可以假设它在符号扩展时遵循Windows ABI。 The compiler will generate a
LOCK CMPXCHG
instruction directly without a function call but it will use MOVSX
when required. 编译器将在没有函数调用的情况下直接生成
LOCK CMPXCHG
指令,但在需要时将使用MOVSX
。
the _InterlockedCompareExchange
this is compiler intrinsic implemented as CMPXCHG
instruction. _InterlockedCompareExchange
这是编译器内部实现为CMPXCHG
指令。 the The sign is ignored
mean that when we compare 2 integers for equal only - no different how we interpret high bit - as sign bit or no. The sign is ignored
意味着当我们比较2个整数只相等 - 没有不同我们如何解释高位 - 作为符号位或否。 this affected only compare for >
or <
but not for =
. 这只影响了比较
>
或<
但不是=
。 and 0xffff
of course not equal to 0x7fff
而
0xffff
当然不等于0x7fff
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.