assembly - Les 教学目的?

标签 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 )?

最佳答案

您正在为架构困惑的微处理器学习汇编程序,这太糟糕了。您会遇到令人困惑的概念,例如 LES 指令。
传统的微处理器有足够大的寄存器来包含一个完整的内存地址。您可以简单地将内存位置的地址加载到寄存器中,然后通过寄存器访问该位置(通常是附近有索引的位置)。
一些机器(特别是实模式下的 Intel 286,这似乎是您正在编程的),只有 16 位寄存器,但可以寻址 1MB 内存。在这种情况下,寄存器没有足够的位:您需要 20 位,但寄存器只有 16 位。
解决方案是使用包含丢失位的第二个寄存器。一个简单的方案是需要 2 个寄存器,其中一个具有低 16 位,另一个具有高 16 位,以产生 32 位地址。那么引用两个寄存器的指令是有道理的:您需要同时获得完整的内存地址。
英特尔选择了更困惑的segment:offset方案:普通寄存器(在您的情况下为 bx)包含低 16 位(偏移量),特殊寄存器(称为 ES)包含 16 位左移 4 位,并添加到偏移量中,以获得结果线性地址。 ES 被称为“段”寄存器,但除非您阅读有关 Multics operating system 的信息,否则这没有任何意义。大约在 1968 年。
(x86 允许对地址的“有效地址”或“偏移量”部分使用其他寻址模式,例如 es:[bx + si + 1234] ,但对于内存地址始终只有一个段寄存器。)
[当完全实现 Multics 方式时,段和段寄存器确实是一个有趣的想法。如果您不知道这是什么,并且您对计算机和/或信息架构有任何兴趣,请查找 Elliot Organick 关于 Multics 的书并从头到尾阅读。你会对我们在 60 年代后期所拥有的感到沮丧,并且似乎在 50 年的“进步”中失去了。如果您想对此进行更长时间的讨论,请参阅 my discussion on the purpose of FS and GS segment registers ]
x86 中剩下的想法几乎是一个笑话,至少它在“现代”操作系统中使用的方式是这样。你真的不在乎;当某些硬件设计师向您展示一台机器时,您必须照原样接受它。
对于 Intel 286,您只需加载段寄存器和索引寄存器即可获得完整地址。每条机器指令必须引用一个变址寄存器和一个段寄存器,以形成一个完整的地址。对于 Intel 286,有 4 个这样的段寄存器:DS、SS、ES 和 CS。每个指令类型明确指定一个索引寄存器并隐式选择 4 个段寄存器之一,除非您提供一个明确的覆盖来说明要使用哪个。除非另有说明,否则 JMP 指令使用 CS。除非另有说明,否则 MOV 指令使用 DS。 PUSH 指令使用 SS 除非你另有说明(在这种情况下你最好不要)。 ES是“额外”的部分;您只能通过在指令中显式引用它来使用它(块移动 [MOVB} 指令除外,它隐式使用 DS 和 ES)。
希望有帮助。
最好使用更现代的微处理器,其中段寄存器愚蠢不是问题。 (例如,32 位模式 x86,其中主流操作系统使用所有段基数 = 0 的平面内存模型。因此您可以忽略分段并使用单个寄存器作为指针,只关心地址的“偏移”部分。 )

关于assembly - Les 教学目的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7343689/

相关文章:

linux - 如何在软盘上测试引导加载程序

assembly - .text 和 .code 节名称之间的区别

assembly - 在 8086 中的变量中存储标志值 - 汇编语言

java - java在不同架构上编译和运行时的行为方式

c++ - 列出所有正在运行的应用程序 MASM32 程序集

string - 复制字符串时出错 - ASM

c++ - 从汇编程序写入返回值时发生意外页面错误

assembly - “PTR” 和 “NEAR PTR” 和有什么区别?

arrays - x86 汇编代码中的 For 循环和数组遍历

linux - 程序集:从 stdin 读取整数,增加它并打印到 stdout