6.1 ~ 6.3
《汇编语言(第3版)》6.1 ~ 6.3、《零基础入门学习汇编语言》P29 ~ 31
第六章 包含多个段的程序
6.1 在代码段中使用数据
dw 即 define word,用来定义字型数据,数据之间以逗号分隔。
end 除了通知编译器程序结束外,还可以通知编译器程序的入口在什么地方。
实验 5 编写、调试具有多个段的程序
看一个程序要从代码段开始看,数据段存放的数据没有意义,数据段中的数据是否被使用取决于代码段。 代码段从 end 后的标号开始,end 后的标号是哪里,哪里就是开始。
(5)程序如下,编写 code 段中的代码,将 a 段和 b 段中的数据依次相加,将结果存到 c 段中。
assume cs:code
a segment
db 1,2,3,4,5,6,7,8
a ends
b segment
db 1,2,3,4,5,6,7,8
b ends
c segment
db 0,0,0,0,0,0,0,0
c ends
code segment
start:
?
code ends
end start
博主的思路是(不是权威,也不一定是最好,仅仅只是博主的思路,不足之处还请指出)
- db 定义了 8 个字节型数据,一个 8086 CPU 的通用寄存器是 16 位的,只能存放 2 个字节,所以想简单的利用 add dx,ax 此类操作直接运算肯定不行
- 所以此处必定需要循环来完成。循环的思路确定了,那么要循环几次呢?即 (cx)=?
- 循环的目的是将两段的 8 个字节依次相加,而一个通用寄存器的容量是 2 个字节,所以我们可以将 8 个字节的数据,分 4 次循环来相加。(也可以简单的就分 8 次循环相加,这里是考虑最高效原则)
- (cx)=4 也确定了,那需要哪些元素(寄存器)来参与呢?我们需要先把 a segment 的数据放入一个段中,所以 ds 数据段寄存器肯定是要加入的
- 有段寄存器 ds,那也就少不了 bx 用来放偏移地址、ax 充当 ds 的媒介,用来告诉 ds 段寄存器的段地址
- 那么既然 ax 不能用了,bx 放偏移地址了,cx 用来告诉循环要几次了,要相加的数据放在哪里呢?
- 所以我们暂时借来 dx 用来存放及相加数据。注意 dx 一定得初始化为 0,好让它干干净净的存放要相加的数据
mov bx,0
mov dx,0
mov cx,4
s:
mov ax,a
mov ds,ax
mov dx,[bx]
mov ax,b
mov ds,ax
add dx,[bx]
mov ax,c
mov ds,ax
mov [bx],dx
add bx,2
loop s
mov ax,4c00h
int 21h
(6)程序如下,编写 code 段中的代码,用 push 指令将 a 段中的前 8 个字型数据,逆序存储到 b 段中。
assume cs:code
a segment
dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh
a ends
b segment
dw 0,0,0,0,0,0,0,0
b ends
code segment
start:
?
code ends
end start
博主的思路是(不是权威,也不一定是最好,仅仅只是博主的思路,不足之处还请指出)
- 此题与上题的区别在于这一次定义的是 dw 字型数据,所以前 8 个字型数据相加,就不能省略为 4 次循环,还是老老实实需要 8 次循环,即 (cx)=8
- 题目要求用 push,所以必定需要引入栈段的思想,而前 8 位字型数据,占用 16 位的空间,故 ss 栈段指针需要指向第 17 位,即 (sp)=10h(栈段第一位从 0 开始)
- 把 a 段 push 进 b 段,所以 b segment 做栈段,a segment 做数据段
mov ax,a
mov ds,a
mov bx,0
mov ax,b
mov ss,ax
mov sp,10h
mov cx,8
s:
push [bx]
add bx,2
loop s
mov ax,4c00h
int 21h