实验
- 综合使用
loop
、[bx]
,编写完整汇编程序,实现向内存b800:07b8
开始的连续 16 个字单元重复填充字数据0403H
。
-
以下为示例程序:
assume cs:code # 1
code segment # 2
mov ax, 0b800h # 3 ; 数据必须以数字开头,要在字母前补 0
mov ds, ax # 4
mov cx, 16 # 5 ; 设置循环次数为 16
mov bx, 07b8h # 6
# 7
S: mov [bx], word ptr 0403h # 8 ; 将字数据 0403h 送向偏移地址
inc bx # 9 ; 字数据占 2 个内存单元 bx 自增两次
inc bx # 10
loop s # 11
# 12
mov ax, 4c00h # 13
int 21h # 14
code ends # 15
end # 16 -
编译、连接和运行结果如下图所示:
-
将源代码程序中字数据
0403H
修改为0441H
,再次运行的结果如下:结论与实验 3 是一致的,
b8000
开始的一块内存与显示有关,且修改的字数据的前两位和颜色有关,后两位是字符的 ASCII 码值。
- 综合使用
loop
、[bx]
,编写完整汇编源程序,实现向内存0:200
到0:23F
依次传送数据0
到63(3FH)
。
-
使用
loop
,[bx]
,mov
实现- 以下为示例程序:
assume cs:code # 1
code segment # 2
mov ax, 0020h # 3
mov ds, ax # 4
mov cx, 64 # 5 ; 设置循环次数为 64
mov bx, 0 # 6
# 7
S: mov [bx], bl # 8 ; 将字节数据送向偏移地址
inc bx # 10
loop s # 11
# 12
mov ax, 4c00h # 13
int 21h # 14
code ends # 15
end # 16- 编译、连接如下图所示:
- 用
g
命令执行程序,并用d
命令显示内存中的内容,如下图所示:
结果很明显。还有,这里因为数据不大于 255 所以传送字节数据。
-
还可以利用栈的特性,使用
loop
和push
实现- 以下为示例程序:
assume cs:code # 1
code segment # 2
mov ax, 0020h # 3
mov ss, ax # 4 ; 根据之前的实验得,在修改 ss 时一并执行
mov sp, 0040h # 5 ; 下一条指令,下一条指令一般是修改 sp 的值
mov bx, 3f3eh # 6 ; 由于栈是对字数据操作,不得不将 2 个内存
# 7 ; 单元的值一起写入 16 位寄存器
mov cx, 32 # 8 ; 对字数据操作,循环 32 次
# 9
s: push bx # 10 ; 压栈时栈顶指针上移 2 个单位 (sp - 2)
sub bl, 2 # 11
sub bh, 2 # 12
loop s # 13
# 14
mov ax, 4c00h # 15
int 21h # 16
code ends # 17
end # 18- 编译、连接如下图所示:
- 重复上次实验的操作,如下图所示:
根据压栈的特性,需要先压入高地址单元的内存,所以是按从
3f
到0
的顺序压入。
- 下面的程序的功能是将
mov ax, 4c00h
之前的指令复制到内存0:200
处,补全程序并调试。
assume cs:code # 1
code segment # 2
mov ax, __ # 3
mov ds, ax # 4
mov ax, 0020h # 5
mov es, ax # 6
mov bx, 0 # 7
mov cx, __ # 8
# 9
s: mov al, [bx] # 10
mov es:[bx], al # 11
inc bx # 12
loop s # 13
# 14
mov ax, 4c00h # 15
int 21h # 16
code ends # 17
end # 18
指令执行是因为 cs:ip
指向了它,cs
就是指令的段地址,我们只需要把指令的段地址交给数据段就能直接通过 [bx]
来获取内存中的内容了。所以 # 3 行的空格填 cs
。
由于不确定指令占用多少字节,现在将 cx
的值设为 0
并编译、连接,如下图所示:
使用 debug
中的 u
命令反汇编,查看指令占用了多少内存,如下图所示:
可见 mov ax, 4c00h
之前的命令占用 1e87:0000
到 1e87:0015
共 17h
个字节。
由此可得,共循环 17h
次,因此 # 8 行的空格填 17h
,并将 cx
的值设置为 17h
,重新编译、连接和反汇编,如下图所示:
确认无误后,使用 g
命令运行,并使用 d
命令查看结果,如下图所示:
可见已成功将 mov ax, 4c00h
之前的指令复制到指定内存。
尾巴
这次没有什么好说的,那就简单说一下在实验时可能遇到的问题:
-
debug
中的mov ax, [0]
与程序中的mov ax, [0]
是不同的,程序中的会被编译器当作mov ax, 0
, 解决方法有两种mov bx, 0 mov ax, [bx]
或者是mov ax, ds:[0]
。 - 程序中所有数据不能以字母开头,如果是字母开头的 16 进制数,需要在前面补 0。
- 栈只能对字数据进行操作,有时需要对操作数据做一些转换。