Consider Intel x86 and AMD x86 Processors. As I understand, since they use the same Instruction Set, in theory an application compiled for Intel x86 processor would run without any modification on AMD x86 processor, even though these processors have different microarchitectures. Is my understanding correct? Or is there any exception to this rule?


Most binaries compiled for x86 will work on x86 because all x86 processors have the same binary instruction format.

Instruction set extensions are quite rare and happen after several consultations between the different vendors. For example, one of the most famous extension is the AES encryption extension to the x86 instruction set called AES-NI and developed by Intel. Both AMD and Intel added the extension to their processors in 2010.

The AES-NI instruction set extensions are used to optimize encryption and decryption algorithms on select Intel and AMD processors. Intel announced AES-NI in 2008 and released supported CPUs late 2010 with the Westmere architecture. AMD announced and shipped AES-NI support in 2010, starting with Bulldozer.

It isn't really true that extensions make x86 CPUs non-compatible because most extensions will be adopted by major vendors in the same year or so.

Code written to take advantage of extensions usually run only under compilers written by the vendor. For example, to take advantage of Intel Extensions you need to use the Intel Compiler, which won't work for AMD processors.

This is not really true. There is no "Intel compiler". Instead, you use an existing compiler with extensions in the compiler. It is up to the compiler to support an extension or not. Most of the time when developing software, you know the CPU you target and you assume that most clients won't be using a very old CPU. You thus simply assume that the targeted CPU supports a certain extension. For example, as to AES, most CPUs support AES-NI. You can safely assume that a user of your code has this extension on their processor and can thus use the extension.

In g++, you have the -maes flag which allows to enable the AES-NI extension. You will thus be able to use these instructions either in inline assembly or let the compiler do it using certain optimization levels. This probably requires looking at the assembly output and doing some testing and reading g++ documentation. I'm not this much aware so I can't tell how that works exactly but you can have a look at an actual implementation here: https://stackoverflow.com/questions/32297088/how-to-implement-aes128-encryption-decryption-using-aes-ni-instructions-and-gcc.

The micro-architecture is how the ISA is implemented in the processor. It varies greatly between vendors. Both AMD and Intel have the same registers though (which could be considered a part of the micro-architecture). There exists several Model Specific Registers (MSR) and these are called differently from Intel or AMD. For example, there exists an MSR to do a system call in the kernel (https://stackoverflow.com/questions/66853510/who-sets-the-rip-register-when-you-call-the-clone-syscall/66863181#66863181). In Intel documentation it will be called IA32-LSTAR while for AMD it will be called LSTAR or STAR64. Both registers have the same number tough. Again, you have a good compatibility.

In your answer at first, you assumed that instructions to "talk to hardware" were different (for device drivers). This is also not commonly true. Today, most devices have very strong conventions that they must follow in order to be compatible with the computers they will be plugged in. For example, you have PCI for most peripherals, SATA for hard-drives, DDR3 for RAM, USB for other peripherals, ACPI for hardware detection and power management etc.

In most computers today, the only difference between using an AMD processor or an Intel processor is in the detection of the different hardware and the base addresses you are going to use to "talk" to this hardware. This could be considered a difference. For example, the base address of the PCI configuration space could be different between an AMD or an Intel processor. I'm not a hardware engineer but this is not necessarily due to the processor but mostly due to the motherboard or other components. Again, there is very good compatibility. The only difference it makes is that code written to detect PCI devices should take in consideration that the base address could change between computer and only use "relative" code as opposed to "absolute" code (use relative addresses instead of absolute and not assume that the address will be the same everywhere).

  • 1
    $\begingroup$ What about Intel intrinsics (Intel specific C-style functions)? Can you add about that? $\endgroup$ Jul 22 at 15:23
  • $\begingroup$ I honestly don't know about it. $\endgroup$
    – user123
    Jul 22 at 15:27
  • $\begingroup$ software.intel.com/content/www/us/en/develop/documentation/… The Intel compiler icc $\endgroup$ Jul 22 at 15:28
  • $\begingroup$ In general, this is not what's used to actually write code for a specific platform. Try to use that in a mainstream IDE. It will be a nightmare. $\endgroup$
    – user123
    Jul 22 at 15:28
  • 1
    $\begingroup$ Probably some newer binaries that were compiled with extensions where the developers made assumptions like I said in my answer. These would not run on older processors. $\endgroup$
    – user123
    Jul 22 at 16:00

As a trivial problem, you can write a program that will try to print on which processor it is running, how many cores, how much memory etc. Such a program should obviously produce different results on an x86 and an AMD CPU.

On the other hand, it is quite possible to write code that runs correctly on a variety of very similar processors. AMD and x86 being "very similar" and not identical.

Many processors are based on some basic architecture, plus some extensions. Many developers check what extensions are available, and use them in order to get faster code by using those extensions. Now the set of bugs in the code that runs when the extension is available, and when it's not available, can be different, so behaviour could change.

  • $\begingroup$ The question is about binary compatibility, not about different results (performance or otherwise). I am only interested if a binary compiled for one micro-architecture can be run on another one if it shares the same Instruction Set $\endgroup$ Jul 20 at 12:39
  • 1
    $\begingroup$ x86 is not a CPU, it is an instruction set that both Intel and AMD use $\endgroup$ Jul 20 at 12:48
  • 1
    $\begingroup$ If you read my answer, it is trivial to write code that works on one machine and crashes on another. So “not binary compatible” in general. Only with effort of the programmer. And x86 is very commonly used for Intel CPUs. $\endgroup$
    – gnasher729
    Jul 20 at 19:27
  • 2
    $\begingroup$ The different extensions is mostly what makes the CPUs not binary compatible, as he says in the last alinea. That is, extra opcodes next to the x86/x64 opcodes that are available or not in some CPU. You can try lscpu on Linux and look at 'Flags' or download CPU-Z for Windows and look at 'Instructions'. $\endgroup$
    – Paul
    Jul 22 at 10:06
  • 1
    $\begingroup$ You can even write a program that prints the current time, that would obviously give different results at different times, even if the processors are binary compatible $\endgroup$ Jul 22 at 10:21

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.