On GNU/Linux, x86/x86-64, in general, what is the reason that (at least sometimes, maybe there are exceptions) 64-bit library code cannot be used by a 32-bit program?

I'm aware of many of the differences between x86-64 and x86, long-mode, the extended registers, the new registers, the removal (to some extent) of segments.

But why does this matter? The changes in long mode that are related to privileged code doesn't apply to system libraries, unless they run in kernel mode, which they don't.

As for the user land changes, larger registers, new registers, etc. why does this matter? On a 64-bit system the CPU would already be running in long-mode when it enters user space, and with long-mode being backwards compatible in this context (without even switching to protected mode), it should be able to use both 32-bit and 64-bit code, in user space.

Am I missing something obvious here?

Now, of course, if the 64-bit library simply has a different API, or that it is simply with a different name, e.g. running ldd might show that it is looking for a shared library with a different name than the 32-bit equivalent. That would be a problem. Although the solution (even if a kludge) would be very easy if that was all there is to it.

I can also imagine that since the x86-64 calling convention is different from regular x86, that would be a problem with even calling the functions in the library. Surely this must be part of the problem?

But it feels like there should be a better reason here, and I'm sure I'm missing something obvious.

  • To be clear, are you asking why a 64-bit application can't use 32-bit libraries or vice versa? Sep 29, 2018 at 3:29
  • I had mixed the two up in the first paragraph, corrected it now. Again: I'm asking why cannot a 32-bit binary use a 64-bit shared library. Sep 29, 2018 at 11:54
  • More like a stackoverflow question Sep 29, 2018 at 12:48

1 Answer 1


An x86-64 processor is only backwards compatible with 32-bit x86 processors through the compatibility mode it implements. The majority of the instructions of the x86-64 in long mode are identical to the ia-32 instructions, so you could achieve some compatibility by (among other things) just ignoring the upper halves of the registers. However, there are differences, and some ia-32 instructions like short jumps are dropped from x86-64 long mode. 64-bit and 32-bit x86 effectively implement different instruction sets.

You can only run 32-bit code on an x86-64 CPU by switching the processor to compatibility mode, and vice versa. To call 64-bit library code from 32-bit compatibility mode requires a mode switch out of compatibility mode to 64-bit long mode. This requires setting up separate code segments for code in long mode and compatibility mode, since the mode is determined by a bit in the code segment descriptor. There are some more things to take into account, like for example the fact that, in compatibility mode, the CPU only sees the lower 4 GB of the virtual address space.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .