Discussion:
32-bit on 64-bit
(too old to reply)
Paul Edwards
2023-08-16 14:35:27 UTC
Permalink
I have had success in getting Win64 executables to
run under UEFI with a relatively small amount of
"glue" to switch formats.

And I decided to see if I could get Win32 executables
to run instead of Win64, using different - more
complicated - "glue".

Here is a simple call to puts, but written in assembler
(so I need a C compiler to generate assembler that
looks like this - a separate exercise):

https://sourceforge.net/p/pdos/gitcode/ci/master/tree/pdpclib/msdemo32.asm

So this is dependent on msvcrt.dll, and then this loader code:

https://sourceforge.net/p/pdos/gitcode/ci/master/tree/bios/exeload.c

(search for w32puts) will put in the stubs for the win32
executable, and the puts stub can be found here:

https://sourceforge.net/p/pdos/gitcode/ci/master/tree/generic/w32hack.asm

So anyway, with this in place, it means I can write a 32-bit
windows executable that works on anything from win 95
to win 11, and it also runs on an appropriate 64-bit UEFI-based
system (basically just UCX64 from http://pdos.org). Note that
this is running 32-bit code in long mode.

There will be issues for something like printf, where I don't
know how many parameters there are, so I will just assume
a maximum of 4 or something like that.

Any thoughts/improvements?

Thanks. Paul.
Paul Edwards
2023-08-16 16:03:26 UTC
Permalink
Note that I tested the win64 on real hardware previously,
but I only just tested the win32 on real hardware now
and it failed. I'll need to find out why tomorrow.

Note that it worked on qemu.

BFN. Paul.
Paul Edwards
2023-08-16 17:24:32 UTC
Permalink
Ok, so my bootx64.efi contains a 1 in the upper 32 bits
of addresses, ie it has been loaded above the 4 GiB
mark (on real hardware).

I'm not sure how to get around that issue.

I could arrange for the high 32 bits of the return address
to be copied onto the stack and then do a ret instead of
a jmp, but that wouldn't work on a 32-bit system.

BFN. Paul.
Paul Edwards
2023-08-16 18:39:51 UTC
Permalink
Post by Paul Edwards
Ok, so my bootx64.efi contains a 1 in the upper 32 bits
of addresses, ie it has been loaded above the 4 GiB
mark (on real hardware).
I'm not sure how to get around that issue.
Switching linker to pdld has a low base address, and that
was sufficient for real hardware to work (plus another bug
fix was needed).

All code has been committed, and there is a w32hack.zip
available in the UCX64 section of http://pdos.org if you
want an image to burn to USB stick.

So we're back to working code, just after code review
or whatever.

BFN. Paul.
Paul Edwards
2023-08-16 18:59:55 UTC
Permalink
Post by Paul Edwards
There will be issues for something like printf, where I don't
know how many parameters there are, so I will just assume
a maximum of 4 or something like that.
I thought of a possible solution for this.

I can make it mandatory to call getmainargs, and have a
fudged argc - if argc is greater than x'80000000' then it
means that it is running under a 64-bit environment, and
argv is also fudged, and is a struct, and has a pointer to
a global variable that contains the number of parameters
to any variable-argument function.

So, when the global exists, the value gets populated.

Otherwise, it's a standard win32 environment that works
without assistance.

BFN. Paul.

Loading...