[英]__int64 on a 32-Bit machine?
I just tried something in MSVC 2010 on my 32-bit machine here and found out that I can use __int64
in my programs - which actually work!我刚刚在我的 32 位机器上尝试了 MSVC 2010 中的一些东西,发现我可以在我的程序中使用__int64
- 这确实有效!
How is that possible?这怎么可能?
Same way 32-bit arithmetic worked on 16-bit systems. 32 位算法在 16 位系统上的工作方式相同。
In this case, it uses 2 32-bit memory addresses to form a 64-bit number together.在这种情况下,它使用 2 个 32 位内存地址一起组成一个 64 位数字。 Addition/substraction is easy, you do it by parts, the only gotcha is taking the carry-over from the lower part to the higher part.加法/减法很容易,您可以按部分进行,唯一的问题是将结转从较低的部分转移到较高的部分。 For multiplication/division, it's harder (ie more instructions).对于乘法/除法,它更难(即更多指令)。
It's obviously slow, quite a bit slower than 32 bit arithmetic for multiplication, but if you need it, it's there for you.它显然很慢,比乘法的 32 位算术慢很多,但如果你需要它,它就在你身边。 And when you upgrade to a 64-bit
processor
compiler, it gets automatically optimized to one instruction with the bigger word size.当您升级到 64 位
处理器
编译器时,它会自动优化为具有更大字长的一条指令。
The Visual Studio 2010 Professional implementation of 64 bit multiplication on a 32-bit processor, compiled in release mode, is: 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
As you can see, it's a LOT slower than normal multiplication.如您所见,它比普通乘法慢很多。
Why do you find it surprising?为什么你觉得很意外? There's nothing to prevent the compiler from supporting 64-, 128- or more-bit integer types on a 32-bit machine.没有什么可以阻止编译器在 32 位机器上支持 64 位、128 位或更多位整数类型。 The compiler can even support 57- and 91-bit types, if it feels like it.如果愿意,编译器甚至可以支持 57 位和 91 位类型。 In practice supporting 2N-bit integer arithmetic on an N-bit machine is a relatively easy task, since the instruction set of a typical machine is often designed with this kind of functionality in mind.实际上,在 N 位机器上支持 2N 位整数算术是一项相对容易的任务,因为典型机器的指令集在设计时通常考虑到这种功能。
32位只是一个机器字的本机大小,意味着它们可以一次处理,并不意味着更大的项目根本不能处理,它们只需要作为单独的32位单元多次处理步,以同样的方式,它们可以小于一个机器字,在这种情况下,只会处理整个机器字的一部分。
It works because 64-bit integer data types are part of the language specification .它起作用是因为 64 位整数数据类型是语言规范的一部分。
A compiler for the language MUST let you work with 64-bit integers (and get correct results, of course).该语言的编译器必须让您处理 64 位整数(当然,并获得正确的结果)。
Your program must work (and work exactly the same), whether you target a 64-bit, 32-bit, 16-bit, or 8-bit machine (whatever the compiler allows).无论您的目标是 64 位、32 位、16 位还是 8 位机器(无论编译器允许什么),您的程序都必须可以运行(并且完全相同)。
Whoever wrote the compiler was obliged to make it do whatever is needed to make every supported data type work on every targeted processor type.编写编译器的人有义务让它做任何需要的事情,使每个受支持的数据类型在每个目标处理器类型上工作。
Supporting potentially "higher" data types has all been taken care of , so that you don't have to do it yourself.支持潜在的“更高”数据类型已全部处理完毕,因此您不必自己动手。
How?如何?
Obviously, accepting code that commands 16-bit arithmetic operations and translating it into machine code that runs on a 16-bit (or higher) processor is "easy" work for a compiler, almost a direct translation.显然,接受命令 16 位算术运算的代码并将其转换为在 16 位(或更高)处理器上运行的机器代码对于编译器来说是“容易”的工作,几乎是直接转换。 Z = X + Y
might translate to mov a,(X); add a,(Y); mov (Z),a;
Z = X + Y
可能转化为mov a,(X); add a,(Y); mov (Z),a;
mov a,(X); add a,(Y); mov (Z),a;
. .
Conversely, accepting code that commands 64-bit arithmetic operations and translating it into machine code that runs on a 32-bit (or lower) processor is more complex.相反,接受命令 64 位算术运算的代码并将其转换为在 32 位(或更低)处理器上运行的机器代码则更为复杂。 The compiler has more work to do, operating on 32-bit pieces of each operand at a time.编译器有更多的工作要做,一次对每个操作数的 32 位部分进行操作。 There are more ways to do get it done.有更多方法可以完成它。
The resulting machine code could use multiple instructions inline (bigger code, faster execution).生成的机器代码可以使用多条内联指令(更大的代码,更快的执行)。 Z = X + Y
might translate to 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); 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;
. .
The resulting machine code could call extended arithmetic subroutines (smaller code, slower execution).生成的机器代码可以调用扩展的算术子程序(代码更小,执行速度更慢)。 Z = X + Y
might translate to mov a,X; call GET64; mov a,Y; call ADD64; mov a,Z; call STORE64;
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.