这个要求来自王爽所著《汇编语言(第2版)》,是第5章实验4的(3)小题。原题是:下面的程序的功能是将"mov ax, 4c00h"之前的指令复制到内存0:200处,补全程序......"
题目原本是一个填空题,其中之一是确定需要复制数据(程序的代码)字节数。
首先,题目要求所编写程序的功能是复制该程序"mov ax, 4c00h"之前的指令到内存0:200处,所以可以确定,其中的指令不包括诸如“assume cs:code”之类的伪指令,而仅仅是代码段中的指令。因此,可以将数据段,也就是数据源的地址,设置为代码段。
mov ax, cs
mov ds, ax
其次,最重要的是确定需要复制的指令的字节数,这也是写这篇文章的主要内容。
有朋友说,可以先将要复制的字节数设置为0,而后利用Debug调试构建好的程序,手动比较程序中开始处的指令到"mov ax, 4c00h"指令之间的字节数,这一点,确实可以通过比较它们的内存地址算出来。虽然可以做出来,只是始终觉得,似乎有些不妥,可能是我的强迫症又犯了吧。
在汇编语言的loop指令中,loop指令会根据cx寄存器的值来决定是否执行循环语句题,loop之后紧跟的是一个标号,例如s,它代表的就是一个指令在内存中的地址。事实上,编译器也会在最后将s标号翻译为一个内存地址。
既然标号就是一个内存地址,我们就可以定义两个标号,通过这两个标号的差,来算出它们之间指令的字节数。所以在这个程序中,将开始处的指令设置为标号"start",将"mov ax, 4c00h"之前的上一条指令设置为标号"stop",需要复制的指令的字节数为"stop-start"。
下面是源代码,注意,该代码与文中提及的习题无关。
;将"mov ax, 4c00h"之前的指令复制到内存0:200处
;P121,《汇编语言(第2版)》,王爽
; BadTudou
; 2014年12月13日
assume cs:code
code segment
;设置源地址
start: mov ax, cs
mov ds, ax
;设置目标地址
mov ax, 0020h
mov es, ax
;设置偏移地址
mov bx, 0
;设置循环次数
mov cx, stop-start
;复制数据的循环语句体
s: mov al, ds:[bx]
mov es:[bx], al
inc bx
loop s
;正常结束程序
stop: mov ax, 4cooh
int 21h
code ends
end