68

Where can I find the names of the new registers for assembly on this architecture?

I am referring to registers in X86 like EAX, ESP, EBX, etc. But I'd like them in 64bit.

I don't think they are the same as when I disassemble my C code, I get r's instead of e's.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Recursion
  • 2,915
  • 8
  • 38
  • 51
  • Guys How can I tell what registers correlate to parameters when doing a system call. Ive been reading and documentation and haven't found a clear answer. – Recursion Nov 20 '09 at 03:49
  • Note that the old upper 8 bits registers (ah, bh etc) no longer work for all opcodes. e.g. `inc ah` is not valid in x64 because that opcode has been reused for one of the new 64bit registers. – Johan Sep 26 '13 at 22:55
  • 1
    @Johan: also note that with the REX prefix, the register codes for ah bh ch dh becomes the new byte registers sil dil bpl spl – phuclv Oct 03 '13 at 07:43

4 Answers4

112

The MSDN documentation includes information about the x64 registers.

x64 extends x64's 8 general-purpose registers to be 64-bit, and adds 8 new 64-bit registers. The 64-bit registers have names beginning with "r", so for example the 64-bit extension of eax is called rax. The new registers are named r8 through r15.

The lower 32 bits, 16 bits, and 8 bits of each register are directly addressable in operands. This includes registers, like esi, whose lower 8 bits were not previously addressable. The following table specifies the assembly-language names for the lower portions of 64-bit registers.

64-bit register | Lower 32 bits | Lower 16 bits | Lower 8 bits
==============================================================
rax             | eax           | ax            | al
rbx             | ebx           | bx            | bl
rcx             | ecx           | cx            | cl
rdx             | edx           | dx            | dl
rsi             | esi           | si            | sil
rdi             | edi           | di            | dil
rbp             | ebp           | bp            | bpl
rsp             | esp           | sp            | spl
r8              | r8d           | r8w           | r8b
r9              | r9d           | r9w           | r9b
r10             | r10d          | r10w          | r10b
r11             | r11d          | r11w          | r11b
r12             | r12d          | r12w          | r12b
r13             | r13d          | r13w          | r13b
r14             | r14d          | r14w          | r14b
r15             | r15d          | r15w          | r15b
Mr. Llama
  • 20,202
  • 2
  • 62
  • 115
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • This is clear, but the lower 8 bits mode seems invalid for `r8` ~ `r15` on my intel x86-64 cpu, though it works for the other 8 general purpose registers. Also `rax` ~ `rdx` support to access the 8 bits in `high` mode, means access the most significant 8 bits of the 16 bit mode, using `ah` ~ `dh` . – Eric Jun 01 '16 at 04:28
  • @EricWang: Did you try to use `mov ah, r8b` or something? You can't use a high-8 register with a REX prefix. `REX mov ah, 0` is `mov spl, 0`, and so on (the encodings for `AH/CH/DH/BH` mean `spl/bpl/sil/dil` when there's a REX prefix (in that order in machine code) – Peter Cordes Nov 23 '17 at 11:50
  • 1
    Note that the low 8-bit register is called `l` instead of `b` on some manuals, for example `r8l` vs `r8b`. See [Why does Apple use R8l for the byte registers instead of R8b?](https://stackoverflow.com/q/43991779/995714) – phuclv May 11 '19 at 03:43
  • The new [APX](https://en.wikipedia.org/wiki/Advanced_Performance_Extensions) [extension](https://www.intel.com/content/www/us/en/developer/articles/technical/advanced-performance-extensions-apx.html) now adds 16 more registers: r16 to r31 – phuclv Aug 03 '23 at 17:40
90

The old 32-bit registers have been extended to 64 bits, the r registers (rax, rbx, rsp and so on).

In addition, there's some extra general purpose registers r8 through r15 which can also be accessed as (for example) r8d, r8w and r8b (the lower 32-bit double-word, 16-bit word and 8-bit byte respectively). The b suffix is the original AMD nomenclature but you'll sometimes see it written as l (lower case L) for "low byte".

I tend to prefer the b suffix myself (even though the current low-byte registers are al, bl, and so on) since it matches the d/w = double/word names and l could potentially be mistaken for long. Or, worse, the digit 1, leading you to question what the heck register number 81 is :-)

The high bytes of the old 16-bit registers are still accessible, under many circumstances, as ah, bh, and so on (though this appears to not be the case for the new r8 through r15 registers). There are some new instruction encodings, specifically those using the REX prefix, that can not access those original high bytes, but others are still free to use them.

In addition, there's some new SSE registers, xmm8 though xmm15.

The eip and eflags registers have also been extended to rip and rflags(though the high 32 bits of rflags are, for now, still unused).

See the wikipedia page and MSDN for more details.

Whether these are supported in the asm keyword for a particular C compiler, I couldn't say. What little assembly I do (and it's becoming about one day a year) is done in assembly rather than C.


