I dislike weird semantic hoop-jumping articles like this. It purposefully obfuscates a simple question to make it seem more complex. Just in the GPR section, the answer is simple...in long mode there are 16 that can be subdivided. There aren't 58 additional registers because of that.
Or, to get more specific, how many pieces of data are there in this union:
union Registers {
struct { unsigned short int AF; };
struct { unsigned char F, A; };
} regs;
Most would say one, with multiple interfaces. It might be "controversial" to some that consider each field independent, but I'd wager that they're a rare exception.
Yeah, this weird double or triple counting registers doesn't really do the article any favours, and yet it misses the place where it could actually be genuinely interesting - trying to work out how many shadow registers are used in register remapping (where the x86 instruction specifies e.g. rcx and that gets temporarily mapped to some temporary register from a bank of 32 or 64, and due to instruction re-ordering a later use of rcx might need to be assigned a different temporary register because some in-between instruction that hasn't yet completed used the first rcx value before it was replaced).
But in your specific example, going from the names, I'm guessing you are meaning Z80, in which case I'd argue that it's 2 registers that are occasionally lumped together (e.g. in this case PUSH/POP AF, EX AF,AF') and even with H and L are separate registers where HL is just a specialisation whereby the contents are used in quite a lot of instructions.
In the shift from 8080 to 8086, arguably e.g. AH and AL should be considered the real registers and AX the synthesized register, but it's already clear that the intention is for AX to be the primary use, with AH and AL more of a legacy view into that register. By the time of EAX and RAX, it's clear that the wider register is the real register, as apart from the special cases around AH and AL, a write of any size affects all the bits of the wider register.
Actually, even in the Z80 case, I think it's a bit futile to try to classify it as one or two registers - the register file is organised in pairs of 8-bit values deliberately so that the pair can feed to 16-bit incrementer even though anything more complicated actually happens on the 8-bit ALU (which of course is actually a 4-bit ALU on the Z80 behind the scenes).
I think the only sensible metric from a hardware perspective would be to consider how many bits a processor has in each of: per-thread, per-core and per-chip state.
> But in your specific example, going from the names, I'm guessing you are meaning Z80, in which case I'd argue that it's 2 registers that are occasionally lumped together (e.g. in this case PUSH/POP AF, EX AF,AF') and even with H and L are separate registers where HL is just a specialisation whereby the contents are used in quite a lot of instructions.
In what "example"? I never once referenced the z80 architecture here, so half of your post is just going off on some tangent. The only registers I referenced were x86 registers (EAX and RAX). The code example is just a generic example of a union, change the names to ZQ, for all I care.
The source example, that you yourself reference 2 sentences later:
> The code example is just a generic example of a union, change the names to ZQ, for all I care.
I'm not sure why you're so upset that I thought that might be a reference to Z80, but it's certainly a weird choice for completely random example code otherwise.
> The only registers I referenced were x86 registers (EAX and RAX).
In your example, you specifically called the structure "Registers" with fields named "AF", "A" and "F". Are you saying that it was completely coincidental that you happened to make a reference to a pair of registers called A and F that can be referenced as a pair using the name AF?
Maybe I'm wrong, but the only processors that have an AF register are Z80 and derivatives. In the 8080 and derivatives, the register pairs are known by the name of the MSB register (e.g. "inx d" compared to "inc de" on z80) and the pair of A and F is called PSW.
But, even if I was wrong in assuming you meant Z80, and this was a complete coincidence, then what of it? It doesn't change the fundamental point I was making - that these are two independent 8-bit registers that are occasionally exposed as one 16-bit register, compared to the x64 AL,AH,AX,EAX,RAX that are essentially 64-bit registers with smaller views into a subset of the register.
The rest of my post wasn't going off on a tangent either - the point I was making is that how the registers are split up and presented to the user isn't very useful, as it's far more interesting to know how many bits of total state there are in a processor, as exposed per-thread, per-core and per-chip.
by a piece of data, you presumably mean a block of untyped memory? i would suggest that is not how most people view a union, and that your union has either one or two members, depending on how it is used.
Correct, there is one contiguous block of memory that can be interfaced in multiple manners. It is still the same block of data, in much the way EAX is just a portion of RAX; not an independent register.
Besides the fact that now all AMD Zen 4 CPUs have AVX-512, there is one mistake in the text.
It is claimed that the only MSR (model-specific register) that can be read by non-privileged code is the TSC (time-stamp counter). This is wrong. Since Pentium Pro (1995), there is also the non-privileged instruction RDPMC (Read Performance-Monitoring Counters) which reads any of the MSRs that are performance counters, i.e. which are used for benchmarks or for profiling the code.
Moreover, the instruction RDTSCP, already mentioned there (introduced initially in an AMD Opteron family), reads not only the TSC, but also a second MSR, which normally contains a number that identifies the hardware core/thread on which the code is run. This other MSR can also be read separately with the non-privileged instruction RDPID (Read Processor ID).
Recent CPUs may also provide non-privileged access to a few other MSRs, e.g. with RDFSBASE/RDGSBASE (Read FS/GS Segment Base), WRFSBASE/WRGSBASE (Write FS/GS Segment Base), RDPKRU (Read Protection Key Rights for User Pages), WRPKRU (Write Data to User Page Key Register) and others.
“In all modes except for long mode, each segment register holds a selector, which indexes into either the GDT or LDT. That yields a segment descriptor which, among other things, supplies the base address and extent of the segment.”
A tad inaccurate. In 16-bit real mode the segment registers are used directly in the addressing scheme by specifying the 64kb segment (16-byte aligned) that we’re working in.
Or, to get more specific, how many pieces of data are there in this union:
Most would say one, with multiple interfaces. It might be "controversial" to some that consider each field independent, but I'd wager that they're a rare exception.