Mixing ml64.exe and Win32 C++: is it possible?
I am currently running WinXP Pro on a dual AMD Opteron system. The development project I'm working on is a high-performance CAD/graphics program. The project is mostly Win32 C/C++, but we also have many specialized performance-critical subroutines hand written in assembler. These assembler files are part of the Visual C++ project and each has a custom build-step that uses ml.exe to compile.
We would like to take advantage of the 64-bit registers in our hand-coded assembler routines. The use of the 64-bit registers would only be for mathematical computation, e.g., we don't need the full support of a 64-bit OS with 64-bit memory addressing. So we were hoping to be able to update our assembler subroutines, compile with ml64.exe, and then link with our existing Win32 project.
It appears, however, this is not possible. The linker will not let us link the object files compiled with ml64.exe to our Win32 project. The only way to make the link successful is to compile the entire Win32 project as 64-bit. But then we cannot run the final executable on 32-bit WinXP.
Is there any way to use the extra registers on the x64 chips while still being able to link and run the final executable in a 32-bit WinXP environment?
-bakerbud9
At first thought I was almost about to respond that it's not possible. After thinking it through there might be some way to do it.
Remember 16/32 bit days? I recall there was a prefix (I think it was 066h or maybe 067h) which allowed you to use 32 bit registers in 16 bit mode. If you on the other hand used the same prefix opcode in 32 bit mode you accessed the 16 bit registers. ... Atleast something along those lines.
First thing you must do is to avoid ml64. It won't work. The object code is incompatible because it's targeted for another OS and another platform. Your only hope is the AMD/Intel manuals and ml.
One question though... What will happen if you run code targeted 64 bit registers on a CPU which doesn't support it like Pentium 4? Best guess is a crash for invalid opcode.
So you should do a check to see if it supports 64 bit code. I would start to look at the instruction cpuid and see what you can get out of it.
I know this is vague because I am not sure myself about it, but what I do know is that your only hope is to continue with your standard tools and forget about the 64 bit versions. AMD might have restricted the access so you can't access the registers from 32 bit mode. Personally I think so.
The alternative is to port your application to 64 bit which will work for sure. I am sure that alot of companies will provide both 32 and 64 bit versions of their software. This is needed if AMD64 platform should be a success.
Hi Henrik,
Perhaps you are right that AMD restricts use of 64-bit registers when running in 32-bit mode. You also are right that using ml64.exe will not ever work with anything compiled 32-bit.
I was thinking that CPUID could be used to determine if the processor had the needed 64-bit registers. It is our plan to make 64-bit hardware a requirement for our software package... so at the assembly level we're not concerned about backwards compatibility. A check of CPUID at startup would let us know if it was a 64-bit platform or not so the program could gracefully exit if needed.
But we were also hoping that we could allow the software to run on 32-bit Windows, since it is still such common platform and Longhorn seems to be, well a "long" time to wait still. In other-words, we were hoping to make 64-bit hardware a requirement but 32-bit OS an option. However, it does not seem this is at all possible... unless we really get into some fine trickery (which we really don't want to do).
As Hendrik said in another post, you cannot use the 64 bit registers in a 32-bit application.
If you are running on a 64-bit system you could compile performance critical parts to 64 bit code (hand assembeld or not) and then use an interprocess communication mechanism to get data between the 2 (COM, TCP/IP, named pipes, ...).
Ronald Laeremans
Visual C++ team
Hi Ronald,
Oh, I think we'll just wait for Longhorn. Hopefully it won't be too many (years) before 64-bit Windows is ubiquitous.
You did precisely answer my question, though. Thank you.
-bakerbud9
Hi bakerbud9,
it is not possible as already said to mix the two architecture in code. The 64 Bit processors have 2-3 operation modes.
1. Full 32 Bit
2. Full 64 Bit
3. Mixed where it is possible to execute 32 Bit code for compatibility reasons with older apps
Recently i was faced with a very similar porting exercise so i can tell you:
1. Port your main app to 64 Bit. It is allmost painless to recompile in most cases
2. Your assembler needs allmost only an adaption in memory arithmetic in 64 Bit ( load, save, adressing etc.). Most sections can be unmodified when 32 types are ok for your processing. I think so. You don't need to use at every 32 Bit assembler line the 64 Bit pendent.
3. Use SSE, 3DNOW or FPU directly. You can increase speed by factor 2-10. Maybe convert some parts that they use these instructions sets if you not already did so.
Bye
Martin