我刚刚在我的32位机器上尝试了MSVC 2010中的一些东西,发现我可以在我的程序中使用__int64 - 这实际上有用!
答案 0 :(得分:35)
同样,32位算法适用于16位系统。
在这种情况下,它使用2个32位内存地址一起形成64位数字。加法/减法很容易,你可以按部分进行,唯一的问题就是从下部到较高部分进行结转。对于乘法/除法,它更难(即更多指令)。
它显然很慢,比乘法的32位算术慢一点,但是如果你需要它,它就在那里。当您升级到64位处理器编译器时,它会自动优化为一个具有更大字长的指令。
在发布模式下编译的32位处理器上的64位乘法的Visual Studio 2010 Professional实现是:
_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
正如您所看到的,它比正常乘法慢很多。
答案 1 :(得分:5)
为什么你觉得这很令人惊讶?没有什么可以阻止编译器在32位机器上支持64位,128位或更多位的整数类型。如果感觉像编译器,编译器甚至可以支持57位和91位类型。实际上,在N位机器上支持2N位整数运算是一项相对容易的任务,因为典型机器的指令集通常在设计时考虑到这种功能。
答案 2 :(得分:3)
32位只是机器字的原始大小,这意味着它们可以一次处理,但这并不意味着根本不能处理更大的项目,它们只需要作为单独的32位处理多个步骤中的单位,就像它们可以小于机器字一样,在这种情况下,只处理整个机器字的一部分。
答案 3 :(得分:0)
它有效,因为64位整数数据类型是语言规范的一部分。
语言的编译器必须让你使用64位整数(当然,得到正确的结果)。
您的程序必须正常工作(并且工作完全相同),无论您是针对64位,32位,16位还是8位计算机(无论编译器允许)。
编写编译器的人必须使无论需要使每个支持的数据类型都在每个目标处理器类型上工作。
可能支持"更高"数据类型已经全部用完,因此您不必自己动手。
如何?
显然,接受命令执行16位算术运算并将其转换为在16位(或更高)处理器上运行的机器代码是简单的"为编译器工作,几乎是直接翻译。 Z = X + Y
可能会转换为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;
。
生成的机器代码可以调用扩展的算术子程序(代码更小,执行速度更慢)。 Z = X + Y
可能会转换为mov a,X; call GET64; mov a,Y; call ADD64; mov a,Z; call STORE64;
。