0

Let's suppose I wanna store the following 64-bit number in the RAX register, what is the byte order in the register?

10011111 10100000 11011111 00000001 00001111 00100110 00100110 11101000

RAX = full number; EAX = 00001111 00100110 00100110 11101000; AX = 00100110 11101000; AH = 00100110; AL = 11101000.

Is the least significant byte to be stored in AL ?

Is the order dependent by little endian or big endian, or is Always the same for registers storage ?

Are these the correct outputs in this case? AL = 232; AH = 38; AX = 9960; EAX = 254158568; RAX = 11502438643946366696

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Antonio
  • 13
  • 5

1 Answers1

1

Your outputs look correct (except that I didn't bother to calculate anything above AL and AH).

The big/little endianness normally applies to addressable memory only, for a register it's kind of make little sense (unless you stretch the definition of endianness a bit, the way you just did - but mind you this ability to access parts of a register by using different register names/instructions is very x86/x64 specific).

IMHO, it is more correct to use the term Bit Numbering here and the definitions of AL,AH etc. from x86 reference documentation.

On the other hand, when RAX is saved into memory AL will be in the byte with the lowest address...

tum_
  • 632
  • 1
  • 7
  • 16
  • Thank you for the answer. So: AL = 1byte(first) AH = 2byte(second) EAX = 1 byte + 2 byte +3byte + 4 byte RAX = 1 byte + 2byte + 3byte + 4byte + 5byte + 6byte + 7 byte + 8 byte ? – Antonio Apr 16 '19 at 16:07
  • Yes. This is all covered on the Net in detail and even in [pictures](https://denhamcoder.net/2018/07/24/x86-x64-registers/) :) Grab the image while the link stays valid. – tum_ Apr 16 '19 at 16:26
  • So in this sense is correct to say that the least significant byte goes in AL ? Always considering my exemple above, the value of AL should be Always 11101000 regardless of whether we'r using a little endian machine or big endian machine, or it will become 10011111 in the case of a big endian machine ? – Antonio Apr 16 '19 at 16:41
  • In other words the thing I cannot understand is: In a Big endian machine AL is 11101000 or 10011111, considering the exemple above ? – Antonio Apr 16 '19 at 16:48
  • I see your confusion... The registers you've used in your question belong to (Intel's) x64 architecture. And it is by definition little-endian. On a big-endian machine (you can find examples in Wiki) your 10011111 byte would be stored in the lowest address when the register's content is saved into memory and the least significant byte 11101000 would be at the highest address but it would hardly be called AL - other machines have other names for CPU registers. – tum_ Apr 16 '19 at 17:14
  • ok, thanks for the help; in any case I cannot express my doubt well. AL represents the lowest 8 bits of the register, and in the example above we have seen to be 11101000. If the machine was big endian, what value would I have in the lower 8 bits of a register(with another name, no AL) ? – Antonio Apr 16 '19 at 17:39
  • The same. Endianness does not apply to register's content. The least significant bits remain the least significant. It's simply a binary number after all. Endianness comes into play when you store this number in RAM (because each byte in memory has an individual address) and when you send you value via a serial link byte by byte - because the receiver must know in what order bytes come. – tum_ Apr 16 '19 at 17:49
  • ok so the least significant byte of a number goes always in the lowest 8-bits of the register regardless of machine ? – Antonio Apr 16 '19 at 17:59
  • .. this is why I keep adding "when the register's content is saved into memory" all the time. Parts of a register do not have adresses, all you have is bit numbers 64..0 but I can see how intel's backward compatibility related "mess" with register names confuses you :) – tum_ Apr 16 '19 at 17:59
  • It is represented by bits[7..0] of the register, yes. Regardless of the endianness of the machine. – tum_ Apr 16 '19 at 18:03
  • Made a mistake in pre-previous comment 64..0 should be 63..0 – tum_ Apr 16 '19 at 18:05
  • you are helping me so much. – Antonio Apr 16 '19 at 18:17
  • :) the way to thank on this resource is to mark the answer as accepted. Good luck, confusion will disappear with practice. – tum_ Apr 16 '19 at 18:19
  • so i can image a register like a number in bits, not like real memory. And eax, ax ecc... just refers to a part of this number ? – Antonio Apr 16 '19 at 18:19
  • That's what it is - a chunk of bits of a fixed size. And eax, ax etc are the remnants of the past - Intel decided to keep the backward compatibility and still allow to execute the code wrtten for 8086, which uses AX, AH, AL. Look at any RISC arch, like ARM - they don't have this naming rubbish, R0 is a 32bit register and this is it. But when you read/write R0 to/from memory - you have to consider the endianness, as usual. – tum_ Apr 16 '19 at 18:31
  • Partial registers that alias onto wider registers is a thing for ARM 32-bit NEON registers (SIMD): 128-bit `q0` = `d1:d0`, and 64-bit `d0` = `s1:s0`. So you can access each of the 4x 32-bit words of `q0` as `s0`,`s1`,`s2`, or `s3`, enabling some horizontal operations. (`d16..31` don't have their halves exposed this way, but only `q0..q15` exist at all so their halves are exposed.) You're right that it's unusual, though; AArch64 dropped that, having q5 = d5 = s5 and introducing new instructions to index into elements of vector regs. – Peter Cordes Apr 17 '19 at 02:27