实验3 多个段的汇编源程序编写与调试
实验任务一:
使用任意文本编辑器,录入汇编源程序task1.asm
assume cs:code, ds:data
data segment
db 'Nuist'
db 5 dup(2)
data ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, 0b800H
mov es, ax
mov cx, 5
mov si, 0
mov di, 0f00h
s: mov al, [si]
and al, 0dfh
mov es:[di], al
mov al, [5+si]
mov es:[di+1], al
inc si
add di, 2
loop s
mov ah, 4ch
int 21h
code ends
end start
每一行代码的含义如下:
mov cx, 5 循环五次
mov si, 0 初始化 si
mov di, 0f00h 初始化 di
s: mov al, [si] 取数据段内对应字符
and al, 0dfh 0dfh的二进制形式为:1101 1111,and操作后实现的功能:将字符改为大写
mov es:[di], al 写入显存
mov al, [5+si] 为 al 赋数据段内的值
mov es:[di+1], al 为先前写入字符的字的高位赋值,以此附以字符颜色
inc si si + 1,移向数据段下一字符
add di, 2 di + 2,移向显存下一个字
loop s 循环执行
汇编、连接、运行后得到的结果:
使用debug工具对程序进行调试,执行到程序返回前,即line27之前,观察结果。

将db 5 dup(2) --> 改成: db 2,3,4,5,6后,重新汇编、链接、运行,观察结果。

猜测数值的作用是设置字体的颜色
实验任务二:
编写程序,在屏幕上以十进制整数形式打印输出这5个两位数
db 23, 50, 66, 71, 35
assume cs:code, ds:data data segment db 23,50,66,71,35 data ends code segment start: mov ax,data mov ds,ax mov dh,0ah mov di,0 mov cx,5 s: mov al,[di] mov ah,00h div dh add al,30h add ah,30h mov bx,ax inc di mov ah,2 mov dl,bl int 21h mov dl,bh int 21h mov dl,20h int 21h loop s mov ah,4ch int 21h code ends end start
执行结果:
![]()
实验任务三:
将下面的程序编译、连接。用debug加载、跟踪、然后回答问题
assume cs:code, ds:data, ss:stack data segment dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h data ends stack segment dw 0, 0, 0, 0, 0, 0, 0, 0 stack ends code segment start: mov ax,stack mov ss, ax mov sp,16 mov ax, data mov ds, ax push ds:[0] push ds:[2] pop ds:[2] pop ds:[0] mov ax,4c00h int 21h code ends end start
(1)data段中的数据为多少

(2)程序返回前,cs=076C,SS=076B,DS=076A

(3)程序加载后,code段的段地址为X,则data段的短地址为X-2,stack段的段地址为:X-1
实验任务四:
将下面的程序编译、连接,用debug加载、跟踪,然后回答问题
assume cs:code, ds:data, ss:stack data segment dw 0123h, 0456h data ends stack segment dw 0, 0 stack ends code segment start: mov ax,stack mov ss, ax mov sp,16 mov ax, data mov ds, ax push ds:[0] push ds:[2] pop ds:[2] pop ds:[0] mov ax,4c00h int 21h code ends end start
(1)程序返回前,data段中的数据为:

(2)程序返回前,cs= 076c、ss=076b、ds=076a 的值为:

(3)设程序加载后,code 段的段地址为 X,则 data 段的段地址为 X - 2,stack 段的段地址为 X - 1。
(4)对于如下定义的段:
name segment
...
name ends
如果段中的数据占 N 个字节,则程序加载后,该段实际占用的空间为: [N/16]*16,
实验任务五:
assume cs:code, ds:data, ss:stack code segment start: mov ax,stack mov ss, ax mov sp,16 mov ax, data mov ds, ax push ds:[0] push ds:[2] pop ds:[2] pop ds:[0] mov ax,4c00h int 21h code ends data segment dw 0123h, 0456h data ends stack segment dw 0,0 stack ends end start
(1)程序返回前,data 段中的数据为

(2)程序返回前,cs = 076A、ss = 076E 、ds = 076D

(3)设程序加载后,code 段的段地址为 X, 则 data 段的段地址为 X + 3,stack 段的段地址为 X + 4。
实验任务六:
如果将前三题中的最后一条伪指令“end start”改为“end”(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因。
改为end后,表明程序从cs:0开始执行,此时实验五仍然可以正确执行,因为实验五中data段和stack段在code段的后面。
实验任务七:
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 ; 在集成软件环境中,请将此处的段名称由c→改为c1或其它名称
db 8 dup(0)
c ends code segment
start:
mov ax,a
mov ds,ax
mov si,0
mov cx,4
s:
mov ax,[si]
add ax,[si+10h]
mov [si+20h],ax
add si,2
loop s
mov ax,4c00h
int 21h
code ends
end start

实验任务八:
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 8 dup(0) b ends code segment start: mov ax,a mov ds,ax mov ax,b mov ss,ax mov sp.16 mov cx,8 s:
push [si] add si,2 loop s
mov ax,4c00h int 21h code ends end start

实验总结:
1、当编写包含多个段的程序时,要用end指明程序开始的位置,否则程序默认从cs:0开始执行,会出错
2、db表示定义了一个字节数据,dw表示定义了一个字数据
3、段名就是段的地址,是一个常数,不能直接移入段寄存器中

浙公网安备 33010602011771号