32 位机器上的 __int64?

发布于 2024-08-30 05:55:06 字数 99 浏览 3 评论 0原文

我刚刚在我的 32 位机器上尝试了 MSVC 2010 中的一些东西,发现我可以在我的程序中使用 __int64 - 这确实有效!

这怎么可能?

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!

How is that possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

熊抱啵儿 2024-09-06 05:55:06

32 位算术在 16 位系统上的工作方式相同。

在这种情况下,它使用2个32位内存地址一起组成一个64位数字。加法/减法很容易,你可以按部分进行,唯一的问题是将较低的部分转移到较高的部分。对于乘法/除法来说,它更难(即更多指令)。

它显然很慢,比 32 位乘法算术慢很多,但如果您需要它,它就在那里。当您升级到 64 位处理器编译器时,它会自动优化为具有更大字长的一条指令。

在 32 位处理器上的 Visual Studio 2010 Professional 实现的 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

正如您所看到的,它比普通乘法慢很多。

Same way 32-bit arithmetic worked on 16-bit systems.

In this case, it uses 2 32-bit memory addresses to form a 64-bit number together. 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. And when you upgrade to a 64-bit processor compiler, it gets automatically optimized to one instruction with the bigger word size.

The Visual Studio 2010 Professional implementation of 64 bit multiplication on a 32-bit processor, compiled in release mode, is:

_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.

雪花飘飘的天空 2024-09-06 05:55:06

为什么你觉得奇怪呢?没有什么可以阻止编译器在 32 位机器上支持 64 位、128 位或更多位整数类型。如果愿意的话,编译器甚至可以支持 57 位和 91 位类型。实际上,在 N 位机器上支持 2N 位整数运算是一项相对容易的任务,因为典型机器的指令集通常是在设计时考虑到这种功能的。

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. The compiler can even support 57- and 91-bit types, if it feels like it. 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.

污味仙女 2024-09-06 05:55:06

32位只是机器字的原始大小,这意味着它们可以一次性处理,并不意味着更大的项目根本无法处理,它们只需要作为单独的32位单元分多次处理步骤,以同样的方式,它们可以小于机器字,在这种情况下,仅处理整个机器字的一部分。

32 bits are merely the native size of a machine word, meaning they can be processed in one go, it does not mean that larger items can't be processed at all, they just need to be processed as separate 32-bit units in multiple steps, in the same way they can be smaller than a machine word, in which case merely a portion of the full machine word will be processed.

甜宝宝 2024-09-06 05:55:06

它之所以有效,是因为 64 位整数数据类型是语言规范的一部分

该语言的编译器必须允许您使用 64 位整数(当然,并获得正确的结果)。

无论您的目标是 64 位、32 位、16 位还是 8 位机器(无论编译器允许什么),您的程序都必须能够运行(并且运行完全相同)。

编写编译器的人有义务使其做任何需要的事情,以使每种受支持的数据类型在每种目标处理器类型上工作。

支持潜在的“更高”数据类型已全部处理,因此您不必自己做。

如何?

显然,接受命令 16 位算术运算的代码并将其翻译成在 16 位(或更高)处理器上运行的机器代码对于编译器来说是“简单”的工作,几乎是直接翻译。 Z = X + Y 可能会转换为 mov a,(X);添加一个,(Y); mov (Z),a;.

相反,接受 64 位算术运算命令的代码并将其转换为在 32 位(或更低)处理器上运行的机器代码则更为复杂。编译器还有更多工作要做,一次对每个操作数的 32 位部分进行操作。还有更多方法可以完成它。

生成的机器代码可以内联使用多个指令(代码更大,执行速度更快)。 Z = X + Y 可能会转换为 mov a,(X); adc a,(Y);移动 (Z),a;移动a,进位; adc a,(X+1); adc a,(Y+1); mov (Z+1),a;.

生成的机器代码可以调用扩展算术子例程(代码更小,执行速度更慢)。 Z = X + Y 可能会转换为 mov a,X;调用 GET64;移动a,Y;拨打ADD64;移动a,Z;调用 STORE64;

It works because 64-bit integer data types are part of the language specification.

A compiler for the language MUST let you work with 64-bit integers (and get correct results, of course).

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).

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. Z = X + Y might translate to 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. The compiler has more work to do, operating on 32-bit pieces of each operand at a time. 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;.

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;.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文