Related:

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • what's standing "R" for ? –  Oct 09 '14 at 11:21
  • 31
    @int80, no idea. Perhaps `e` means extended and `r` means _really_ extended :-) – paxdiablo Oct 09 '14 at 11:43
  • 1
    i know that "e" stands for extended (from 16bit). but r? but your answer is just logic %) –  Oct 09 '14 at 13:40
  • 1
    This is not correct. When using the `REX` prefix you cannot use the upper halves (`ah`, `bh`, `ch`, `dh`) because they are mapped to the lower halves of other registers (`si`, `bp`, `sp`, `di` respectively). This means that if you have an address stored in `r8` you cannot move the contents of `ah` to this address. – Fotis Dec 28 '14 at 19:36
  • 2
    @Fotis, which bit is "not correct" exactly? If you're referring to the x86-64 inability to access upper halves (ah, etc) in instructions with the REX prefix, that's a limitation I didn't even cover, though I'll add a short note. That just means _some_ instructions cannot access those upper halves, it doesn't mean the registers don't exist or that you can't use them at all. And, just to clarify, the registers themselves aren't mapped, it's the instruction encodings - if you change `sil`, that doesn't affect the `ah` content going forward. – paxdiablo Dec 28 '14 at 23:54
  • @paxdiablo You stated that the upper halves are still accessible, which is not correct and I gave you an example. They are still accessible _some times_. – Fotis Dec 29 '14 at 09:00
  • @paxdiablo I forgot to add some things about the instruction encodings. Of course the instruction encodings are mapped, the correct terminology for what you're talking about is _aliasing_ (for example see https://software.intel.com/en-us/articles/introduction-to-x64-assembly: _The eight 64-bit MMX registers MMX0-MMX7 are aliased on top of FPR0-7_). You should also change the part that says the problem is with some new instruction encodings. Old instruction encodings with the `REX` prefix have the same problem. Prefix != instruction encoding. – Fotis Dec 29 '14 at 09:16
  • Fotis, covering your points one by one. First, you state correctly they're not accessible under some circumstances and claim that my phrase "they're still accessible" is incorrect because of that. They _are_ still accessible under non-REX instructions and I think you may be read something into my answer stuff that I never said. In any case, I believe my edit clarified that. – paxdiablo Dec 29 '14 at 10:00
  • Second, what we're discussing is _not_ aliasing, that particular term refers to actual overlaying of registers whereas what we're discussing is simply an addressing limitation. If it was aliasing then changing an aliased register would affect its counterpart, not the case here. – paxdiablo Dec 29 '14 at 10:01
  • Finally, I suspect the "new instruction encoding" is just a semantic issue. Anything using REX _is_ a new encoding in my opinion even though it may be a prefix affecting current instructions. The "instruction" (or prefix/opcode pair if you prefer) `rep stos` has a vastly different effect to `stos` on its own. – paxdiablo Dec 29 '14 at 10:05
  • So, bottom line, I appreciate the input given that it's allowed me to improve the answer a fair bit already but I don't think it's necessary to modify it further. Unless I'm mistaken about the aliasing (I'm always happy to be proven wrong if it means answers become better) but I don't think that's the case here. – paxdiablo Dec 29 '14 at 10:07
  • @paxdiablo Your edit clarified that they are accessible _some times_. Second, what I said is that your correction (...if you change `sil` that doesn't affect `ah`...) on my comment does not apply, since I said mapping and not aliasing. Of course this is not aliasing and that's what I said at my first comment. Finally, I agree that the last part is just a semantic issue. `rep stos` has a vastly different effect to `stos`, but the `stos` instruction has exactly the same encoding in both cases, `rep stos` has just one more prefix. – Fotis Dec 29 '14 at 11:38
  • 8
    "r" stands for register, as in R8, R9, R10, etc. With respect to rax through rbp, the "r" is for consistency. – vy32 Mar 02 '15 at 16:39
  • The low-byte register suffix is `l` instead of `b` on some manuals, for example `r8l` vs `r8b`. See [Why does Apple use R8l for the byte registers instead of R8b?](https://stackoverflow.com/q/43991779/995714) – phuclv May 11 '19 at 03:44
  • Good info, @phuclv, I have added that to the answer. – paxdiablo May 12 '19 at 06:01
  • 1
    @paxdiablo: added some links to your answer that address the comment about what `r` and `x` stand for. The consensus is that it's just "Register", like on most RISC ISAs with orthogonal registers. – Peter Cordes May 12 '19 at 08:50
  • 1
    No probs, @Peter, just made some minor grammatical changes but appreciate the addition. – paxdiablo May 12 '19 at 10:07
9

X64 extends the 32-bit general purpose registers as follows:

EAX -> RAX
EBX -> RBX
ECX -> RCX
EDX -> RDX
ESI -> RSI
EDI -> RDI
ESP -> RSP
EBP -> RBP

X64 also adds the following 64-bit general purpose registers:

R8, R9, R10, R11, R12, R13, R14, R15

Additionally, SSE is part of the X64 specification, so the xmm0-xmm15 vector registers are available as well

You can find some basic info on the architecture at Wikipedia/X86-64 or go to Intel's website.

amesh
  • 1,311
  • 3
  • 21
  • 51
brainiac
  • 404
  • 2
  • 6
5

Let's read the Intel manual

Where can I find the names of the new registers for assembly on this architecture.

In the processor's manual "Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture", e.g. version 253665-053US:

  • search for "registers"
  • the first match is the index "3.4 BASIC PROGRAM EXECUTION REGISTER"
  • two items below "3.4.1.1 General-Purpose Registers in 64-Bit Mode"

On that section:

if a 64-bit operand size is specified: RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, R8-R15 are available. R8D-R 15D/R8-R15 represent eight new general-purpose registers.

Reminder: 64 bit mode is the "normal" mode in x86-64. The other main mode is "compatibility mode" which emulates IA32.

If you keep searching for "register" on the TOC, you will also find sections on "number crushing" registers for floating point and SIMD scattered in the manual:

  • 8.1.2 - x87 FPU Data Registers (STx)
  • 9.9.2 - MMX Registers
  • 10.2.2 - XMM Registers
  • 14.1.1 - 256-Bit Wide SIMD Register Support (YMM)

There are many more control registers which have various side effects and can generally not be written to unless you want those effects (and often require ring 0). These are summarized in "Volume 3 System Programming Guide - 2.1.6 System Registers", which is more for OS developers.

A good empirical approach is to run info all-registers in GDB: How to print register values in GDB?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985