在这个汇编指令中
mov ax, es:[bx]
:
做了什么?
答案 0 :(得分:3)
:
是表示地址的段部分的惯例。因此,ES
是一个细分受众群(因此SI
,例如此位置无效)和[BX]
该细分受众群内的偏移量;用作偏移的段寄存器同样无效,并且会产生错误。
答案 1 :(得分: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>]
其中addr ==(es <&lt; 4)+ [bx]
答案 2 :(得分:1)
当您访问进程存储器中的某些数据时,总是涉及一个段寄存器,它定义了一个以主寄存器作为偏移量的存储器窗口。这些寄存器是cs
,ds
,es
,ss
,fs
和gs
。其中一些段寄存器具有特殊用途,如cs
或ss
。
当您使用类似于示例的寄存器访问数据时,汇编器会选择默认段。该段寄存器在指令中编码。
有些情况下,您想要覆盖默认选择,并使用不同的段寄存器,然后使用默认的段寄存器,您可以通过使用段覆盖来实现这一点,这是您的示例所做的。
执行时
mov eax, [ebx]
默认使用ds
段
但是段覆盖的指令
mov eax, es:[ebx]
指定应使用es
段。在Windows中,默认情况下,ds
和es
指向同一段,因此不需要此覆盖,因为它将访问相同的物理地址。
答案 3 :(得分:0)
DS:OFFSET其中DS是段地址,OFFSET是相对于段的偏移量。
这意味着像这样计算地址: DS * size_of_segment + OFFSET
通常,对于x86,段的大小为16byte。
例如:
DS: 07C0H 0000 0111 1100 0000
+ OFFSET: 0000H 0000 0000 0000 0000
= 07C00H 0000 0111 1100 0000 0000