gpt4 book ai didi

c++ - _InterlockedCompareExchange 文档中 "The sign is ignored"的含义

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:07:25 27 4
gpt4 key购买 nike

_InterlockedCompareExchange 的文档对每个参数说

The sign is ignored.

这是否意味着像 0xffff0x7fff(对于 16 位版本)这样的数字将被 _InterlockedCompareExchange16 等视为相等其他宽度内在函数?或者这是否意味着内在函数接受有符号和无符号整数?还是别的?

如果这不是文档中的错误,它至少看起来是模棱两可的。

最佳答案

符号位不会被忽略,就像其他位一样进行比较。

..CompareExchange.. 函数只关心位的相等性,不以任何特殊方式解释它们。在基于 x86 的系统上,它们使用 CMPXCHG 实现/CMPXCHG8B 指令,它将 CPU 寄存器与内存位置进行比较。符号问题变成了关于类型和参数传递的问题,而不是比较本身。

因为大多数互锁函数也作为 Windows API 函数存在,我们可以先看一下它们。 basic version采用 LONG 类型的 32 位参数。较小的有符号类型将被符号扩展为 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

然后打印:

Number: 65535 0x0000ffff (64 bit)
Number: -42 0xffffffd6 (64 bit)
Number: -42 0xffffffd6 (64 bit)

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 位 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

我们可以看到生成的代码使用MOVSX 对16 位数字进行符号扩展。这是 Windows ABI 所要求的。

当您使用 #pragma intrinsic(_InterlockedCompareExchange) 时,事情就不太清楚了。我无法在文档中找到有关内部函数 ABI 的明确声明,但我们可以假设它在符号扩展方面遵循 Windows ABI。编译器将直接生成 LOCK CMPXCHG 指令,无需函数调用,但在需要时会使用 MOVSX

关于c++ - _InterlockedCompareExchange 文档中 "The sign is ignored"的含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46073591/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com