les
指令在汇编语言中的作用是什么?
为什么我们需要加载es
段和一个寄存器?书中给出了以下示例:
les bx, p ; Load p into ES:BX
mov es:[bx], al ; Store away AL
为什么在这种情况下需要加载 es
和 和 bx
?
还有,为什么要使用 es:[bx]
?如果 p
指向内存中的 100h,那么 es
和 bx
都不是 100h,而是 200h(bx+es
)吗?
英特尔选择了一个更混乱的segment:offset
方案:普通寄存器(在您的情况下为bx)包含低16位(偏移量),而特殊寄存器(称为ES)包含左移4位的16位,加到偏移量上,以获得结果线性地址。 ES被称为“段”寄存器,但是如果您不去阅读1968年左右的Multics操作系统,这将毫无意义。
(x86允许对内存地址的“有效地址”或“偏移量”部分使用其他寻址模式,例如es:[bx + si + 1234]
,但始终只有一个段寄存器用于内存地址。)
p指向一个32位的FAR指针,具有段和偏移部分(与仅为偏移部分的NEAR指针相对)。
LES将加载段:偏移量到ES:BX
中。
否则,您将需要使用三个指令。
一个用于加载BX
,两个用于加载ES
(段寄存器不能直接从内存中加载,必须先加载到通用寄存器中,然后再加载到段寄存器中)。
哦,是的,wallyk提到了保护模式是一个好观点(尽管这与您的问题无关)。
在这里,ES
将被解释为选择器,而不是实际的段。
在此上下文中,段(地址)是物理地址的一部分:
将段左移4位(即乘以2^4 = 16),然后加上偏移量,以从段:偏移量获取物理地址。
相比之下,选择器是指向所谓的描述符表中条目的指针(即选择器指向描述符),并且在保护模式下使用。 描述符表(例如GDT)可能包含有关内存块的信息条目,包括有关物理内存地址,块大小,访问权限等的信息(还有一些稍微不同的用法)。
mov es, word [1234h]
进行加载。唯一的限制是你不能在计算中使用段寄存器(如inc
,add
,and
等指令),也不能在嵌入指令的立即值中加载(如mov es,0ABCDh
)。 - ecm