《汇编语言》第五章主要介绍在汇编语言中如何使用循环和在循环中使用变量,以及使用循环从一段内存复制二进制信息到另一段内存,共三个话题。这三个话题的关键词(key word)分别是:loop、[bx]和segment prefix(段前缀)。
本文我将对这三个话题进行简单描述,并给出一张思维导图总结该章节的知识点,最后重点讨论该章节的课后实验题。
一、知识点总结
1,循环
汇编语言中,编写一个简单的循环,最主要应用loop指令和标号(mark)。其中,loop指令包含两个步骤:
1)(cx)=(cx)-1;
2)判断cx是否为0,然后决定跳转到标号表示的指令地址或执行后面的代码。
如下,是一个计算2^12的汇编程序
assume cs:code
code segment
mov ax,2
mov cx,12
s:add ax,ax
loop s
mov ax,4c00h
int 21h
code ends
end
2,在循环中使用变量
举一个简单例子:计算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
由于循环内,需要递增内存地址,不能用常量,需要设计一个变量,随着循环递增。
3,内存复制
将内存ffff:0 - ffff:b单元中的数据复制到0:200 - 0:20b单元中
assume cs:code
code segment
mov ax,0ffffh
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
如上,在循环中,直接使用显示段前缀,即可实现内存段的切换。简化了内存复制的步骤。
二、知识图谱
三、实验题
1,编程,向内存0:200 - 0:23F依次传送数据0 - 63(3FH),程序只能使用9条指令,包括退出指令。
assume cs:code
code segment
mov ax,0020h
mov ds,ax
mov bx,0
mov cx,40h
s:mov [bx],bx
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
2,代码补全
将“mov ax,4c00h”之前的指令复制到内存0:200处。
assume cs:code
code segment
mov ax,<span style="color:#ff0000;">cs</span>
mov ds,ax
mov ax,0020h
mov es,ax
mov bx,0
mov cx,<span style="color:#ff0000;">17h</span>
s:mov al,[bx]
mov es:[bx],al
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
问题:
1)复制的是什么?从哪里到哪里?
复制的是机器码(二进制信息),从CS:IP开始到“mov ax,4c00h”之前。其中,CS:IP即代码段的起始地址。
2)复制的是什么?有多少个字节?你如何知道要复制的字节的数量。
该段代码使用的是按字节复制“mov al,[bx]”。我的办法是先估一个字节数,如10,填进代码,然后在debug下反汇编,看看真实的字节数
如上图所示,反汇编“cs:0”开始的代码,到“mov ax,4c00h”,看第一列,它的地址是0017(h)。故,需要复制的代码字节数为17H。
执行到0017后(g 0017),可以用“u命令”反汇编“0020:0”的代码,比较一下,是否正确。