3

I'm reading "Hacking: The Art of Exploitation".

In the book the registers are different from the registers that I can see on my pc. These are my cpu registers:

rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8, r9, r10, r11, r12, r13, r14, r15, rip, eflags, cs, ss, ds, es, fs, gs

while in the book the registers are:

eax, ecx, edx, ebx, esp, ebp, esi, edi, eip, eflags, cs, ss, ds, es, fs, gs

Can someone explain why they are different? I'm running on an AMD cpu; does AMD have different CPU registers from Intel?

In this case can someone explain me the correspondence between the registers of the two architecture?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Invictus
  • 426
  • 3
  • 13
  • 4
    The first set are the 64 bit registers. The second are the 32 bit, which is a subset. You can usually run 32 bit code on a 64 bit processor, just make sure you create a 32 bit program. – Jester Jul 07 '17 at 13:41
  • ah finally!! And so in which way can I understand the correspondence? @Jester – Invictus Jul 07 '17 at 13:42
  • The `e` registers are the low 32 bits of the `r` registers. – Jester Jul 07 '17 at 13:43
  • ah ok so the e prefix is for 32bit and r prefix for 64bit? @Jester – Invictus Jul 07 '17 at 13:45
  • @francescopioGaglione Exactly. Note that you can use the e prefix on amd64, too. This refers to the lower 32 bit of the corresponding 64 bit register. – fuz Jul 07 '17 at 13:48
  • Ah Great, thanks a lot!!! I'll try very soon – Invictus Jul 07 '17 at 13:54
  • 2
    Not a perfect duplicate of the linked question, but the answer works perfectly for this. It even has diagram showing how the low half of RAX is called EAX, etc. etc. – Peter Cordes Jul 08 '17 at 03:56

1 Answers1

11

The registers starting with r as in rax, rbx, etc, are the 64-bit registers introduced with the AMD64 extension to the existing 32-bit x86 ISA. That ISA extension was subsequently adopted by Intel and is often known by the more neutral name x86-64. Essentially all x86 chips released in the last decade from AMD and Intel support this ISA.

Registers like eax, ebx, etc are the 32-bit registers which exist both in the original 32-bit x86 ISA, as well as the 64-bit x86-64. If your book refers only to those registers, it is likely that it doesn't cover the 64-bit extension (perhaps it was written before it).

Note that the 32-bit and the 64-bit registers are not separate registers since they overlap: the 64-bit rax, for example, has eax as its bottom 32-bits, and so on for rbx and ebx, r8 and r8d and so on. Therefore, modifications to a 32-bit register are reflected in the corresponding 64-bit register, and vice versa.

A similar relationship exists among the 16-bit (ax, etc) and 8-bit (al, etc) registers. You can find all the gory details in many places.

BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
  • What did you have in mind with that footnote? `or rax, rbx` where the low half of `rbx` is all-zero? That writes all of `rax` with a value that happens to be the same as what was there before. – Peter Cordes Jul 09 '17 at 12:51
  • Just pointing out that the while changing any bit in a 32-bit register always changes the corresponding 64-bit register (indeed even changing 0 bits usually changes the 64-bit reg due to upper-bit zeroing), the "vice-versa" doesn't apply in the case that only the upper bits of a 64-bit reg were changed. @PeterCordes – BeeOnRope Jul 10 '17 at 05:55
  • But there's no way to modify only the upper bits except with a read-modify-write of the whole 64-bit register like my `or` example. If you allow that to count, then `or rax, 0x1234` modifies only `eax` half, leaving the upper half of `rax` unchanged... There's nothing like `mov eax, ebx` that modifies only upper half of RAX the way `mov ah, 1` modifies the upper half of AX. I'm arguing that you should delete the footnote, because it's more confusing than helpful. Some may think it implies that there is a way to write (without RMW) to the upper half of a register. – Peter Cordes Jul 10 '17 at 10:46
  • Yes, by "modify a bit" I mean that the bit changed from 1 to 0 or 0 to 1 with the actual arguments, i.e., it's about the actual change for some execution of the instruction, not what the instruction is capable of across all invocations. So a change to a 32-bit register _always_ produces a change in the corresponding 64-bit register, but the reverse isn't true when only the top bits of a 64-bit registers are modified (even though there aren't dedicated instructions that do that). @PeterCordes – BeeOnRope Jul 10 '17 at 16:22
  • The existing text is not wrong even for that special case. A `mov rax, rbx` is reflected in `eax` even if `ebx == eax`. My main objection is that it might make beginners look for a general-purpose way to write the top half of a 64-bit register, but also that thinking about this special case doesn't add any new insight. update: just saw your edit. That's an improvement, and a lot less confusing, but still a distraction. – Peter Cordes Jul 10 '17 at 16:34
  • Yes, of course, in some sense all operations on a 64-bit registers are _reflected_ in the corresponding 32-bit register, depending on the semantics of _reflected_. One could also argue, however, that as a practical matter an instruction like `btc rax, 50` is never _reflected_ in the lower 32-bits. There is no corresponding case for the reverse direction (modifications of a 32-bit register). Certainly I'm not claiming it adds any insight - it's just an obvious implication of the way the registers overlap. @PeterCordes – BeeOnRope Jul 10 '17 at 16:56
  • @PeterCordes I just deleted the footnote – BeeOnRope Jul 12 '17 at 22:18
  • Victory is mine! :P The previous update had already made it a lot less confusing, though. – Peter Cordes Jul 12 '17 at 22:21
  • 1
    I concede nothing :) ... but for sure you were right that the note had a negative impact to a typical reader's understanding and that the existing text isn't wrong. The footnote was pendantic without adding anything. @PeterCordes – BeeOnRope Jul 12 '17 at 22:22