- 处理的数据在什么地方?
- 要处理的数据长度是多少?
bx、si、di 和 bp
只有这个 4 个寄存器可以用来在 [...]
中进行内存单元寻址。
1 | mov ax, [bx] |
错误用法:
1 | mov ax, [cx] |
在 [...]
中,这 4 个寄存器可以单个出现或者以 4 种组合出现:bx 和 si、bx 和 di、bp 和 si、bp 和 di。
以下都是正确的指令:
1 | mov ax, [bx] |
在 [...]
中使用寄存器 bp,段地址默认从 ss 读取。
数据位置的表达
- 立即数:指令要处理的直接包含在机器指令中的数据(执行前在 CPU 的指令缓冲器中)
- 寄存器:指令要处理的数据在寄存器
- 段地址(SA)和偏移地址(EA):指令要处理的数据在内存中
寻址方式
当数据存放在内存中时,我们可以使用多种方式给定这个内存单元的偏移地址。8086CPU 寻址方式总结:
寻址方式 | 含义 | 名称 | 常用格式举例 |
---|---|---|---|
[idata] | EA=idata;SA=(ds) | 直接寻址 | [idata] |
[bx] | EA=(bx);SA=(ds) | 寄存器间接寻址 | [idata] |
[si] | EA=(si);SA=(ds) | 寄存器间接寻址 | [idata] |
[di] | EA=(di);SA=(ds) | 寄存器间接寻址 | [idata] |
[bp] | EA=(bp);SA=(ss) | 寄存器间接寻址 | [idata] |
[bx+idata] | EA=(bx);SA=(ds) | 寄存器相对寻址 | [idata] |
[si+idata] | EA=(si);SA=(ds) | 寄存器相对寻址 | [idata] |
[di+idata] | EA=(di);SA=(ds) | 寄存器相对寻址 | [idata] |
[bp+idata] | EA=(bp);SA=(ss) | 寄存器相对寻址 | [idata] |
[bx+si] | EA=(bx)+(si);SA=(ds) | 基址变址寻址 | [idata] |
[bx+di] | EA=(bx)+(di);SA=(ds) | 基址变址寻址 | [idata] |
[bp+si] | EA=(bp)+(si);SA=(ss) | 基址变址寻址 | [idata] |
[bp+di] | EA=(bp)+(di);SA=(ss) | 基址变址寻址 | [idata] |
[bx+si+idata] | EA=(bx)+(si)+idata;SA=(ds) | 相对基址变址寻址 | [idata] |
[bx+di+idata] | EA=(bx)+(di)+idata;SA=(ds) | 相对基址变址寻址 | [idata] |
[bp+si+idata] | EA=(bp)+(si)+idata;SA=(ss) | 相对基址变址寻址 | [idata] |
[bp+di+idata] | EA=(bp)+(di)+idata;SA=(ss) | 相对基址变址寻址 | [idata] |
bx、bp 存基址,si、di 存变址,有了 idata 叫相对。
指令要处理的数据有多长
8086CPU 可以处理 byte 和 word 两种尺寸的数据。在机器指令中要指明指令进行的是字操作还是字节操作。
- 通过寄存器名指明要处理的数据的尺寸。寄存器是 ax 就是字,al、ah 就是字节操作。
- 通过操作符
X ptr
指明内存单元长度,X 可以为 word 或 byte。
1 | mov word ptr ds:[0], 1 ;操作一个字单元 |
- 其他方法,有些指令默认访问单元是字单元还是字节单元,
push [1000H]
,push 指令只执行字操作。
bx 定位整个结构体,idata 定位结构体中的某个数据项,si 定位数组项中的每个元素。[bx].idata[si]
1 | mov ax, seg |
div 指令
div 是除法指令
- 除数:8 位、16 位两种,在一个寄存器或内存单元。
- 被除数:如果除数为 8 位,被除数为 16 位,默认放在 ax;如果除数为 16 位,被除数为 32 位,dx 存放高 16 位,ax 存放低 16 位。
- 结果:除数为 8 位,al 存商,ah 存余数;除数为 16 位,ax 存商,dx 存余数。
先把被除数放好(ax 或 dx:ax),然后指定除数
1 | div 除数 |
1 | div byte ptr ds:[0] |
含义:
(al)=(ax)/((dx)*16+0)
的商
(ah)=(ax)/((dx)*16+0)
的余数
1 | div word ptr es:[0] |
含义:
(ax)=((dx)*10000h+(ax))/((es)*16+0)
的商
(dx)=((dx)*10000h+(ax))/((es)*16+0)
的余数
伪指令 dd
dd 用于定义 dword(double word,双字)型数据。
1 | data |
在 data 段定义了 3 个数据:
- 01h 占 1 个字节;
- 0001h 占 1 个字;
- 00000001h 占 2 个字
dup
由编译器识别处理的符号,伪指令,配合 db、dw、dd 等数据定义伪指令使用,用来进行数据的重复。
1 | db 3 dup (0) |
定义 3 个字节,值为 0。
1 | db 3 dup (0,1,2) |
定义 9 个字节,他们是 0、1、2、0、1、2、0、1、2。
dup 的使用格式如下:
1 | db 重复次数 dup (重复的字节型数据) |
定义一个 200 个字节的栈段:
1 | stack segemnt |
实验 7 寻址方式在结构化数据访问中的应用
1 | cs:codesg |