简体   繁体   English

__int64 在 32 位机器上?

[英]__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.

相关问题 32位代码在64位Linux计算机上运行 - 32-bit code runs on 64-bit linux machine 将不同的32bit-cast转换为long / __ int64,为什么? - Different 32bit-cast into long/__int64, why? 在64位计算机上编译32位代码时,应如何处理“从'void *'到'int'的转换会失去精度”? - How should I handle “cast from ‘void*’ to ‘int’ loses precision” when compiling 32-bit code on 64-bit machine? 与 32 位和 64 位平台的 int64_t 匹配的整数文字? - Integer literal that matches int64_t for both 32-bit and 64-bit platforms? 将有符号 32 位整数与无符号 64 位整数相加 - Sum signed 32-bit int with unsigned 64bit int 如何在一个 64 位整数中存储和使用两个 32 位带符号整数? - How to store and use two 32-bit signed int in one 64-bit int? 64位和32位整数 - 64-bit and 32-bit integers 在64位linux armv8机器上编译32位二进制文​​件时遇到问题 - Having trouble compiling 32-bit binary on 64-bit linux armv8 machine 从源代码在64位计算机上构建32位mysql c ++连接器 - Building 32-bit mysql c++ connector from source on a 64-bit machine 在64位计算机上编写32位软件时要注意什么? - What to watch out for when writing 32-bit software on 64-bit machine?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM