[英]__int64 on a 32-Bit machine?
我刚刚在我的 32 位机器上尝试了 MSVC 2010 中的一些东西,发现我可以在我的程序中使用__int64
- 这确实有效!
这怎么可能?
32 位算法在 16 位系统上的工作方式相同。
在这种情况下,它使用 2 个 32 位内存地址一起组成一个 64 位数字。 加法/减法很容易,您可以按部分进行,唯一的问题是将结转从较低的部分转移到较高的部分。 对于乘法/除法,它更难(即更多指令)。
它显然很慢,比乘法的 32 位算术慢很多,但如果你需要它,它就在你身边。 当您升级到 64 位
处理器
编译器时,它会自动优化为具有更大字长的一条指令。
Visual Studio 2010 Professional 在 32 位处理器上的 64 位乘法实现,在发布模式下编译,是:
_allmul PROC NEAR
A EQU [esp + 4] ; stack address of a
B EQU [esp + 12] ; stack address of b
mov eax,HIWORD(A)
mov ecx,HIWORD(B)
or ecx,eax ;test for both hiwords zero.
mov ecx,LOWORD(B)
jnz short hard ;both are zero, just mult ALO and BLO
mov eax,LOWORD(A)
mul ecx
ret 16 ; callee restores the stack
hard:
push ebx
A2 EQU [esp + 8] ; stack address of a
B2 EQU [esp + 16] ; stack address of b
mul ecx ;eax has AHI, ecx has BLO, so AHI * BLO
mov ebx,eax ;save result
mov eax,LOWORD(A2)
mul dword ptr HIWORD(B2) ;ALO * BHI
add ebx,eax ;ebx = ((ALO * BHI) + (AHI * BLO))
mov eax,LOWORD(A2) ;ecx = BLO
mul ecx ;so edx:eax = ALO*BLO
add edx,ebx ;now edx has all the LO*HI stuff
pop ebx
ret 16 ; callee restores the stack
如您所见,它比普通乘法慢很多。
为什么你觉得很意外? 没有什么可以阻止编译器在 32 位机器上支持 64 位、128 位或更多位整数类型。 如果愿意,编译器甚至可以支持 57 位和 91 位类型。 实际上,在 N 位机器上支持 2N 位整数算术是一项相对容易的任务,因为典型机器的指令集在设计时通常考虑到这种功能。
32位只是一个机器字的本机大小,意味着它们可以一次处理,并不意味着更大的项目根本不能处理,它们只需要作为单独的32位单元多次处理步,以同样的方式,它们可以小于一个机器字,在这种情况下,只会处理整个机器字的一部分。
它起作用是因为 64 位整数数据类型是语言规范的一部分。
该语言的编译器必须让您处理 64 位整数(当然,并获得正确的结果)。
无论您的目标是 64 位、32 位、16 位还是 8 位机器(无论编译器允许什么),您的程序都必须可以运行(并且完全相同)。
编写编译器的人有义务让它做任何需要的事情,使每个受支持的数据类型在每个目标处理器类型上工作。
支持潜在的“更高”数据类型已全部处理完毕,因此您不必自己动手。
如何?
显然,接受命令 16 位算术运算的代码并将其转换为在 16 位(或更高)处理器上运行的机器代码对于编译器来说是“容易”的工作,几乎是直接转换。 Z = X + Y
可能转化为mov a,(X); add a,(Y); mov (Z),a;
mov a,(X); add a,(Y); mov (Z),a;
.
相反,接受命令 64 位算术运算的代码并将其转换为在 32 位(或更低)处理器上运行的机器代码则更为复杂。 编译器有更多的工作要做,一次对每个操作数的 32 位部分进行操作。 有更多方法可以完成它。
生成的机器代码可以使用多条内联指令(更大的代码,更快的执行)。 Z = X + Y
可能转化为mov a,(X); adc a,(Y); mov (Z),a; mov a,CARRY; adc a,(X+1); adc a,(Y+1); mov (Z+1),a;
mov a,(X); adc a,(Y); mov (Z),a; mov a,CARRY; adc a,(X+1); adc a,(Y+1); mov (Z+1),a;
.
生成的机器代码可以调用扩展的算术子程序(代码更小,执行速度更慢)。 Z = X + Y
可能会转化为mov a,X; call GET64; mov a,Y; call ADD64; mov a,Z; call STORE64;
mov a,X; call GET64; mov a,Y; call ADD64; mov a,Z; call STORE64;
.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.