汇编语⾔中MOV和OFFSET指令的两个问题?
(1)往段寄存器送段地址时要写成
MOV AX,DATA
MOV DS,AX
不能写成
MOV DS,DATA
这是为什么?有⼈说由于段寄存只能进⾏16位的读写,因此需要⽤ax来倒⼀下,还有⼈说是因为段寄存器不能⽤于⽴即数寻址,究竟哪个对呢?如果第⼆个对,那么段名DATA是⽴即数吗?还是因为别的原因?
(2)书上有道例题是
MOV BX,OFFSET STR ;STR是已经定义的变量
LEA SI,VAR ;VAR是已经定义的变量
MOV AH,[BX]
MOV AX,[SI+2]
后⾯有段解释说前两个指令功能相同,( 但OFFSET只能与简单的符号地址相连,⽽不能和诸如[SI+X]等复杂的地址表达式相连 ),因此,LEA指令在取得变量的偏移地址后以相对寻址⽅式访问其他存储单元⽅⾯是很有⽤的。
请问括号⾥的那段话是什么意思?
难道意思是 MOV SI,OFFSET STR
MOV AX,[SI+2]
是不对的吗?为什么?
解答:
1、从intel的集我们可以看到与有关的有:
MOV mem,greg
MOV greg,mem
MOV rreg,reg
很显然,不能把⽴即数赋值给段寄存器。
DATA SEGMENT作为,在编译连接过程会被赋⼀个⽴即数的值。
2、
MOV SI,OFFSET STR
MOV AX,[SI+2]
这个是没错的。
LEA SI,STR与MOV SI,OFFSET STR最⼤区别在于OFFSET STR是⼀条伪指令,与SEG DATA之类相似,它在编译和连接过程被赋给⼀个值,你可以把它看成⼀个⽴即数,LEA SI,STR是把STR的赋给SI,你可以把它看成。另外,MOV SI,OFFSET STR是⼀条2⽴即寻址指令,LEA SI,STR是⼀条3字节内存寻址指令,后者虽然有⽐较灵活的,但前者具有更⼩的和更快的执⾏速度,推荐尽可能使⽤MOV SI,OFFSET STR。当然,OFFSET只能是标号或名。