汇编语言中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,segreg
MOV segreg,mem
MOV serreg,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后面只能是标号或变量名。

参考资料:Intel CPU资料、Microsoft MASM说明

温馨提示:答案为网友推荐,仅供参考
第1个回答  2008-05-13
1、立即数不能直接传递给段寄存器,例:
xxx dw 2010
....
mov ds,xxx ;允许(xxx是变量)
....
mov ds,2010 ;不允许(2010是立即数)
;===============
2、LEA是计算机指令,在代码执行期它具有计算能力。而OFFSET是伪操作,它只在编译时简单地获取一个变量的地址,在代码执行期它没有计算能力。

例:
MOV BX,OFFSET str ;源代码
如果str的地址是2010,则编译后该行变为:
MOV BX,2010 ;执行代码

下面是允许的:
MOV SI,OFFSET STR
MOV AX,[SI+2]

类似下面是不允许的(这就是“括号里的那段话的意思”):
MOV SI,OFFSET STR + DX
第2个回答  2008-05-12
1.MOV AX,DATA 把数据段首地址给AX,而地址在内存里是一个立即数`所以不能直接给段寄存器 要用通用寄存器倒一下.
2.意思是MOV BX,OFFSET [SI+X]
是错的.就是 OFFSET 后面跟的是变量名.而不能是表达式
第3个回答  2008-05-12
MOV BX,OFFSET STR str的段偏移 放入BX中
再给你些资料 大家互相学习嘛!

-mov [edi], eax ----把eax的值(dword)赋给位于内存地址edi处的值
2--mov [bp-02], dx ---把dx的值(word)赋给位于内存地址bp-02处的值
3--mov esi,[BP+14] ---把位于内存地址BP+14的dword大小的值移入esi寄存器
4--mov eax, dword ptr [ebp-04]---把位于内存地址ebp-04的dword大小的值移入eax寄存器
5--mov eax, dword ptr[0000003Ah]--把位于内存地址3A的dword大小的值放入eax寄存器
6--mov cl, byte ptr [34h]--把位于内存地址34的byte大小的值放入cl寄存器
7--mov dx, word ptr [3Eh]--把位于内存地址3E的word大小的值放入dx寄存器
8--mov eax,[00403045h] --从内存地址403045读取一个32位的值
9--mov al, byte ptr [eax+ecx]--把位于内存地址eax+ecx的byte大小的值放入al寄存器

参考资料:qq

相似回答