2

So, let's say I'm working with the registers %rax and %rdi.

As a basic example, let's say %rax is equivalent to 0xaaaaaaaaaaaaaaaa and %rdi is equivalent to 0xbbbbccccddddeeff.

Something simple like movq %rdi, %rax is simple enough to me. We simply move the value in %rdi into %rax.

So, say we have the following:

movq %rdi, %rax
movb %dil, %al

The first instruction would have %rax equal 0xbbbbccccddddeeff.

But I'm not sure how I would determine the value of %rax after the second instruction is implemented due to the fact that we are using the 8-bit versions of %rdi and %rax.

I'm very new to assembly language and there are quite a few things I'm pretty confused about. I've been doing a lot of research and studying up on it, but I'm still pretty lost, so I thought asking a clarifying question here would help me out. Any explanation on how to approach this would be greatly appreciated!

larn
  • 398
  • 2
  • 16

1 Answers1

2

The second instruction movb %dil, %al only replaces the lowest 8-bits of %rax. The rest stays as it is.

So %rax would be 0xbbbbccccddddeeff, because the lowest 8-bits would be copied two times.

Without the first instruction movq %rdi, %rax - which copies the whole register to %rax - only the lowest 8-bits would be replaced and the value of %rax would have been 0xaaaaaaaaaaaaaaff.

zx485
  • 28,498
  • 28
  • 50
  • 59
  • Awesome, thank you! It was very helpful for you to explain it in the absence of the first instruction as well. – larn Feb 23 '20 at 22:25
  • Although, how would this work if I wasn't using two 8-bit registers? For example, if I did ```movzbw %dil, %ax```. What's the correct thing to do for an 8-bit and 16-bit register instruction like htis? – larn Feb 23 '20 at 22:29
  • 2
    It's nothing special. In the case of `movzbw %dil, %ax` the 8-bit value of `%dil` will be zero extended to the unsigned 16-bit value of `%ax` - and written to it (the lowest 16-bit of `%rax`). So the lowest 16 bits of `%rax` would be overwritten. – zx485 Feb 23 '20 at 23:21
  • 3
    @larn: Watch out, however, that 32-bit instructions are different. `movl %edi, %eax` will copy the low 32 bits and **zero** the upper 32 bits. See https://stackoverflow.com/questions/11177137/why-do-x86-64-instructions-on-32-bit-registers-zero-the-upper-part-of-the-full-6 – Nate Eldredge Feb 23 '20 at 23:24
  • @zx485 I'm a little confused about the language of assembly at the moment, considering I'm such a newbie. What would the hex value be of %rax after performing such an instruction? I don't think I'm interpreting your words correctly at all. Having a value to look at will definitely help me put the pieces together – larn Feb 23 '20 at 23:36
  • With your given two instructions, the value of `%rax` would be `0xbbbbccccdddd00ff` (zero extending 0xFF to 0x00FF). – zx485 Feb 23 '20 at 23:39
  • 2
    @larn: You can and should single step code in a debugger and watch register values change. If you're ever not sure about something, just try it yourself. Just put these two instructions at the top of `_start:` or `main:` and assemble into an executable that you run GDB on. – Peter Cordes Feb 24 '20 at 08:09