4

我不完全理解前两行的含义,以及后两行的区别..

LDS SI,[BX]
LES DI,[BX]
LEA DI,5000h 
MOV DI,5000h

我认为 LEA 在 DI 中加载 5000h,而 MOV 在 DI 中加载 5000h 的内容。我对吗??

4

2 回答 2

7

前两个将 32 位的内容加载bxdssi(或esdi)中。

后两个是相同的,因为值是文字。然而,如果他们是:

lea di,[bx]
mov di,[bx]

那么您的期望是正确的:前者将地址bx放入di,后者将指向的 16 位bx放入di.

有关两者的更多信息,请参阅/ 的这个问题和/的这个问题lesldsmovlea

于 2013-08-20T16:06:08.387 回答
4

lea指令实际上并没有从内存中加载任何内容。

lea与我们现在所拥有的相比,8086 的功能是有限的。leajust 可以将最多两个地址寄存器和一个立即(常数)值相加,并将这个和放入目标寄存器。例如,将plus加 3的总和lea bp, [bx+si+3]设置到bp寄存器。bxsi

80386处理器引入了一系列缩放模式,其中索引寄存器的值可以乘以一个有效的缩放因子来获得位移。有效的比例因子是 1、2、4 和 8。因此,您可以使用lea ebp, [ebx+esi*8+3].

相反,指令ldsles将值从内存加载到一对寄存器:一个段寄存器(dses)和一个通用寄存器。其他段寄存器也有此加载指令的版本:lfslgslssfs和段寄存器分别gsss在 80386 中引入)。所以这些指令加载“远”指针 - 一个由 16 位段选择器和 16 位(或 32 位,取决于模式)偏移量组成的指针,因此总远指针大小为 16 位中的 32 位位模式和 32 位模式下的 48 位。

这些是 16 位模式的便捷指令,无论是 16 位实模式还是 16 位保护模式。

在 32 位模式下,不需要这些指令,因为操作系统将所有段基数设置为零(平面内存模型),因此不需要加载段寄存器。我们只使用 32 位指针,而不是 48 位。

在 64 位模式下,这些指令不会被执行。它们的操作码给出访问冲突中断(异常)。自从英特尔实施 VEX -“矢量扩展 - (AVX) 以来,英特尔回收了 and 的操作码ldsles开始将它们用于 VEX 前缀。这就是为什么只能x/ymm0..7在 32 位模式下访问的原因。VEX 前缀ldslesin的无效编码重叠32 位模式,其中 R̅、X̅ 和 B̅ 位均为 1。

于 2017-05-09T20:39:49.920 回答