10
\$\begingroup\$

What kind of binary compatibility is present for 2 processors sharing an Instruction Set?. I had asked a question on Computer Science Stack Exchange, to which I got an answer which said:

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. etc. Such a program should obviously produce different results on an x86 and an AMD CPU.

I could not figure out how to write a program in any programming language or Assembly code that correctly prints the name of the processor. Such a program, would print "Intel i3-3220" on an Intel i3-3220 machine and "AMD Ryzen 5000 ..." (Don't know the exact model name) on an AMD Ryzen 5000 machine. Since both processors are binary compatible, I should be able to write a program that runs on both of them without recompiling. If a program exists to print the name of the processor, it has to detect the processor first. Of course, it can ask the Operating System the processor name, but this isn't the same as writing a program to detect the CPU model. I don't think such a program exists. But the operating system correctly detects the CPU Model.

Ubuntu uses the same operating system for AMD and Intel x86-64 processors. There is only one x86-64 bit version available called AMD64, that runs on both AMD and Intel x86-64 machines. How does the operating system detect the CPU model with the same, binary compatible program?

\$\endgroup\$
4
  • 6
    \$\begingroup\$ Most, if not all, modern processors have ID and version registers. These are usually numeric codes so you would need a translation table to actually print the processor type and revision. \$\endgroup\$ – Peter Smith Jul 21 at 11:02
  • 7
    \$\begingroup\$ @Justme CPUID on x86 can return the processor name/model as a human readable string (function 0x80000002 trough 0x80000004). \$\endgroup\$ – Unimportant Jul 21 at 11:18
  • \$\begingroup\$ @Unimportant Thanks for the correcting, so modern processors include extensions to provide user printable string. \$\endgroup\$ – Justme Jul 21 at 11:26
  • 2
    \$\begingroup\$ @PeterSmith Most UCs I've worked on even had valid ASCII in identification registers. Those were custom cores with custom instruction sets, though, which means there was no need for standardized versioning the way you'd expect in mass-produced consumer electronics. \$\endgroup\$ – DonFusili Jul 23 at 8:28
10
\$\begingroup\$

The architecture defines what results software can expect when running on an implementation conforming to the architecture. It is essentially a contract that ensures binary compatibility between different implementations and microarchitectures.

In general, the ISA only makes up a (small) portion of the architecture (x86, AMD64, ARM, RV etc). The architecture also defines registers, debug, exception handling, [..]. Any design implementing a given architecture must also include these various items to conform to that architecture.

In your particular question regarding CPU identification, the architecture will define methods of determing the implementation ID, optional architectural features, etc. Jonathan's answer covers the CPUID instruction in x86(_64) and shows the binary compatibility when running on different implementations of the architecture. Here's an answer on SO which describes using register accesses to find similar information in an ARM64 (AArch64) implementation. (Incidentally, the different ways one accesses this information in these two examples (x86, ARM) is a good example of the conceptual difference between a CISC and RISC architecture.)

\$\endgroup\$
17
\$\begingroup\$

For x86, you can use the CPUID instruction. It allows you to query various pieces of information about the CPU. It's built right into the CPU (and is not an operating system service).

\$\endgroup\$
10
  • 4
    \$\begingroup\$ @ShashankVM Yes. That's the intention of the CPUID instruction - the output includes the CPU vendor string (e.g. AuthenticAMD, GenuineIntel, CentaurHauls, etc) as well as other results that can be decoded to obtain other useful info. \$\endgroup\$ – nanofarad Jul 21 at 17:02
  • 1
    \$\begingroup\$ @ShashankVM: It does break binary compatibility. Binary compatibility means that you will get the same result, regardless of what CPU you run it on. But you don't get the same result. On one CPU, you get "AMD", on another you get "Intel". \$\endgroup\$ – Jörg W Mittag Jul 21 at 23:09
  • 8
    \$\begingroup\$ @JörgWMittag Isn't that an overly-strict usage of the term ‘binary compatibility’?  ISTM that this complies with the intent of compatibility, despite the different result. \$\endgroup\$ – gidds Jul 21 at 23:30
  • 2
    \$\begingroup\$ There are all sorts of different processor extensions available; the other function of CPUID is to give a machine-readable description of which instruction sets are available so your program can contain several different binary implementations of an algorithm for different processors and select one at runtime. \$\endgroup\$ – pjc50 Jul 22 at 9:39
  • 1
    \$\begingroup\$ @ShashankVM Re "Can I have a program in binary which can run on both Intel and AMD processor and produce the correct (but different) output?" - you can have a program, run repeatedly on the same system and producing correct, but different output - read timestamp counter for example. \$\endgroup\$ – Arvo Jul 22 at 9:56
6
\$\begingroup\$

In RISC-V, there is the Machine Implementation ID register (mimpid) that provides a unique encoding of the source and version of the processor implementation.

Source: The RISC-V Instruction Set Manual Volume II: Privileged Architecture Version 1.7

\$\endgroup\$

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