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


在上面的代码中,我们将r8寄存器的值复制到哪里?确切地说,ds是什么意思?

更具体地说,这些是我难以理解的部分:


[rax+18]必须在此类地址中保留地址情况如何?
rax的作用是什么?
我如何跟踪18

我知道这是新手的问题,但我是一个问题。

评论

我想知道,这是您在短时间内遇到的第二个“此代码有什么作用”问题,您试图做什么以理解该代码?英特尔的体系结构手册非常有帮助(尽管起初有点让人不知所措),我建议在这里问一下之前先看一下。第二卷包括指令集参考。

@ tmr232如果您注意到此问题是在询问与前一个问题不同的概念。确实,我有一份intel的《体系结构手册》,但它并不能完全回答我的问题。它甚至严格地解释了说明。如果您查看我以前的问题答案,它仅会解释我已经知道的qword,ds,mov,但我很难回答上述确切问题。

这基本上是mov [rax + 18],r8,其中:1)取rax持有的值,2)向其添加18,3)将r8的值写入该地址。

@FreeMind rax可能指向一个结构。在这种情况下,[rax + 18]是结构成员的地址。编译器无法直接寻址,因为在编译时未知其地址。

如果您认为该解决方案有效(就像我一样),那么@FreeMind接受该解决方案

#1 楼

让我们逐条查看该指令:

mov

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

这是指令的操作码部分。它描述了CPU需要执行的基本操作。 mov是一个操作码,指示CPU将数据从第二个操作数复制到第一个操作数。 mov指令上的第一个操作数是目标操作数,第二个是源操作数。

qword ptr

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

这第二个操作数是此指令中最复杂的部分,因此我将其拆分为几部分,将逐一进行介绍。

这部分是第一个操作数的第一部分。操作数是在其上执行操作的对象,例如地址或寄存器。 qword表示此操作数描述的是四字大小的地址,在Intel的x86处理器系列中,这意味着8个字节(一个字长2个字节)。 ptr表示应将操作数的值视为地址。

在我们的例子中,这意味着将第二个操作数的值分配给8个字节,该8个字节从剩余的指针指向的地址开始第一个操作数(ds:[rax+18])。

ds:

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

冒号是可选的,如果存在,它将跟随段寄存器使用访问数据地址时。这称为内存分段。段寄存器的创建首先是为了允许访问比16位处理器中的寄存器大的内存地址,并在实模式之外的32位和64位处理器中变得冗余,这是大多数CPU切换到保护模式之前的模式。模式(32位)或长模式(64位)。

除了特殊含义的特殊段寄存器(例如32位窗口中的fs以及Linux和64位窗口中的gs)之外,这可以如果未在16位模式下运行,则将被广泛忽略。

[rax + 18]

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

方括号与前面讨论的ptr关键字结合使用,用于突出显示在执行操作之前已取消引用地址。应该将方括号内的所有值加在一起以计算目标地址。在我们的示例中,这意味着rax +18。这意味着rax可能指向结构,类,数组或其他一些对象。复杂的内存对象,我们正在访问该内存结构的偏移量18处的成员。由于没有任何前缀或后缀表示数字的基数,因此我假定它以十六进制表示。

这意味着rax可以是qword的数组,并且此指令正在访问第四个(索引3) )的元素(因为18h = 24 = 8 * 3)。

rax可以是四个qword的结构,例如定义为以下时间点的三维时间点:

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


可能正在访问t成员。

请注意,出于某些优化的原因(我将不在此处讨论),rax不一定指向结构的开始,并且可能已经指向结构内的偏移量,而是向该偏移量添加18。

,(逗号)

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

逗号只是简单的操作数分隔符,表示第一个操作数已经结束,第二个操作数即将开始。

r8

br />
相比第一个o佩兰,第二个是小菜一碟。这仅表示当前在寄存器mov qword ptr ds:[rax+18],中的值是源值,并将分配给地址r8

评论


如果rax指向由8个字节大小的元素组成的数组的开头,rax + 0x18不会指向第四个元素,而不是第三个元素吗? rax指向第一个元素,因此偏移3得出4。

– Andrey Portnoy
19-3-28在20:13



@AndreyPortnoy看起来您是对的。感谢您发现我的错误!我编辑了答案

– NirIzr
19年5月2日在8:30