News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Using 64-bit code in 32-bit OS?

Started by jj2007, January 01, 2012, 10:20:52 PM

Previous topic - Next topic

jj2007

I have tried to find traces of attempts to run, using 32-bit Windows, 64-bit code with a 64-bit CPU, but found almost nothing, except this one: http://vxheavens.com/lib/vrg02.html

Japheth's 32/64 example does something else

Running 32-bit code from a 16-bit environment is as easy as movzx eax, word ptr [bx]. So I wonder whether that could be possible as a 32-bit OS/64-bit code combo... any thoughts about that?

Imagine you could write an algo that runs on Win32 but uses, temporarily, the whole range of 64-bit registers ::)

Don't ask me to simply test it - for the time being I am stuck with a 32-bit CPU :bg

BogdanOntanu

Nope, it is not possible anymore. In 32 bits protected mode you can NOT access the extra registers and can not access the extra features of the 64 bits CPU.

Hence you MUST run an 64 bits OS in order to take advantage of an 64 bits CPU.

However you can run 32 bits code inside an 64 bits OS (compatibility mode of the CPU in long mode allows this). 32bits code run inside an 64 bits OS should not run slower (theoretically) than in 32 bits mode. It could even run faster because in long mode an 32 bits program can have more memory available for itself.

If you run your own OS or in an more forgiving OS like DOS for example you could eventually do this:
1) switch the CPU temporarily to long mode (64bits mode)
2) perform a few calculations in 64 bits mode
3) fast return in 32 bits mode to show your results

However this makes no sense in the long run because you will block interrupts and drivers (they are different in 64 bits mode) and because of this block you will not be able to stay long in 64 bits mode
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

jj2007

Quote from: BogdanOntanu on January 01, 2012, 10:24:24 PM
Nope, it is not possible anymore. In 32 bits protected mode you can NOT access the extra registers and can not access the extra features of the CPU (mainly PAE extensions).

You are the expert, Bogdan. But imagine you would not touch memory, only registers, in order to keep out of the paging etc business. Where and how does the CPU receive the precious message "from now on act as a 64-bit CPU"? Is it an interrupt, or an opcode?

Just curious.

dedndave

i would think the 32-bit OS would crash if you tried that

BogdanOntanu

Quote from: jj2007 on January 01, 2012, 10:29:20 PM
Quote from: BogdanOntanu on January 01, 2012, 10:24:24 PM
Nope, it is not possible anymore. In 32 bits protected mode you can NOT access the extra registers and can not access the extra features of the CPU (mainly PAE extensions).

You are the expert, Bogdan. But imagine you would not touch memory, only registers, in order to keep out of the paging etc business. Where and how does the CPU receive the precious message "from now on act as a 64-bit CPU"? Is it an interrupt, or an opcode?

Just curious.

It is an series of operations that must be performed in order to switch the CPU in 64 bits mode. Until you do this the CPI does NOT recognize any kind of 64 bits stuff. (unlike in 16 bits mode where with some prefix you can access 32 bits registers in 16 bits mode).

IF you try to access the 64 bits registers (with REX prefix) then the CPU will interpret them as normal 32 bits instructions and not as references to R12, R13 etc.

Form my 64 bits version of SOLAR OS you must perform the flowing sequence of operations in order to go to 64 bits mode:

0) disable paging if it is enabled (it is in most modern 32 bits OS including windows)
1) create 64 bits page tables (PML4, etc see Intel manuals for details)
2) enable PAE

; enable PAE: CR4.PAE = 1
mov eax,cr4
or eax,<1 shl 5>
mov cr4,eax


3) enable long mode:

; enable long mode: IA32_EFER.LME = 1
mov ecx,0C000_0080h
rdmsr
or eax,<1 shl 8>
wrmsr


4) enable paging and by this the CPU is in 64 bits mode

; enable paging: CR0.PG = 1
mov eax,cr0
or eax,<1 shl 31>
mov cr0,eax


5) load a new GDT containing an 64 bits code selector

; load a new 64 bits GDT
lgdt [gdt_48_64]


6) jump to the new selector

      ; note: 18h is SOL_OS 64 bit code selector
jmp far 18h,_here


ONLY Now you can write 64 bits code that make use of 64 bits registers like R12,...etc


.USE64
_here:
mov r12,0AABBCCDD_11223344h
...



Note:
a) the code examples are written in SOL ASM syntax but this is relatively similar to MASM syntax
b) I have left out the page tables and GDT setup code

Most of those required operations are not allowed by Windows and/or Linux in user mode.

Hence you can not do it.

Another cool idea would be to write a driver to allow this BUT you will have to touch the memory because you must write the new 64 bits page tables somewhere ;)



Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

jj2007

Thanks, Bogdan. In the meantime, I found Entering the 64-bit Submode, but your explanation is much clearer.

Basically, it seems not completely impossible, at driver level. For some time, there will be plenty of people who run a 32-bit OS on a 64-bit CPU, so the question is not merely academic; however, I doubt that it has the potential to become a standard practice to use rax in a 32-bit OS :bg

By the way: Would steps 4ff be required if
- interrupts were disabled
- the 64-bit code was simply copied from a 64-bit exe file over a range of nops in the 32-bit code section?
So the CPU would be told right in the middle of some 32-bit code, via wrmsr, "the next bytes are to be interpreted as 64-bit instructions" ?

BogdanOntanu

Quote from: jj2007 on January 01, 2012, 11:01:12 PM
...
By the way: Would steps 4ff be required if
- interrupts were disabled
- the 64-bit code was simply copied from a 64-bit exe file over a range of nops in the 32-bit code section?
So the CPU would be told right in the middle of some 32-bit code, via wrmsr, "the next bytes are to be interpreted as 64-bit instructions" ?

Step 4) is required because without it the CPU is not yet in 64 bits mode. Only after paging is re-enabled the CPU goes into 64 bits long mode.

Step 6) is also required because without it you are in long mode BUT the CPU is in 32 bits compatibility mode (this is the mode that allows 32 bit code to be executed in 64 bits mode).  The FAR JUMP will load an 64 bits selector into CS and in this way it will signal to the CPU that it is OK to enable R12 and all the extra registers stuff.

So no, you can not simply write to an MSR and get in/out of 64 bits mode. It will not work. Instead you need to execute the whole sequence.

Additionally the IDT table (interrupts and exceptions descriptor table) is different in 64 bit mode than it is in 32 bits mode.

Hence ANY hardware interrupt (eg. timer, network card, video card, etc) will triple fault and reset the CPU. You can not stay long in here because without handling the hardware interrupts you will stop the computer I/O devices from working.

Also if you are unlucky to generate an exception (divide by zero) the CPU will reset because the old 32 bit IDT can not handle it.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

jj2007