5.2 立即、寄存器与直接寻址
寻址方式(addressing mode)回答:“这个操作数来自哪里,或者结果要写到哪里?”同一个操作会因为操作数是指令内字面量、寄存器还是存储器单元而产生不同的数据路径。
本节使用 MOV 介绍三种形式。MOV 目的,源 把位模式从源复制到目的,不会删除源中的数据。
操作数可以位于三个地方
| 方式 | 示例 | 源操作数的含义 |
|---|---|---|
| 立即寻址 | MOV AX,1234H | 指令中内嵌的字面量 1234H |
| 寄存器寻址 | MOV AX,BX | BX 当前保存的内容 |
| 直接存储器寻址 | MOV AX,[1234H] | 存储器偏移量 1234H 处保存的字 |
方括号不是装饰。它表示:把括号中的值当作地址,并访问存储器。
没有方括号时,1234H 是数据;加上方括号后,[1234H] 表示一个存储器位置。若该位置保存 BEEFH,那么:
MOV AX,1234H使 AX=1234H;
MOV AX,[1234H]使 AX=BEEFH。
立即数形式和寄存器形式不需要为操作数数据读取存储器;直接存储器形式要求 BIU 形成地址并执行总线周期。这种差异同时影响编码和执行时间。
源与目的的宽度必须兼容
8 位目的需要 8 位源,16 位目的需要 16 位源。例如,MOV AL,7FH 的宽度相符;对于 MOV AX,7FH,汇编器需要选择 007FH 这样的 16 位立即数表示。
普通 8086 MOV 不能在一条指令内直接把任意一个存储器位置复制到另一个任意存储器位置。除之后学习的专用串指令外,通常至少有一个操作数是寄存器。
实验 1——从正确的数据仓路由操作数
调节 AX、BX、指令立即数和一个直接存储单元。选择并执行不同 MOV 形式,交换台会标出当前有效的源与目的。
检查理解
直接寻址内嵌的是地址,不是操作数数据
对于专用累加器形式:
A1编码MOV AX,[moffs16];
A3编码MOV [moffs16],AX。
这里的 moffs16 表示直接写在指令中的 16 位存储器偏移量。若偏移量为 1234H,其字节按低位在前排列:
| 字节位置 | 值 | 作用 |
|---|---|---|
| 1 | A1H | 从直接存储器偏移量读取 AX |
| 2 | 34H | 偏移量低字节 |
| 3 | 12H | 偏移量高字节 |
字节 A1 34 12 不会把 1234H 放入 AX。它告诉处理器访问偏移量 1234H,存放在那里的字才会成为数据。
这里存在两次不同的小端重建:
1. 指令字节 34 12 重建地址 1234H。
2. 从该地址读出的两个字节重建字操作数。
不要混淆这两个层次。颠倒地址字节会访问另一个位置;颠倒数据字节会改变读取出来的字。
直接存储器引用仍然需要段。若没有段超越,直接数据寻址通常使用 DS;5.4 节将推导完整物理地址。
实验 2——修复并操作直接地址探针
编辑 A1/A3 与地址的低/高字节,然后真正发起一次模型读写。内存图会让颠倒的地址明显命中另一个单元。
检查理解
不靠猜测阅读汇编
对于每个操作数:
1. 没有方括号的字面数字是立即数。
2. 寄存器名称表示该寄存器当前保存的内容。
3. 方括号表示存储器访问;先计算括号中的偏移量,再读写存储器。
4. 把地址字节与数据字节分开处理。
直接寻址把偏移量固定在指令中。下一节将利用 BX、BP、SI、DI 和可选位移计算地址,让地址可以重复使用和移动。