Les的教学目的?

时间:2011-09-08 05:57:19

标签: assembly x86 masm

汇编中les指令的目的是什么?

为什么我们需要加载es注册?本书给出了以下示例:

les    bx, p           ; Load p into ES:BX
mov    es:[bx], al     ; Store away AL

为什么我们需要在这种情况下加载es bx

为什么我们使用es:[bx]?如果p在内存中指向100h,则esbx 100h = 200h(bx+es)不是一样的吗?

3 个答案:

答案 0 :(得分:9)

太糟糕了,你正在为一个结构凌乱的微处理器学习汇编程序。你会得到令人困惑的概念,比如LES指令。

传统的微处理器具有足够大的寄存器以包含完整的存储器地址。您只需将内存位置的地址加载到寄存器中,然后通过寄存器访问该位置(通常是附近的索引)。

有些机器(特别是英特尔286似乎是您正在编程的)只有16位寄存器但可以处理1mB的内存。在这种情况下,寄存器没有足够的位:您需要20位,但寄存器只有16位。

解决方案是使用包含缺失位的第二个寄存器。一个简单的方案是需要2个寄存器,其中一个寄存器具有低16位,其中一个具有高16位,以产生32位地址。然后引用两个寄存器的指令是有意义的:你需要两个寄存器来获得一个完整的存储器地址。

英特尔选择了更简洁的方案:索引寄存器(在您的情况下为bx)包含低16位,另一个寄存器(称为ES)包含16位左移4位,并添加到索引寄存器,得到结果地址。 ES被称为“段”寄存器,但除非你在1968年左右阅读Multics operating system,否则这没有任何意义。

[完全实现Multics方式时,段和段寄存器确实是一个有趣的想法。如果您不知道这是什么,并且您对计算机和/或信息架构有任何任何的兴趣,请在Multics上找到Elliot Organick书籍,并阅读封面以涵盖。你会对我们在60年代后期所拥有的东西感到沮丧,并且似乎已经失去了50年的“进步”。]

x86中的想法还剩下一个笑话,至少它在“现代”操作系统中使用的方式。你真的不在乎;当一些硬件设计师为您提供一台机器时,您必须按原样使用它。

对于Intel 286,您只需加载段寄存器和索引寄存器即可获得完整地址。每个机器本身必须引用一个索引寄存器和一个段寄存器以形成完整地址。对于Intel 286,有4个这样的段重组器:DS,SS,ES和CS。每个指令类型都明确指定一个索引寄存器,并隐式选择4个段寄存器中的一个,除非您提供一个明确的覆盖,说明要使用哪一个。除非另有说明,否则JMP指令使用CS。除非另有说明,否则MOV说明使用DS。 PUSH指令使用SS,除非你另有说明(在这种情况下你最好不要)。 ES是“额外”部分;你只能通过在指令中明确引用它来使用它(块移动[MOVB}指令除外,它同时使用DS和ES)。

希望有所帮助。

最好使用更现代的微处理器,其中段寄存器愚蠢不是问题。

答案 1 :(得分:5)

8086段寄存器csdsesss是16位寄存器可以处理超过64K内存的原始机制。在8086/8088中,有20位地址(1024 K)要生成。 x86处理器的后续版本增加了新的方案来解决更多问题,但是从一对16位值生成20位以上的地址是基本原因。

在所谓的“实模式”(原生于8086/8088/80186/80286)中,通过将段寄存器的内容乘以16(或等效地,向左移动四位)并添加来计算地址抵消。

在保护模式下(80386及更高版本可用),段寄存器选择包含基本物理地址的“描述符”。例如,操作数es:[bx]bx添加到该物理地址以生成操作数地址。

答案 2 :(得分:3)

指向具有段和偏移部分的32位FAR指针(与NEAR指针(仅为偏移部分)形成对比)。 LES会将segment:offset加载到ES:BX

否则,您必须使用三条指令。 一个用于加载BX,两个用于加载ES(段寄存器不能直接从内存加载,但必须加载到通用寄存器中,然后加载到段寄存器中)。

哦,是的,wallyk提到保护模式有一个很好的观点(虽然这与你的问题不同)。 在这里,ES将被解释为选择器,而不是实际的段。

此上下文中的段(地址)是物理地址的一部分:
将段向左移位4位(即将其乘以2 ^ 4 = 16)并添加偏移量以从段中获取物理地址:offset。

相反,选择器是指向所谓描述符表中的条目的指针(即,选择器指向描述符)并且在保护模式中使用。 描述符表(例如GDT)可以包含关于内存块的信息条目,包括有关物理内存地址,块大小,访问权限等的信息(还有一些其他用途)。