Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lightweight method to use Amd64 instructions under 32-bit Windows?

For some CPU-bound code using 64-bit variables, it is beneficial to use the Amd64 instruction set rather than x86. How can it be done under 32-bit Windows (e.g. Windows XP SP3)? Of course I assume a modern, Amd64-enabled CPU. I'm excluding the working but heavyweight method: running a full-blown 64-bit OS as a virtual machine, e.g. Ubuntu for Amd64 under Virtualbox.

I understand some assembly is needed, and there will restrictions, in particular addressing more memory than 32-bit Windows manages. But I'm thinking of purely computational tasks needing only a moderate amount of memory and no call to external functions.

like image 331
fgrieu Avatar asked Aug 20 '11 16:08

fgrieu


2 Answers

There is no way to use Amd64 instructions (Long mode) in 32-bit general-purpose OS (without kernel modification/special drivers/hypervisor).

This is because:

1) to use native 64-bit instructions you need to switch into long mode. This is privileged action. 32-bit OS kernel can't continue to work if the CPU is switched into 64-bit mode, so you should switch back before entering a kernel

2) But kernel are often called asynchronously, for timer (scheduler) and other hardware interrupts (drivers). It will not save 64-bit registers nor change mode from long into protected.

May be it is possible to write special driver, which will do the 64-bit tasks on 32-bit OS, but such driver is more like 64-bit kernel and dynamic patcher of kernel. I know no one such solution.

You can only use MMX, SSE, SSE2, SSE3, AVX for accessing 64-bit ALU and registers of your CPU when running in 32-bit OS.

I can say, that Linux, some BSD, Mac OS X have a mode, when 64-bit kernel is used, but user-space software is 32-bit. In such case it will be possible to run both 32-bit and 64-bit applications, because kernel knows about 64-bit mode and can access 64-bit registers to do a task switch. As far as I know, MS Windows have not such mode itself (the W7 emulates 32bit mode, but this is called my MS as simulator so I assume it is not an in-kernel feature).

Other possibility (this is better, is your CPU has support of hardware virtualization), is to use 64-bit hypervisor (VMware/Xen, other overpriced solutions) with 32-bit and 64-bit guest OSes. VirtualBox is other option of using hypervisor, and it is free to use.

like image 145
osgx Avatar answered Dec 13 '22 09:12

osgx


In general, running 64-bit code in a 32-bit OS kernel is going to be next to impossible, for the following reasons:

  • The 32-bit OS is unaware of the additional 64-bit registers (and upper 32-bits of the existing registers) and will not save them across task switches
  • The 32-bit OS is not prepared to enable 64-bit code execution. Enabling 64-bit code execution means switching to IA-32e paging (which requires an entirely different page table format) and setting CS.L = 1 and CS.D = 0 in the code segment descriptor in the GDT (or LDT). (See the IA-32 manuals, vol 3a/3b 5.2.1)

In principle, you may be able to workaround both problems by writing a new HAL for Windows, which operates in IA-32e mode, and switches to a 64-bit trampoline code segment to save and restore 64-bit registers. This is a rather complex task; take a look at the Windows DDK for details. You could also use an emulation approach, as VirtualBox and friends do, if your CPU supports VMX. But it would be much simpler to simply use a 64-bit OS from the start.

like image 38
bdonlan Avatar answered Dec 13 '22 08:12

bdonlan