29
mov qword ptr ds:[rax+18], r8

In the above code, where are we copying the value of r8 register into?

I know that ds means data segment which is a segment in memory, but what does exactly [rax+18] mean?

More specifically, these are the parts I'm having trouble with understanding:

  1. Is it mandatory that rax should hold an address in such situation?
  2. what is the role of 18?
  3. How can I trace the [rax+18]?

I know it is newbie's question but I am one.

6
  • 5
    As this is your second "what does this code do" question in a short time I am wondering, what have you tried to do to understand the code? Intel's Architecture Manuals are quite helpful (though a bit overwhelming at first), and I suggest having a look there before asking here. The second volume include the instruction set reference.
    – tmr232
    Aug 29, 2015 at 20:30
  • @tmr232 If you notice this question is asking a different concept from the former one. Indeed, I have got a copy of intel's Architecture manual but it does not exactly answer my question. It even explains the instructions in the strict way. If you check out my former question answer it just explains qword, ds, mov which I already know but I have difficulty with the exact questions asked above.
    – FreeMind
    Aug 29, 2015 at 20:39
  • 1
    This is basically mov [rax + 18], r8, which: 1) takes the value that rax holds, 2) adds 18 to it, 3) writes the value of r8 to that address.
    – rev
    Aug 29, 2015 at 21:16
  • 4
    @FreeMind rax may point to a structure. In that case [rax+18] is the address of a member of the structure. A compiler cannot address directly because it's address is not known at compile time.
    – 0xec
    Aug 30, 2015 at 4:16
  • 1
    @FreeMind accept the solution if you think it is valid (as I do) Jun 11, 2018 at 13:22

1 Answer 1

52

Lets go over the instruction piece by piece:

mov

movqword ptr ds:[rax+18],r8

This is the opcode part of the instruction. It describes the base operation the CPU is required to perform. mov is an opcode instructing a CPU to copy data from the second operand to the first operand. The first operand on the mov instruction is a target operand, and the second is the source.

qword ptr

movqword ptrds:[rax+18],r8

This second operand is the most complex part of this instruction, so I've split it to several pieces and I'll go over each individually.

This part is the first part of the first operand. Operands are objects such as addresses or registers on which operations are performed. qword indicates this operand describes an address of quad-word size, in Intel's x86 family of processors this means 8 bytes (a word is 2 bytes long). ptr indicates the value of the operand should be treated as an address.

In our case, this means assigning the value in the second operand to the 8 bytes starting at the address pointed to by the remaining of the first operand (ds:[rax+18]).

ds:

mov qword ptrds:[rax+18],r8

The colon is optional, and if present it follows the segment register to use when accessing data addresses. This is called memory segmentation. Segment registers were first created to allow accessing memory addresses wider than the size of registers in 16bit processors and became redundant in 32 and 64-bit processors outside of real-mode, which is the mode most CPUs start at before they're switched to protected-mode (32bit) or long-mode (64bit).

Except for specific-meaning special segment registers (such as fs in 32bit windows, and gs in Linux and 64-bit windows), this can be widely ignored if not operating in 16bit modes.

[rax+18]

mov qword ptr ds:[rax+18],r8

The brackets are coupled with the previously discussed ptr keyword and are used to highlight the address is being dereferenced before the operation is performed. All values inside the brackets should be added together to calculate the target address.

In our case, this means rax + 18. This means rax probably points to a structure, a class, an array or some other complex memory object, and we're accessing the member at offset 18 of that memory structure. As there isn't any prefix or postfix indicating the number's base, I'll assume it's in hex.

This means rax could be an array of qwords, and this instruction is accessing the forth (index 3) element of that array (since 18h=24=8*3).

rax could be a structure of four qwords, such as a three-dimensional point in time defined as the following:

struct _point
{
    long x;
    long y;
    long z;
    long t;
};

probably accessing the t member.

It is important to note that for certain optimization reasons (into which I won't dive here), rax is not necessarily pointing the beginning of a structure, and could be already pointing to an offset within the structure, adding 18 to that offset instead.

, (comma)

mov qword ptr ds:[rax+18],r8

Commas are simply operand separators, indicating the first operand has ended and the second is about to begin.

r8

mov qword ptr ds:[rax+18],r8

Compared to the first operand, the second one is a piece of cake. This simply means the value currently in register r8 is the source value, and what will be assigned to the address rax+18.

4
  • 2
    If rax is pointing at the beginning of an array of 8 byte sized elements, wouldn't rax + 0x18 point at the fourth, not the third element? rax is pointing at the first element, so offsetting by 3 gives 4. Mar 28, 2019 at 20:13
  • 2
    @AndreyPortnoy Looks like you're right. Thanks for catching my mistake! I edited my answer
    – NirIzr
    May 2, 2019 at 8:30
  • 1
    This answer makes the world a better place to live, in some sense...
    – gonidelis
    Apr 9, 2021 at 11:17
  • @gonidelis haha! <3
    – NirIzr
    Apr 9, 2021 at 17:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.