2

It does not necessarily need to be an entire program, just a simple operation which performs the same action on both processors.

Without CPU emulation such as qemu.

If this is not possible, can you explain to me like I am 5, why it is not possible.

walther
  • 13,466
  • 5
  • 41
  • 67
user2675345
  • 531
  • 3
  • 12

5 Answers5

2

It would be like trying to read English with a french dictionary and vice versa.

Different CPUs are like different languages, only an emulator can act as an
interpreter to let a program for an architecture be run on an other.

galop1n
  • 8,573
  • 22
  • 36
  • If two chip manufacturers decided to use identical instructions, i.e. ADD = 0101 then are there any other reasons why object code generated for one will not work for the other? I'm looking for more of a list of arguments here not just the most obvious one. – user2675345 Feb 04 '14 at 15:21
  • It's not only instruction but also addressing mode encoding. Otherwise they aren't any reason ! think about AMD vs Intel procs. – hivert Feb 04 '14 at 17:57
  • 1
    "It would be like trying to read English with a french dictionary and vice versa." That's a nice way to put it :D – Jake Oct 13 '22 at 16:16
1

This is an old question, but I just found this via a Google search and want to try and clarify for anyone else who might stumble upon it.

In short, x86 and ARM binaries are incompatible, but I think this comment from the OP clarifies what the real question is:

If two chip manufacturers decided to use identical instructions, i.e. ADD = 0101 then are there any other reasons why object code generated for one will not work for the other? I'm looking for more of a list of arguments here not just the most obvious one.

If hypothetically two chip manufacturers decided to use identical instructions/encodings/pipelines, then yes they'd be able to run the same code, but that's because they'd already be using the same ISA.

Intel and AMD designs for x86 processors are typically very different from a physical perspective1, but those different chips from different manufacturers are able to run the same code precisely because they've "decided to use identical instructions".

x86 and ARM themselves aren't really "chip" designs, but they're specifications of an abstract machine2. There's a strong link between the physical design/implementation and how the instruction sets and pipelines are defined because there will be obvious efficiencies to certain approaches, but an "ARM" processor doesn't have to confirm to any specific physical design. An "ARM" processor just has to provide the same programming model as the "ARM" abstract machine.

In theory there's nothing stopping any one "chip" from implementing both x86 and ARM instructions as long as it had a way to distinguish between then, but it would probably be a hugely inefficient waste of money, power and resources. The current momentum behind ARM is at least partially due to the bloat that x86 has built up over the years, so combining the two would probably give you the worst of both worlds.


1 - Take this with a grain of salt, as processor architectures are changing rapidly, but from what I understand Intel tends to design monolithic implementations and AMD tends to design chiplet implementations.

2 - This is a simplification, but "x86" and "ARM" are actually whole ISA families, and both can refer to a large number of different standards with various optional extensions.

