5

Many software only supports 64-bit machine because the market for 32-bit is small now. However, for those who are stuck with 32-bit machines, this means newer versions cannot be installed, and this can lead to security issues. One example is Firefox/Waterfox.

In general, is there a way to make a 32-bit program from a 64-bit installation (.exe, .msi)?


See more: Why should browser's security be prioritized?

11
  • 3
    If you could do it easily, so could software vendors and they would do it for you. – gronostaj Sep 11 '18 at 11:35
  • 2
    It's also worth noting that if you're talking about an x86 system, it really is worth upgrading even aside from the security implications. An otherwise identical x86 system running 32-bit versus 64-bit will (almost) always perform better running 64-bit. – Austin Hemmelgarn Sep 11 '18 at 19:19
  • @AustinHemmelgarn I've thought that x86 is another way to say 32-bit? – Ooker Sep 12 '18 at 4:31
  • 1
    No, x86-64 is a superset of x86. It contains all the features of x86 + more. x86 is a subset of x86-64. – gronostaj Sep 12 '18 at 11:03
  • 1
    @Ooker It depends on the context. Realistically speaking though, when someone just says 'x86' without any specific qualifiers, they mean the architecture as a whole, not just the 32-bit version. – Austin Hemmelgarn Sep 12 '18 at 15:01
12

No, this is not possible. The reason why is quite broad, maybe even too broad for SuperUser, given that you would need to explain the fundamentals on how x86 and x64 were created, and how this influences programming in general.

But to explain briefly, it comes down to this:

In the past, we had 16-bit processors. Then intel made the first 32 bit processor, also known as x86. This is the 8086, 80286 (286 for short) etc... This was basically a modifcation to the 16 bit processors, with extra instruction sets added. With every new release of their processor series, Intel added more instruction sets to the processor family, which in the end caused the instructionset to contain many many instructions. Intel could not just remove old instruction sets because that would mean there was no backwards compatibility, and Intel wanted to keep supporting older processors.

As the processor is 32 bits, there is an upper limit, namely the highest 32-bit number. This means, that memory assignment only goes up to about 3,5GB.

Back in the days, computers were not so powerful, so if intel would aim for 64 bits from the start, it would mean that much more time was spent calculating the same numbers so performance would degrade simply because the numbers to calculate with are bigger.

Besides 32 bit processors worked quite well for a long time.

At some point, AMD entered the market and introduced the 64bit processor. AMD created their own instruction sets to allow working with 64 bits while keeping the intel instruction sets for 32 bits in tact to allow for backwards compatibility with 32 bits.

Given that they are in fact different instruction sets, a programmer who creates 32 bit programs will call different routines than when they create 64 bit programs.

Now that I explain why this is hard to do, lets continue to explain the problem from a programming perspective.

When you code a program, you write your code first. If your code is backwards compatible for 32 bits programs, you simply cannot use 64-bits numbers nor can you address more than 3,5gigs of memory at the same time. Basically, you cannot cross any limits that 32 bit programs face or your program will crash when done so.

As you now have code, only you can actually run your program. In order to make it so that other people can run your program, you have to compile the code into an executable. This means that the easy to read code is converted into instructions that the processor understands. During compile, you specify if your program is meant to run on x86 or x64, and the compiler will generate code using the instruction sets based on that processor architecture.

As you can see, you can't just modify an executable and make it work on a different executable. You first need to decompile the program to code, then recompile it using different instructions.

That said, given that a program that is compiled for x86 will natively work on x64, it is safe to assume that a programmer creates an x64 program because he is going to break limits of the x86 architecture. So even if you were to turn the x64 version into an x86 version, it is likely that the program will be unstable as you will cross the limitations of what a 32-bit program can do.

2
  • 6
    Nice write-up. Technically not entirely correct, but as a simplified explanation it will do nicely. – Tonny Sep 11 '18 at 8:04
  • 2
    Thanks. Yeah, it is hard to make it technically correct if you have to limit yourself. This is the best I could do to keep it suitable for SuperUser. – LPChip Sep 11 '18 at 8:11
9

Theoretically it can be done!

There are ways to translate from a neutral bytecode/internal representation to a specific architecture's binary like how modern compilers/JITters work. There are also emulators that run programs for another architecture on the current one. Bochs and qemu are two of the most famous ones. See:

Despite that I've yet to see anyone writing a converter like that for a single binary, because basically you'll also need to emulate every system and library calls, in which case it'd be better to run the whole emulator anyway. Qemu also has the ability to emulate only the user space, so it's actually possible to run a program along with its required libraries without a full-fledged OS. But as always, emulation is not meant for performance-sensitive things like web browsing or media playing

However if your x86 PC is 32-bit only, that means it's already more than 10 years old. Pretty much any Intel CPUs from Pentium 4 Prescott in 2004 onward (apart from some early Atom CPUs) and all AMD CPUs from Athlon 64 in 2003 onward are 64-bit capable. It's time to update.

If your PC is new enough to support x86_64 and VT-x then you can run a 64-bit virtual machine inside a 32-bit host, however it's not recommended and the performance will be even worse than running a 64-bit host with a 32-bit VM inside. A 64-bit OS doesn't need twice the memory compared to a 32-bit one like many people thought, so even with only 2GB of RAM, a 64-bit OS is generally still faster due to twice the number of registers and many other things. Between 1 and 2GB of RAM it's arguable but I'd go for 64-bit


That said, regarding security measures, 32-bit OSes nowadays are often late on security patches because developers all run a 64-bit system. For example the Meltdown and Spectre patches are pushed for 32-bit Linux more than half a year after 64-bit Linux has been patched. Meltdown patches are provided for 64-bit Windows 10 build 1507 and up but 32-bit users are only protected since build 1511. And even if they're patched, such ancient machines will usually face a lot more performance impact because they don't have the new instructions and features to offset the slowdown. Due to that reason MS doesn't enable the patch on some old PCs unless explicitly told by the user. And beside performance drop, a 32-bit patch will be more likely to be buggy because of a significantly fewer number of testers. See Linux's 32-Bit Kernel Has Been Buggy Since Being Mitigated For Meltdown:

Not only did it take months after Intel's Meltdown vulnerability was published (and x86_64 being mitigated) to see Linux KPTI support for x86 32-bit to mitigate Meltdown (from January's disclosure to mainline readiness in July), but it turns out it ended up exposing a 32-bit only bug that has lived in the kernel from summer 2018 until now [28 July 2019] with the Linux 5.3.

Sometimes they won't be patched at all because there's not enough user base, thus little incentive to spend the massive effort. The issue is also impossible to fix without hardware support if it's a hardware bug. For example recent side-channel attacks like Spectre or L1TF also need an updated microcode, so if the CPU and/or mainboard manufacturer don't release a firmware update, you're out of luck! Those bugs affect CPUs in the last two decades, but it's not possible to provide patches for very old systems. Windows 7 also dropped Pentium 3 support because it's too hard to patch without SSE2 support, or because too few people running it on those CPUs.

32-bit Windows is also more vulnerable because:

If you run a 64-bit OS in an emulator then it'll even be slower. And even if you accept the crawling speed and use an emulator then malwares on the host can still attack the virtual machine in such a vulnerable system. Again, time to update if you really care about security, or you'll have to live with less a secured system indefinitely

Further reading:

5
  • 2
    "such ancient machines will face a lot more performance impact because they don't have the new instructions and features to offset the slowdown." - This isn't entirely true. There is absolutely no reason, I could not run a 32-bit operating system with an i7 8086K, and Windows 10. Just because the system is running a 32-bit operating system does not mean it's ancient. – Ramhound Sep 11 '18 at 11:08
  • on those systems it's better to run a 64-bit OS. In case a 32-bit OS is really needed, just run it in a VM. I've already stated that those applies to 32-bit only systems – phuclv Sep 11 '18 at 11:10
  • +1 for pointing out emulation (w/ binary translation) could do it. – Bob Sep 11 '18 at 11:24
  • See more: Why should browser's security be prioritized? – Ooker Sep 24 '18 at 12:37
  • 1
    @Ramhound is understating the issue somewhat. It's not just that you could choose to install a 32bit OS on a new system, at the bottom end of the PC market (eg atom with 2gb of ram) some systems have still sold with within the last 2 or 3 years with 32bit Windows even if they had a 64bit capable CPU. This is presumably partly because these systems have very small SSDs and win32 has a smaller footprint than win64, and partly because MS's cheapest tier of Windows licensing to major OEMs (this is not the same as the 'OEM' install you can buy as a consumer) was (is???) 32bit only. – Dan Is Fiddling By Firelight Sep 24 '18 at 13:48
5

This is technically possible; the process is called binary translation.

You'll most often find this put into practice with emulators for disparate platforms (e.g. ARM on x86, x86 on ARM), or virtualisation where hardware acceleration is not available.

The biggest problem you'll face is that you cannot simply run most programs in a vacuum. They depend on the operating system's ABI, which typically varies between architectures. This means you end up needing to add a translation layer for all interactions with the OS (API calls, etc.), at which point you might as well emulate the entire OS ... which is described in phuclv's answer.

1

Recompile the program to a 32-bit target

Your question was framed as having a 64-bit binary and wanting to run it as a 32-bit one, which is quite hard and you end up having to use an emulator or other complex issues.

However, if you have the original code in an high level language (as is the case for Firefox), you can probably compile it into 32-bit code.

Here, I respectfully disagree with the last paragraph of LPChip answer that a programmer creates an x64 program because he is going to break limits of the x86 architecture. They could be doing it because it is the default target, to match the native architecture, or simply to benefit from being able to use more memory if the user had enough RAM.

Some features like 64 bit counters made from 32 bit ones will be slightly slower than using a native register. If the program does use features specific to 64 bits (like inline 64 bit assembly) it won't work. The onus will be primarily on the compiler support on whatever high level language is being used (and the code on being well-written so it is quite portable to begin with).

If we focus on building Firefox / Waterfox, it is not a simple endeavor for the novice (nowadays browsers are like an OS of its own), less so with Firefox Quantum additionally requiring a rust compiler. Still, Linux distros still compile 32 bit versions of Firefox, showing that it can run under 32 bits.

1
  • While I generally like this answer, unfortunately, it's often not as simple as recompilation: while good practice suggests that developers should use platform-agnostic types (e.g. int32_t or int64_t instead of long or long long), that's unfortunately not always followed. If any assumptions about word size exist, compiling for a different architecture won't work. Similarly, if there are any x86_64-specific optimisations. Keep in mind that x86_64 provides many more general purpose registers than x86; it's not just pointer size that differs. – Bob Sep 26 '18 at 3:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.