目录
第五章:[BX] 和 LOOP 指令
📌 主要内容
本章重点讲解了 8086 汇编中最基本的间接寻址与循环控制机制,通过 [BX]
访问内存、LOOP
指令实现循环,并结合 DEBUG 工具跟踪执行过程,最后介绍段前缀与安全空间的定义与应用。
🧠 笔记重点
5.1 [BX]
的寻址机制
-
概念
[BX]
表示以寄存器 BX 中的值作为段偏移访问内存,即物理地址 =DS × 16 + BX
。 -
使用步骤
- 初始化 DS:
mov ax, data
→mov ds, ax
- 设置 BX:
mov bx, offset myVar
- 执行寻址:
mov ax, [bx]
- 初始化 DS:
-
示例:遍历数组
assume cs:code, ds:data data segment dw 10,20,30,40 data ends code segment start: mov ax, data mov ds, ax mov cx, 4 mov bx, 0 loop1: mov ax, [bx] ; 读取 DS:BX ; 在这里可以对 AX 做进一步处理 add bx, 2 ; BX 指向下一个字 loop loop1 mov ax, 4c00h int 21h code ends end start
- 每次
LOOP
后 BX 增加 2,处理下一个元素。
- 每次
5.2 LOOP
指令详解
-
概念
LOOP label
自动将 CX 减 1,再根据 CX 是否为零决定跳转。 -
执行微操作
TMP ← CX - 1
CX ← TMP
- 若
TMP ≠ 0
,IP ← IP + offset(label)
;否则继续。
-
影响标志
LOOP
不修改任何标志位,仅影响 CX。
-
使用步骤
- 设置 CX:
mov cx, n
- 写循环体:放在 label 至
loop label
之间 - 结束循环:当 CX 递减至 0 时跳出
- 设置 CX:
-
示例:计算2的12次方
assume cs:code code segment mov ax, 2 mov cx, 11 s: add ax,ax loop s mov ax, 4c00h int 21h code ends end
5.3 在 DEBUG 中跟踪
-
步骤详解
- 加载程序:
debug
进行跟踪 - 反汇编检查:
u
查看机器码与符号对照 - 设置寄存器:
r cx bx ds
初始化寄存器 - 单步执行:使用
t
观察 IP、CX、BX 逐条变化 - 查看内存:在每次
mov ax, [bx]
后使用d ds:bx
验证内存内容
- 加载程序:
-
关键观察
r cx
看 CX 由初值递减至 0r bx
看 BX 如何随add bx,2
或inc bx
变化r ip
看loop
是否正确跳转到 label
5.4 DEBUG vs MASM 对指令的不同处理
-
DEBUG
mov ax,2000 mov ds,ax mov al,[0] mov bl,[1] mov cl,[2] mov dl,[3]
- debug将[idata]解释为内存单元,idata是内存的偏移地址
-
MASM
assume cs:code code segment mov ax,2000h mov ds,ax mov al,[0] mov bl,[1] mov cl,[2] mov dl,[3] mov ax, 4c00h int 21h code ends end
- 编译器将[idata]解释为idata
-
编译器如何做
1.使用bx寄存器间接访问
mov ax,2000h mov ds,ax mov bx,0 mov al,[bx]
2.显示的给出段地址
mov ax,2000h mov ds,ax mov al,ds:[0]
5.5 [BX]
与 LOOP
联合应用深入
-
完整流程
- 数据段设置:初始化 DS
- 循环计数:
mov cx, count
- 偏移初始化:
mov bx, offset
- 读/写操作:
mov ax, [bx]
或mov [bx], val
- 偏移更新:
add bx, size
- CX 计数:
loop label
-
示例:计算ffff:0~ffff:b单元数据的和,结果存放在dx中
assume cs:code code segment mov ax,0ffffh mov ds,ax mov bx,0 mov dx,0 mov cx,12 s: mov al,[bx] mov ah,0 add dx,ax inc bx loop s mov ax, 4c00h int 21h code ends end
5.6 段前缀(Segment Override)
-
用途
修改默认段寄存器,用来访问非 DS 段的数据。 -
写法
mov ax, es:[bx] mov al, ss:[bp+4]
-
执行过程
- CPU 在取指后遇到前缀字节(26h→ES、2E→CS、36h→SS、3E→DS),重置寻址时用的段寄存器。
-
示例
mov ax, data1 mov ds, ax mov ax, data2 mov es, ax mov bx, 0 mov dx, es:[bx] ; 访问 data2 段
5.7 “安全空间”定义与管理
-
目的
保证程序运行时有足够空间,不被栈或代码覆盖。 -
定义方法
buffer segment db 256 dup(0) buffer ends
db
定义字节,dup(0)
生成 256 个 0。
-
应用场景
- 字符串缓冲区
- 临时数据存储
- 实验数据区
5.8 综合实例
-
将内存ffff:0 ~ ffff:b单元中的数据复制到0:200 ~ 0:20b单元中
assume cs:code, code segment mov ax,0fffh mov ds,ax mov ax,0020h mov es,ax mov bx,0 mov cx,12 s: mov dl,[bx] mov es:[bx],dl inc bx loop s mov ax, 4c00h int 21h code ends end
🧪 实验4:[bx]和loop的使用
-
编程,向内存0:200 ~ 0:23F依次传递数据0 ~ 63(3FH)
assume cs:codesg codesg segment mov ax,0020H mov ds,ax mov cx,64 mov bx,0 mov dx,0 s: mov [bx],dl inc dl inc bx loop s mov ax, 4c00h int 21h codesg ends end
-
编程,向内存0:200 ~ 0:23F依次传递数据0 ~ 63(3FH),程序中只能使用9条指令
assume cs:codesg codesg segment mov ax,0020H mov ds,ax mov cx,64 mov bx,0 s: mov [bx],bl inc bx loop s mov ax, 4c00h int 21h codesg ends end
-
下面的程序功能是将“mov ax,4c00h"之前的指令复制到内存0:200处,补全程序。上机调试,跟踪运行结果
assume cs:code code segment mov ax, code mov ds,ax mov ax,0020h mov es,ax mov bx,0 mov cx, 18h s: mov al,[bx] mov es:[bx],al inc bx loop s mov ax,4c00h int 21h code ends end
🔍 拓展理解
- 深入理解每条机器码字节的含义,有助于逆向分析和手动优化;
- 熟练使用
LOOP
与多种寻址方式,为后续复杂数据结构操作(如字符串、结构体)打基础; - 多段管理是大型汇编程序必备技能,了解段前缀与寄存器配合使用至关重要。