[Hb-IV] 使用[bx]和loop

《汇编语言·第三版》--王爽


1 题目

(1) 向内存中传数据

编程,向内存0:200 ~ 023F依次传送数据0 ~ 63(3FH),程序中只能使用9条指令,9条指令包括“mov ax, 4c00h”和“int 21h”。


(2) 补全程序,跟踪运行

下面的程序的功能是将“mov ax, 4c00h”之前的指令赋值到内存0:200处,补全程序。上机调试,跟踪运行结果。

Table 1. l42.asm

1.         assume cs:code

2.         code segment

3.                mov ax, code         ;标号code最终被编译、连接程序处理为一个段的段地址

4.                mov ds, ax

5.                mov ax, 0020h

6.                mov es, ax

7.                mov bx, 0

8.                mov cx, 018h               ;此源程序经编译连接接被加载后,cx的值为整段程序的长度(包含mov ax, 4c00h和int 21h)

9.               

10.     s:     mov al, [bx]

11.            mov es:[bx], al

12.            inc   bx

13.            loop s

14.           

15.            mov ax, 4c00h

16.            int   21h

17.     code ends

18.     end

提示:

[1] 复制的是什么?从哪里到哪里?

[2] 复制的是什么?有多少个字节?你如何知道要复制的字节的数量?


2 练习

(1) 向内存中传数据

[1] 源程序

Table 2. l41.asm

1.         assume    cs:code

2.          

3.         code          segment

4.                  mov ax, 20h

5.                  mov ds, ax                

6.                  mov bx, 0

7.                 

8.                  mov cx, 40h

9.         s:      mov [bx], bl               ;bx作为偏移地址的同时bl作为传输值

10.              inc    bx

11.              loop s

12.             

13.              mov ax, 4c00h

14.              int    21h

15.     code          ends

16.     end


[2] 编译连接


Figure1. 编译连接

[3] 查看0:200 ~ 0:23F内容

Figure2. 0:200 ~ 0:23F内存内容

欧克,写入成功。


(2) 补全程序,跟踪运行

[1] 程序加载后各寄存器中的值

经编译后连接后的汇编程序,被加载时各寄存器的值如下:

Figure3. 汇编源程序编译和连接

Figure4. Debug加载汇编程序时各寄存器值的含义

CX代表整个程序的长度。DS为PSP的段地址,DS+10H为整个程序的段地址。CS:IP为程序第一条指令的地址。


图中绿色方框中为“mov ax, 4c00h”和“int 21h”两条指令,左边的DB004C, CD21为指令对应的机器码,共占5个字节,所以在“mov ax, 4c00h”之前的指令共占内存CX – 5 = 1D -51 = 18H字节。在l4.asm源程序中,原给cx赋值为0FFH,占三个字节。若现在想给CX赋值为整段程序指令的长度则CX = 018H,所以,l4.asm中赋值给CX的值为018H。


跟踪运行:

Figure5. 可用g 0012命令一下子运行到CS:0016处

可以用debug g命令以g  0016形式直接运行至循环语句loop处,再用p命令或者g 0018命令运行出循环。程序运行结束后,查看0:200内存中的内容:

Figure6. 查看0:200内存中的内容
欧克,程序拷贝成功。

[2] 程序中标号的含义

标号如l42.asm中的code最终被编译、连接程序处理为一个段的段地址,所以赋值DS为code后,DS就代表此段代码的段地址。


3 总结

  • 汇编程序经加载后各寄存器的值。见“程序加载后各寄存器中的值”。
  • debug理解“mov  al,[idata]”指令,[idata]被理解为偏移地址,此指令可实现将ds: idata内存单元中的值存到al中。masm理解“mov [idata], al”指令,[idata]被理解为常数idata。Debug和masm都将“mov al, [bx]”中的[bx]理解为偏移地址,即将ds:bx单元中的值存到al中。
  • 要完整的描述一个内存单元,需要两种信息:内存单元的地址;内存单元的长度(类型)。
  • 在DOS下,0:200 ~ 0:2FF空间没有系统或其它程序的数据或者代码,可往这段空间写数据。
  • 汇编程序中的标号代表了一个地址。如l41.asm中的code最终被编译、连接程序处理为一个段的段地址。s最终被处理为“mov [bx], bl”指令的地址。
  • CPU执行loop指令时,需进行两步操作:第一步,(cx) = (cx) – 1;第二步,判断cx中的值,不为0则转至loop后面的标号处执行程序。

[2014.11.23 - 15:55]
R《Hb》Note Over.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值