My understanding of x86 registers say that each register can be accessed by the entire 32 bit code and it is broken into multiple accessible registers.
In this example EAX
being a 32 bit register, if we call AX
it should return the first 16 bits, and if we call AH
or AL
it should return the next 8 bits after the 16 bits and AL
should return the last 8 bits.
So my question, because I don't truly believe is this is how it operates. If we store the 32 bit value aka EAX
storing:
0000 0100 0000 1000 0110 0000 0000 0111
So if we access AX
it should return
0000 0100 0000 1000
if we read AH
it should return
0000 0100
and when we read AL
it should return
0000 0111
Is this correct? and if it is what value does AH
truly hold?
In this example EAX being a 32 bit register, if we call AX it should return the first 16 bits, and if we call AH or AL it should return the next 8 bits after the 16 bits and AL should return the last 8 bits.
ax is the 16-bit, "short" size register. It was added in 1979 with the 8086 CPU, but is used in DOS or BIOS code to this day. al and ah are the 8-bit, "char" size registers. al is the low 8 bits, ah is the high 8 bits.
It stands for a general purpose register. The 16 bit AX register can be addressed as AH (high byte) and AL (low byte). The EAX register is the 32 bit version of the AX register. The E stands for extended. Copy link CC BY-SA 2.5.
No, that's not quite right.
EAX is the full 32-bit value AX is the lower 16-bits AL is the lower 8 bits AH is the bits 8 through 15 (zero-based)
So AX is composed of AH:AL halves, and is itself the low half of EAX. (The upper half of EAX isn't directly accessible as a 16-bit register; you can shift or rotate EAX if you want to get at it.)
For completeness, in addition to the above, which was based on a 32-bit CPU, 64-bit Intel/AMD CPUs have
RAX, which hold a 64-bit value, and where EAX is mapped to the lower 32 bits.
All of this also applies to EBX/RBX, ECX/RCX, and EDX/RDX. The other registers like EDI/RDI have a DI low 16-bit partial register, but no high-8 part, and the low-8 DIL is only accessible in 64-bit mode: Assembly registers in 64-bit architecture
Writing AL, AH, or AX leaves other bytes unmodified in the full AX/EAX/RAX, for historical reasons. i.e. it has to merge a new AL into the full RAX, for example. (In 32 or 64-bit code, prefer a movzx eax, byte [mem]
or movzx eax, word [mem]
load if you don't specifically want this merging: Why doesn't GCC use partial registers?)
Writing EAX zero-extends into RAX. (Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?)
Again, all of this applies to every register, not just RAX. e.g. writing DI or DIL merges into the old RDI, writing EDI zero-extends and overwrites the full RDI. Same for R10B or R10W writes merging, writing R10D leaving R10 independent of the old R10 value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With