3

在本汇编指令中

mov ax, es:[bx]

做什么:

4

4 回答 4

3

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

于 2013-11-02T05:45:51.133 回答
3

: 具体是做什么的?

“:”不“做”任何事情,就像“。”一样。在大多数高级编程语言中不会“做”任何事情。':' 与形式的指令一起使用<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>]

其中 addr == (es << 4) + [bx]

于 2013-11-02T07:21:35.697 回答
1

当您访问进程内存中的某些数据时,总会涉及到一个段寄存器,它定义了一个以主寄存器为偏移量的内存窗口。这些寄存器是csdsesssfsgs其中一些段寄存器具有特殊用途,例如csss。当您使用示例中的寄存器访问数据时,汇编器会选择默认段。该段寄存器在指令中编码。在某些情况下,您想要覆盖默认选择,并使用不同的段寄存器,然后是默认的,您可以通过使用段覆盖来实现这一点,这就是您的示例正在执行的操作。

执行时

mov   eax, [ebx]

默认情况下,ds将使用该段

但是带有段覆盖的指令

mov   eax, es:[ebx]

es指定应改为使用该段。在 Windows 中,默认情况下,dses指向同一段,因此不需要此覆盖,因为它将访问相同的物理地址。

于 2013-11-02T08:42:26.053 回答
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
于 2014-05-22T05:15:00.560 回答