目录 上一页 下一页 下一章

第10章 细节补充 -289-

与指令"MOV 寄存器,OFFSET 数据标号"完全一致,但是它们之间有一些很微妙的差别。这个差别在应用DEBUG编制程序时就有体现,请看下面的例子:
C:\ASM\>DEBUG[Enter]
-a100[Enter]
0F6A:0100 mov ah,9
0F6A:0102 mov dx,109
0F6A:0105 int 21
0F6A:0107 int 20
0F6A:0109 db'This is a sample',0d,0a,24
0F6A:011C[Enter]
-a100[Enter]
0F6A:0100 mov ah,9
0F6A:0102 lea dx,[10a]
0F6A:0106 int 21
0F6A:0108 int 20
0F6A:010A db'This is a sample',0d,0a,24
0F6A:011D [Enter]
  这两个程序很简单,可以在屏幕上显示一个字符串。所不同的是第二个程序换用"LEA"指令完成取偏移地址的功能。"LEA"的应用格式是很特殊的,表面上看这个指令采用一个存储器直接寻址方式,取到DX寄存器中的数据应该是"T"与"h"的ASCII码6854H,实际上如果跟踪执行这个程序就会观察到取到DX寄存器中的数据并非是6854H,而正是010AH。可见这个指令与MOV指令并不相同,通常对"寻址方式"的理解并不适用于LEA指令。
  由此看来指令"LEA BX,[SI]"也不是要把内存中[SI]地址处的两字节数据送进BX寄存器,而是送进SI的值。这一点可以说是这个指令最奇怪的地方,不过要是再细想一下这也正是将LEA称为"取有效地址指令"的原因。
  特别值得一提的是Borland公司出品的Turbo Assembly编译程序(TASM.EXE)对LEA指令的处理方法很不寻常,它会不声不响地用指令"MOV 寄存器,OFFSET 标号"替换掉LEA。原因很简单,这样替换之后生成的可执行程序会短小一些。这一点从刚才我们用DEBUG编制的两个对比程序中也可以看出来。
  另外新增的LES指令是用于处理32位指针的:
助记符:LES(Load ES with pointer)
用 途:将存于内存中的32位指针送入ES和指定的寄存器内
格 式:LES 寄存器,存储单元
执 行:32位指针中低16位作为偏移地址送入指定的寄存器中,高16位
    作为段地址送入ES寄存器中
  所谓32位的指针,其实就是以"段:偏移"形式给出的完整的逻辑地址,只是要求段地址在高字,偏移地址在低字而已。应用这个指令要注意两点:
  (1)此指令并非要固定与DI寄存器配合,虽然在串处理指令中ES段寄存器与DI寄存器是配合应用的,但是这条指令允许将偏移地址装入其它寄存器中。比如"LES SI,存储器"、"LES AX,存储器"这样的用法都可以;
  (2)与指令LEA不同,这个指令是真正要从内存中取得指针。不过在内存中定义指针时要采用定义"双字"的伪指令。前面我们讲过伪指令DB和DW,DB可以定义一个BYTE,DW可以定义一个WORD,如果要定义一个"双字"就要使用伪指令"DD(Define Double word)"。如果32位指针不是使用DD伪指令定义的,则使用LES指令编制的程序会出现编译错误。
  段地址并不是只能装入ES寄存器,还可以装入DS寄存器,相应的指令就是LDS(Load DS with pointer),用法及注意事项与LES指令相同,不再过多讨论。
  (7)CPU控制指令

Copyright © 2004-2015 Reanimator www.cookmoon.org

目录 上一页 下一页 下一章