tags:

views:

180

answers:

3

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?
+11  A: 

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.

Blindy
It won't get optimized unless you compile for x64, regardless of what processor you have.
Dan Berindei
Er, yea, that's what I meant. Long night..
Blindy
Would have been true in C# though!
Blindy
A: 

Imagine an environment where the largest data item was only as big as the machine word of the processor. Now, imagine how much more useful that environment would be if that restriction were lifted. That's how (and why) it's done.

KevinDTimm
I can imagine why a machine would be more useful with those limits lifted.. but how should I know why now according to your answer?
koa
+1  A: 

Why do you find it surprising? There's nothing to prevent the compiler to support 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.

AndreyT