mov qword ptr ds:[rax+18], r8
在上面的代码中,我们将r8寄存器的值复制到哪里?
我知道这ds
意味着数据段是内存中的一个段,但究竟是什么[rax+18]
意思?
更具体地说,这些是我无法理解的部分:
rax
在这种情况下必须持有地址吗?- 的作用是
18
什么? - 我怎样才能追踪
[rax+18]
?
我知道这是新手的问题,但我就是其中之一。
mov qword ptr ds:[rax+18], r8
在上面的代码中,我们将r8寄存器的值复制到哪里?
我知道这ds
意味着数据段是内存中的一个段,但究竟是什么[rax+18]
意思?
更具体地说,这些是我无法理解的部分:
rax
在这种情况下必须持有地址吗?18
什么?[rax+18]
?我知道这是新手的问题,但我就是其中之一。
让我们逐条查看指令:
mov
qword ptr ds:[rax+18],r8
这是指令的操作码部分。它描述了 CPU 需要执行的基本操作。mov
是指示 CPU 将数据从第二个操作数复制到第一个操作数的操作码。mov
指令的第一个操作数是目标操作数,第二个是源操作数。
mov
qword ptr
ds:[rax+18],r8
第二个操作数是这条指令中最复杂的部分,所以我将它分成了几部分,我将逐一介绍。
这部分是第一个操作数的第一部分。操作数是执行操作的地址或寄存器等对象。qword
表示这个操作数描述了一个四字大小的地址,在英特尔的 x86 系列处理器中,这意味着 8 个字节(一个字长 2 个字节)。ptr
指示操作数的值应被视为地址。
在我们的例子中,这意味着将第二个操作数中的值分配给从第一个操作数的剩余部分 ( ds:[rax+18]
)指向的地址开始的 8 个字节。
mov qword ptr
ds:
[rax+18],r8
冒号是可选的,如果存在,它跟在访问数据地址时使用的段寄存器之后。这称为内存分段。段寄存器首先被创建以允许访问比 16 位处理器中寄存器大小更宽的内存地址,并且在实模式之外的 32 位和 64 位处理器中变得冗余,这是大多数 CPU 在切换到受保护之前开始的模式-模式(32 位)或长模式(64 位)。
除了特定含义的特殊段寄存器(例如fs
在 32 位窗口中,以及gs
在 Linux 和 64 位窗口中),如果不是在 16 位模式下运行,则可以广泛忽略。
mov qword ptr ds:
[rax+18]
,r8
括号与前面讨论的ptr
关键字耦合,用于在执行操作之前突出显示正在取消引用的地址。括号内的所有值应加在一起以计算目标地址。
在我们的例子中,这意味着rax
+ 18。这意味着rax
可能指向一个结构、一个类、一个数组或其他一些复杂的内存对象,我们正在访问该内存结构偏移 18 处的成员。由于没有任何前缀或后缀表示数字的基数,我假设它是十六进制的。
这意味着rax
可能是一个 qwords 数组,并且该指令正在访问该数组的第四个(索引 3)元素(因为 18h=24=8*3)。
rax
可以是四个 qwords 的结构,例如定义如下的三维时间点:
struct _point
{
long x;
long y;
long z;
long t;
};
可能正在访问该t
成员。
重要的是要注意,出于某些优化原因(我不会在这里深入探讨),rax
不一定指向结构的开头,并且可能已经指向结构内的偏移量,而是将 18 添加到该偏移量。
mov qword ptr ds:[rax+18]
,
r8
逗号只是操作数分隔符,表示第一个操作数已结束,第二个操作数即将开始。
mov qword ptr ds:[rax+18],
r8
与第一个操作数相比,第二个操作数是小菜一碟。这只是意味着当前寄存器r8
中的值是源值,以及将分配给地址的值rax+18
。