1

I am starting to learn x86_64 assembly, one thing I noticed is the usage of registers such as rdi, rbp, rax, rbx. Do they exist in the CPU or is this some sort of abstract mechanism used by assembler?

For example if I do

mov       rax, 60

does this find a register in hardware with this assigned name?

phuclv
  • 37,963
  • 15
  • 156
  • 475
Naveen
  • 769
  • 1
  • 9
  • 28
  • 1
    Yes they do exist. Of course they don't have tiny labels printed on them :D However, modern cpus have a larger register file physically and the cpu maps the visible architectural registers to that transparently to the programmer. You do not normally have to deal with that. – Jester May 30 '21 at 00:47
  • 3
    Physical registers exist physically. Virtual registers do not. **Obviously.** This question really isn't a programming question anyway, and doesn't belong on Stack Overflow. It is probably appropriate on superuser.com. See e.g. https://superuser.com/questions/695475/whats-the-difference-between-a-hardware-register-and-a-memory-mapped-register – Peter Duniho May 30 '21 at 00:54
  • 1
    more registers mean more instructions or a different instruction set. also understand that x86 is microcoded...many/most architectures are not. – old_timer May 30 '21 at 01:13
  • 1
    how would the processor work if there werent registers somewhere in the logic? – old_timer May 30 '21 at 01:15
  • 1
    There isn’t a register in the CPU dedicated to contain rax. Instead, there is a large collection of registers, maybe a couple hundred, and there is a pointer that indicates which of those registers contains the value of rax at any given moment. This reassignment is done by the CPU each time an instruction changes the value of rax. – prl May 30 '21 at 01:22
  • 2
    The reason there aren’t more register available directly in assembly language has to do with the way assembly language is encoded. There are only 3 bits in the instruction to encode the register. The 64-bit extension added one more bit, allowing 16 registers. AVX encoding added one more bit for certain instructions, allowing 32 of certain types of vector registers. – prl May 30 '21 at 01:25
  • [Terminology: “registers” in assembly language programming](https://stackoverflow.com/q/814448/995714), [What are CPU registers and how are they used, particularly WRT multithreading?](https://stackoverflow.com/q/2384578/995714), [How many EAX register do modern processor have?](https://stackoverflow.com/q/21216290/995714) – phuclv May 30 '21 at 01:34
  • Does this answer your question? [Terminology: "registers" in assembly language programming](https://stackoverflow.com/questions/814448/terminology-registers-in-assembly-language-programming) – phuclv May 30 '21 at 01:34
  • @prl: it's only AVX-512 (with 4-byte EVEX prefixes) that has 32 vector regs. AVX1 / AVX2 with VEX prefixes add a 3rd operand (so a whole new 4-bit field), but otherwise can only address the same 0..15 that legacy-SSE + REX can. (Or the ymm versions.) – Peter Cordes May 30 '21 at 01:40
  • On older processors, you can actually see the registers on the die. For example, see [this article](http://www.righto.com/2020/06/a-look-at-die-of-8086-processor.html) for the 8086. The registers are to the left. – fuz May 30 '21 at 07:44
  • That is interesting, thanks @fuz – Naveen May 30 '21 at 14:04

1 Answers1

7

CPU hardware doesn't find registers by name, it's up to the assembler to translate names like rax to 3 or 4-bit register numbers in machine code. (And the operand-size implied by the register name is also encoded via the opcode and (lack of) prefixes).

e.g. add ecx, edx assembles to 01 d1. Opcode 01 is add r/m32, r. The 2nd byte, the ModRM 0xd1 = 0b0b11010001, encodes the operands: the high 2 bits (11) are the addressing mode, plain register, not memory (for the dest in this case, because it's 01 add r/m32, r not 03 add r32, r/m32).
The middle 3 bits are the /r field, and 010 = 2 is the register number for edx.
The low 3 bits are the r/m field, and 001 is the register number of ECX.
(The numbering goes EAX, ECX, EDX, EBX, ..., probably because 8086 was designed for asm source compatibility with 8080 - i.e. "porting" on a per-instruction basis simple enough for a machine to do automatically.)

This is what the CPU is actually decoding, and what it uses to "address" its internal registers. A simple in-order CPU without register renaming could literally use these numbers directly as addresses in an SRAM that implemented the register file. (Especially if it was a RISC like MIPS or ARM. x86 is complicated because you can use the same register numbers with different widths, and you have partial registers like AH and AL mapping onto halves of AX. But still, it's just a matter of mapping register numbers to locations in SRAM, if you didn't do register renaming.)


For x86-64, register numbers are always 4-bit, but sometimes the leading zero is implicit, e.g. in an instruction without a REX prefix like mov eax, 60. The register number is in the low 3 bits of the opcode for that special encoding.

Physically, modern CPUs use a physical register file and a register-renaming table (RAT) to implement the architectural registers. So they can keep track of the value of RAX at multiple points in time. e.g. mov eax, 60 / push rax / mov eax, 12345 / push rax can run both mov instructions in parallel, writing to separate physical registers. But still sorting out which one each push should read from.


if thats the case, i am wondering why there are only 16 registers in x86_64 architecture ...

A new ISA being designed for the high-performance use-cases where x86 competes would very likely have 32 integer registers. But shoehorning that into x86 machine code (like AVX-512 did for vector regs), wouldn't be worth the code-size cost.

x86-64 evolved out of 16-bit 8086, designed in 1979. Many of the design choices made then are not what you'd make if starting fresh now, with modern transistor budgets. (And not aiming for asm source-level compatibility with 8-bit 8080).

More architectural registers costs more bits in the machine code for each operand. More physical registers just means more out-of-order exec capability to handle more register renaming. (The physical register numbering is an internal detail.) This article measures practical out-of-order window size for hiding cache miss latency and compares it to known ROB and PRF sizes - in some cases the CPU runs out of physical registers to rename onto, before it fills the ROB, for that chosen mix of filler instructions.


, doesn't more registers means more performance ?

More architectural registers does generally help performance, but there are diminishing returns. 16 avoids a lot of store/reload work vs. 8, but increasing to 32 only saves a bit more store/reload work; 16 is often enough for compilers to keep everything they want in registers.

The fact that AMD managed to extend it to 16 registers (up from 8) is already a significant improvement. Yes, 32 integer regs would be somewhat better sometimes, but couldn't be done without redesigning the machine-code format, or with much longer prefixes (like AVX-512's 4-byte EVEX prefix, which allow 32 SIMD registers, x/y/zmm0..31 for AVX-512 instructions.)

See also:

Related Q&As:

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