Jesse Wyatt
  • 113
  • 8
  • Instruction encoding isn't the only necessary thing for ISA compatibility. We can assume "identical instructions" includes all their semantics and implicit operands, and rules for which operands will fault or not, and how FLAGS are set, and having the same set of registers. But other things can be different, too, like memory-ordering and atomicity rules for multi-threaded code. – Peter Cordes Jul 12 '22 at 05:05
  • Interestingly, this is one area where Intel and AMD aren't identical, with Intel providing stronger atomicity guarantees ([any alignment within a cache line, vs. only within an aligned 8-byte chunk](https://stackoverflow.com/questions/36624881/why-is-integer-assignment-on-a-naturally-aligned-variable-atomic-on-x86/36685056#36685056)) - compilers and `std::atomic` implementations choose to target the lowest common subset of guarantees, naturally. See [What EXACTLY is the difference between intel's and amd's ISA, if any?](https://stackoverflow.com/q/38516823) for that and other stuff – Peter Cordes Jul 12 '22 at 05:06
  • Anyway, for ARM vs. x86, note that part of what lets Apple's Rosetta be efficient and correct is that they have hardware support for a stronger memory-*ordering* model, like x86-TSO, which the M1 CPU can switch to when running AArch64 code translated from x86 machine code. So they don't need to figure out which loads/stores might touch shared data, in order to add barriers (or use `ldar` / `stlr` with them, or with everything.) See https://singhkays.com/blog/apple-silicon-m1-black-magic/#performance-must-suck-when-trying-to-emulate-x86-on-arm-right – Peter Cordes Jul 12 '22 at 05:10
  • Also semi-related: [Could a processor be made that supports multiple ISAs? (ex: ARM + x86)](https://stackoverflow.com/q/63440762) (different front-end for the same out-of-order exec back-end? Possible in theory, but harder the more different the ISAs are.) – Peter Cordes Jul 12 '22 at 05:11
  • Anyway yes, overall good answer, my above comments are just footnotes / additions, not real problems. If two CPUs used the same machine code format, it would be normal to design them to be compatible enough for software to run on both. – Peter Cordes Jul 12 '22 at 05:12
  • 1
    For sure, I understand there is more to an ISA than the binary instruction encoding but was trying to keep this as beginner friendly as possible. I think it's mostly important to to clarify that in this context terms like "x86" and "ARM" refer to standard programming models, not necessarily physical chip designs, and that an ISA is itself essentially the kind of hypothetical interface OP was suggesting. Very good points about memory-ordering and atomicity/threading. The Rosetta note is super interesting, I wasn't aware that Apple Silicon had actual *hardware* support for strong-ordering. – Jesse Wyatt Jul 12 '22 at 05:51
  • Yeah, 100% agreed, your answer makes the key points in a beginner friendly way without getting bogged down in the details that caught my attention. BTW, polyglot machine code is possible (see my answer), but metadata would be a problem for getting two different OSes to actually run the same executable. So we'd need to imagine some hypothetical environment or program-loader that would be willing to load and try to run machine code without metadata that specifies which ISA (and OS) it's for. – Peter Cordes Jul 12 '22 at 06:02
0

No it's not. Program executed by the CPU are encoded in machine language. x86 and ARM doesn't have the same instructions in their respective machine language, and the encoding are very different.

hivert
  • 10,579
  • 3
  • 31
  • 56
0

It is possible if you don't compile directly for the specific ISA, but it is still work in progress. Have a look at Transmeta. What they do is insert a layer on top of the internal architecture that accepts "generic" code. You can think of it like a JVM in hardware, at a very high level of abstraction.

Tib51
  • 162
  • 6
0

It's possible to write polyglot machine code, which decodes on x86 as a jump to more x86 machine code (which doesn't have to be valid ARM machine code). And if executed on ARM, it ends up executing a different part of the code.

So you'd have one small part of the machine code which can be decoded as instructions for either ISA, jumping to separate destinations depending on which.

For example, https://news.ycombinator.com/item?id=27033330 is a 4-way polyglot for x86, ARM, AArch64, and MIP(little-endian). Each different interpretation of the code branches to a different relative offset. (Before reaching any instructions that would do more than modify registers.) I googled polyglot arm x86, there are likely others. Also related: x86-32 / x86-64 polyglot machine-code fragment that detects 64bit mode at run-time? is a polyglot for multiple modes of x86, which use the same machine-code format but different defaults for operand-size, except for 64-bit mode which changes the meaning of some opcodes.

It's not practical (or likely possible) to write an entire program this way, nor for the code to do the same things on both ISAs. If they have the same machine-code format, they're the same ISA (assuming other things are the same, like memory-ordering semantics, and a bunch of kernel stuff like interrupt handling, page tables, TLB invalidation semantics, etc.) ARM and x86 are not the same ISA, using very different machine-code formats.


Of course, normally a "fat binary" doesn't need that, you have metadata which tells the OS's program-loader which part of your program is which. (A "fat binary" being one with multiple versions of the machine code, usually compiled for different ISAs.

MacOS had this during the PowerPC to x86 transition, you could have one file that was about twice the size, but would run on either. And now they have it again with x86-64 and AArch64. When you run that executable, an x86-64 MacOS will see that there's a "slice" for x86-64, and run that part of the program the same as if it was the only thing in the executable. But an AArch64 MacOS would look for an AArch64 slice in an executable, and run it if found.

If the OS doesn't find what it's looking for, the execve system call will return an error about invalid exec format. It won't map AArch64 machine code into memory and jump to it, on an x86-64 machine.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847