我不完全理解前两行的含义,以及后两行的区别..
LDS SI,[BX]
LES DI,[BX]
LEA DI,5000h
MOV DI,5000h
我认为 LEA 在 DI 中加载 5000h,而 MOV 在 DI 中加载 5000h 的内容。我对吗??
该lea
指令实际上并没有从内存中加载任何内容。
lea
与我们现在所拥有的相比,8086 的功能是有限的。lea
just 可以将最多两个地址寄存器和一个立即(常数)值相加,并将这个和放入目标寄存器。例如,将plus加 3的总和lea bp, [bx+si+3]
设置到bp
寄存器。bx
si
80386处理器引入了一系列缩放模式,其中索引寄存器的值可以乘以一个有效的缩放因子来获得位移。有效的比例因子是 1、2、4 和 8。因此,您可以使用lea ebp, [ebx+esi*8+3]
.
相反,指令lds
和les
将值从内存加载到一对寄存器:一个段寄存器(ds
或es
)和一个通用寄存器。其他段寄存器也有此加载指令的版本:lfs
、lgs
和lss
、fs
和段寄存器分别gs
(ss
在 80386 中引入)。所以这些指令加载“远”指针 - 一个由 16 位段选择器和 16 位(或 32 位,取决于模式)偏移量组成的指针,因此总远指针大小为 16 位中的 32 位位模式和 32 位模式下的 48 位。
这些是 16 位模式的便捷指令,无论是 16 位实模式还是 16 位保护模式。
在 32 位模式下,不需要这些指令,因为操作系统将所有段基数设置为零(平面内存模型),因此不需要加载段寄存器。我们只使用 32 位指针,而不是 48 位。
在 64 位模式下,这些指令不会被执行。它们的操作码给出访问冲突中断(异常)。自从英特尔实施 VEX -“矢量扩展 - (AVX) 以来,英特尔回收了 and 的操作码lds
并les
开始将它们用于 VEX 前缀。这就是为什么只能x/ymm0..7
在 32 位模式下访问的原因。VEX 前缀lds
与les
in的无效编码重叠32 位模式,其中 R̅、X̅ 和 B̅ 位均为 1。