2013-11-02 272 views
3

此汇编指令具体做什么?什么意思:在x86中是什么意思?

mov ax, es:[bx] 

:是做什么用的?

+0

[x86汇编的可能重复的 - 什么结肠装置? (GAS语法)](http://stackoverflow.com/questions/18736663/x86-assembly-what-the-colon-means-gas-syntax) –

回答

2

具体做什么:做什么?

“:”不会“做”任何事情,就像“。”一样。在大多数高级编程语言中都没有“做”任何事情。 ':'与<segment register> : <address expression>形式的指令一起使用。默认情况下,所有x86指令都有一个“默认段选择器”,用于确定指令的“存储器操作数”所指示的地址。这通常是“ds”或“ss”,具体取决于指令。指令可以指定CS,DS,ES,SS,FS和GS段寄存器中的任何一个,但是通过在指令二进制编码中指定适当的“指令前缀字节”。

在16位“实模式”程序中,段寄存器中的值用于确定存储器地址的“高位位”。它与指令中指定的存储器地址结合生成指令引用的实际地址。这允许在16位硬件上运行的程序能够访问大于16位的存储空间,只要它们可以将存储器分组成4k块,这些块可以相对于“段选择器”寄存器被访问。

在32位程序中,段选择器实际上是描述动态映射(包括偏移量和大小)的结构的索引。该地址是通过将索引结构中存在的信息与指令中存在的存储器操作数组合来计算的。

大多数情况下,在32位程序中,大多数段寄存器都指向指定整个32位地址空间的结构。主要的例外是“fs”寄存器,它指定映射到操作系统定义的特殊数据结构的偏移量和大小。它被用作内核空间和用户空间之间通信的机制之一。它通常包含对当前“进程或线程”的内核表示的所有“用户空间可见”属性的访问。

64位程序完全避开段寄存器。除FS和GS之外的所有段寄存器都被定义为无效,并且表现得好像映射了整个用户空间一样。 FS寄存器通常用于访问正在执行的程序的当前“32位上下文”。 “GS”寄存器通常用于提供对当前“64位上下文”的访问。这允许32位程序在64位系统上运行,但也使64位内核(以及32位过程和64位过程之间的映射层)能够访问它需要工作的64位上下文。

因此,要回答你原来的问题:

中概率(未给出关于处理器的模式或操作系统的知识),指令:

mov ax, es:[bx] 

实际上相当于:

mov ax, [bx] 

然而,它使用16位寄存器的事实表明它可能是一个实模式程序,在这种情况下它可能意味着:

mov ax, [<addr>] 

其中地址==(ES < < 4)+ [BX]

+0

两个指令'mov ax,es:[bx]'和'mov ax,[bx]'不等价,除非之前使用了'assume'命令。在这种情况下,默认寄存器是'ds'而不是'es',所以需要使用段,这就是'es:'所做的。 – Devolus

+0

大多数情况下,在32位程序中,es的偏移量为0,并引用整个地址空间。这就是为什么我说“概率地说”它们是等价的。 –

+0

这并没有让它变得更好,因为答案取决于'ds'和'es'具有相同的值。所以在Windows程序中,指令的效果是一样的,因为'es'和'ds'指向相同的段,但这并不能使指令本身等效,只是它在Windows系统中的作用(也许还有在Linux中,由于OP显然不知道这一点,所以他会被误导,你应该用'假设es和ds是相等的'来代替'probabillity'部分 – Devolus

2

:约定用于指示地址的段部分。 ES因此是一个段(因此SI,例如在这个位置将是无效的)和[BX]该段内的偏移;用作偏移的段寄存器同样是无效的,并且导致错误。

+0

谢谢。更有意义 – CBaker

1

当你在处理存储器访问某些数据,则总是有涉及一个段寄存器,它定义了存储器窗口主要寄存器作为偏移量。这些寄存器是cs,ds,es,ss,fsgs。其中一些段寄存器具有特殊用途,如csss。 当你用例子中的寄存器访问数据时,汇编器会选择一个默认段。该段寄存器在指令中编码。 有些情况下,您想要覆盖默认选择,并使用不同的段寄存器,然后使用默认选项,并且可以通过使用段覆盖来实现此目的,这是您的示例正在做的事情。

当执行

mov eax, [ebx] 

默认ds段将被用于

但与段重载

mov eax, es:[ebx] 

指令指定该es段应被代替使用。在Windows中,默认情况下,dses指向同一个段,因此不需要此重写,因为它将访问相同的物理地址。

0

DS:OFFSET其中DS是段地址,OFFSET是相对于段的偏移量。

这意味着计算像这样的地址:DS * size_of_segment + OFFSET

通常,用于x86段的大小是16字节。

例如:

 DS: 07C0H 0000 0111 1100 0000 
+ OFFSET: 0000H  0000 0000 0000 0000 
=   07C00H 0000 0111 1100 0000 0000