《汇编语言》学习(五)循环

时间:2021-02-17 01:27:49

    《汇编语言》第五章主要介绍在汇编语言中如何使用循环和在循环中使用变量,以及使用循环从一段内存复制二进制信息到另一段内存,共三个话题。这三个话题的关键词(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”的代码,比较一下,是否正确。