寻址方式
默认段选择规则访存类型 | 所用段及段寄存器 | 缺省选择规则 |
指令 | 代码段 CS | 取指令 不允许段跨越前缀 |
堆栈 | 堆栈段 SS | 所有堆栈的进出栈 不允许段跨越前缀 |
局部数据 | 数据段 DS | 除堆栈 串处理 指令以外的数据访问 |
目的串 | 附加数据段 ES | 串处理指令的目的串 不允许段跨越前缀 |
该表对于正确使用汇编指令相当重要。
eg. MOV AX, [2000H]
和 MOV AX, ES:[2000H]
段跨越前缀缺省,默认DS,不缺省,则按照段跨越前缀处理。
如当前 (DS)=3000H,按照实模式,操作的实际地址为 32000H
何为实模式?
由于一个寄存器只能存放16位,而我们的寻址空间有20位,所以在存储器寻址的时候,必须想办法用16位的寄存器来得出20位的地址,所以发明了一种基址+偏移地址的存储方法,将基址左移4位,基址就可以表示出第5-20位,而偏移地址可以表示1-16位,相加起来,就可以表示所有1~20位的组合。按照上例,DS为基址,左移4位相当于数学乘16,相当于16进制中补零,所以 实际操作地址为30000+2000=32000H。
eg. MOV AX, COUNT[SI]
这是寄存器相对寻址方式,等效于 MOV AX, [COUNT + SI]
假设 (DS) = 3000H, (SI) = 2000H, COUNT = 3000H。
那么,实际操作地址为 30000H+3000H+2000H=35000H。
类似的基址变址寻址 MOV AX,[BX][DI]
等效于MOV AX,[BX+DI]
方便二维数组查找,还可以相对基址变址寻址MOV AX,MASK[BX][SI]
等效于MOV AX[MASK+BX+SI]
不管再多么花里胡哨,我们最后都能把它等效到最初形式。不过,请注意,以上情况都是需要访问存储器的,才需要用到实模式,如果不访问存储器,那么自然不会按实模式来,例如立即数寻址、寄存器寻址等(也就是没有用到中括号的情况)。
JMP指令的寻址
JMP指令分为段内和段间寻址,段内寻址仅仅修改IP,不需要修改CS,因为段内寻址表示,他们仍然处在一个代码段中,所以不用修改CS,段间寻址(FAR PTR)由于需要对代码段进行修改,所以既要修改CS,又要修改IP。
eg. JMP BX
,(IP)=BX
eg.JMP [BX]
,(IP)=16H*DS+BX
eg.JMP [BX][SI]
,(IP)=16H*DS+BX+SI
与上面所述是基本相同的。
eg. JMP FAR PTR NEXTROUTINT
类似于这种,应当同时修改CS和IP。
指令系统
点击此连接获取累死整理的指令系统
汇编.xlsx
eg.lea bx, [bx+si+0f62h]
bx = bx+si+0f62h,不向存储器读取,不需要访问ds
eg. lea bx,list
等效为 mov bx, offset list
offset仅支持简单的符号地址,不能与变址等复杂的操作数寻址方式搭配,所以要用到地址传送的时候,还是建议使用lea
eg.les di, [bx]假设ds=b000h,bx=080ah,(0b080ah)=05aeh,0b080ch=4000h
(di)=05aeh,(ds)=4000h