首页 > 编程语言 > 详细

汇编语言程序设计 实验3 多个段的汇编源程序编写与调试

时间:2020-11-23 20:08:06      阅读:28      评论:0      收藏:0      [点我收藏+]

汇编语言程序设计 实验3 多个段的汇编源程序编写与调试

一、实验目的

1. 理解和掌握将数据、代码、栈放入不同逻辑段的程序的编写和调试
2. 理解具有多个段的汇编源程序对应的目标程序执行时,内存分配方式
3. 掌握大小写字符的转换方法、数字字符和数值之间的转换方法
4. 理解并掌握各种寻址方式的灵活应用
5. 掌握汇编指令loop, and, ordiv, mul的用法

二、实验内容及结果

(一)实验任务一

使用任意一款文本编辑器,编写8086汇编源程序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

阅读源程序,从理论上分析源代码的功能,尤其是line15-25,循环实现的功能是什么,逐行理解每条指
令的功能。
使用masmlinktask1.asm进行汇编、链接,得到可执行文件task1.exe,运行并观察结果。
使用debug工具对程序进行调试,执行到程序返回前,即line27之前,观察结果。
修改line45个字节单元的值,重新汇编、链接、运行,观察结果。
1、具体的汇编、链接过程可以参考《
汇编语言程序设计 实验2 汇编源程序编写与汇编、调试》。运行ex1.exe文件,得到结果:

技术分享图片

2、使用debug工具对程序进行调试

首先使用r命令查看寄存器中的值,再使用g命令执行到程序返回前,即line27之前,结果如下所示:

技术分享图片

3、修改line45个字节单元的值:

db 5 dup(2)
--> 改成:
db 2,3,4,5,6

重新汇编、链接、运行,结果如下所示:

技术分享图片

 从这里已经可以看出data段line4的字节数据的用途是 决定ASCII码字符的颜色属性。

其中

mov cx, 5 //循环5次
        mov si, 0 //将0送到si寄存器中
        mov di, 0f00h//设置初始地址
s:      mov al, [si]//将[si]的值送入al
        and al, 0dfh//转换字母为大写字母
        mov es:[di], al//将结果保存至显示缓冲区
        mov al, [5+si]//将第si+5个字节送入al
        mov es:[di+1], al//保存数据
        inc si//si+1
        add di, 2//di+2
        loop s

(二)实验任务二

已知数据段data中定义字节数据如下所示: 

data segments
db 23, 50, 66, 71, 35
data ends

编写程序,在屏幕上以十进制整数形式打印输出这5个两位数。 程序如下所示:

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 di,0
mov cx,5

s1: mov ah,0
mov al,ds:[di]
mov bl,10
div bl
mov ds:[10+di],al
mov ds:[11+di],ah

mov ah,2
mov dl,ds:[10+di]
add dl,30h
int 21h

mov ah,2
mov dl,ds:[11+di]
add dl,30h
int 21h

mov ah,2
mov dl," "
int 21h

inc di
loop s1

mov ax,4c00h
int 21h
code ends
end start

技术分享图片

(三)实验任务三

教材「实验5 编写、调试具有多个段的程序」(1)

代码为:

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

技术分享图片

 技术分享图片

 

①CPU执行程序,程序返回前,data段中的数据 不变 

②CPU执行程序,程序返回前,CS=076C,SS=0769,DS=075A (与自己系统有关)

③设程序加载后,CODE段的段地址为X,则DATA段的段地址为 X-2 ,STACK段的段地址为 X-1 

(四)实验任务四

「实验5 编写、调试具有多个段的程序」(2) 

代码如下所示:

assume cs:code
code segment
mov ax, 20h
mov ds, ax
mov bx, 0
mov cx, 40h
mov al, 0
s:mov [bx], al
inc al
inc bx
loop s
mov ax, 4c00h
int 21h
code ends
end

运行结果如下所示:

 

2、选做部分
利用栈的特性,综合使用loop,push实现(限定仅使用8086中已学过指令实现),编写源程序
灵活使用debug的t命令、g命令、p命令调试。在程序退出前,用d命令查看0:200~0:23F,确认是否将0~3F传送至此段内存区域。  

代码如下所示:

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

运行结果如下所示:

 技术分享图片

①CPU执行程序,程序返回前,data段中的数据为多少?

执行程序后,data段有16个字节空间,前两个字数据不变,其余为00补全了。

②CPU执行程序,程序返回前,CS=076C,SS=076B,DS=076A 

③设程序加载后,CODE段的段地址为X,则DATA段的段地址为 X-2 ,STACK段的段地址为 X-1 

对于如下定义的段:

name segment

     ......

name ends

       如果段中数据位N个字节,程序加载后,该段实际占据空间为:(N/16的取整数+1)*16个字节

       如果N小于16,那么实际占用16个字节(理解这个小问题);如果N大于16,那么实际占用(N/16的取整数+1)*16个字节。其实都是这个公式。

(五)实验任务五

「实验5 编写、调试具有多个段的程序」(3)

代码为:

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

技术分享图片

 

①CPU执行程序,程序返回前,data段中的数据为多少?

执行程序后,data段有16个字节空间,前两个字数据不变,其余为00补全了。

②CPU执行程序,程序返回前,CS=076A,SS=076E,DS=076D 

③设程序加载后,CODE段的段地址为X,则DATA段的段地址为 X+3 ,STACK段的段地址为 X+4 

(六)实验任务六

「实验5 编写、调试具有多个段的程序」(4)

如果将(1)、(2)、(3)题中的最后一条伪指令“end start”改为“end”(也就是说不指明程序的入口),则那个程序仍然可以正确执行?请说明原因。

      答案:如果不指名程序的(code段的)入口,并且使用end替换end start,都能正常运行。但只有(3)题中程序可以正确的执行(因为只有它是在内存中可执行代码在最前面)。

      讲解:因为如果不指名入口,程序会从加载进内存的第一个单元起开始执行,前二个题中,定义的是数据,但CPU还是将数据当做指令代码执行了。只不过程序执行时逻辑上是错误了。但真的能执行的。

      如果指明了程序的入口,CPU会直接从入口处开始执行真正的机器码,直到遇到中断指令返回。此种方式能够确保程序逻辑上的正确。因此有必要为程序来指明入口。

(七)实验任务七

「实验5 编写、调试具有多个段的程序」(5)

源码如下:

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

cz segment

   db 0,0,0,0,0,0,0,0

cz ends

code segment

start:

   mov ax,a

   mov ds,ax           ;ds指向a段

 

   mov ax,b

   mov es,ax           ;es指向b段

 

   mov bx,0

   mov cx,8            ;计算8次,故计数器为8

s:

   mov dl, [bx]       ;将ds:[bx]内存单元按字节送入dl,此循环用到ax

   add dl, es:[bx]     ;将ds:[bx]与es:[bx]内存单元值相加

   push ds             ;保护ds值,因为下面用到ds了

   mov ax, cz         ;我的编译器不认C这个段的标号,故改成了CZ

   mov ds, ax         ;将ds指向cz段

   mov [bx], dl       ;将dl(a和b相对应内存单元内容之和)写入cz中

   pop ds             ;将ds恢复

   inc bx             ;bx递增

   loop s

   

   mov ax,4c00h

   int 21h

code ends

end start

结果如下:

技术分享图片

 

 

(八)实验任务八

「实验编写、调试具有多个段的程序」(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:
mov ax,b
mov ss,ax
mov sp,16
mov ax,a
mov ds,ax
mov cx,8
mov bx,0
s0:push ds:[bx]
add bx,2
loop s0
mov cx,8
mov ax,4c00h
int 21h
code ends

end start

结果如下:

技术分享图片

三、实验总结

在完成任务345的时候突然有一点点搞不明白为什么是这样?看cx,程序加载时,我们发现cx=0044,含义:此程序所有机器码占用的空间是44H=68字节,data和stack由于定义的都是小于16个字节,一律按照16个字节分配空间,其余补00;剩余的36个字节就是code段真正的可执行的机器码。由于code段不足48个字节(3*16),故程序加载时也补0了

 

汇编语言程序设计 实验3 多个段的汇编源程序编写与调试

原文:https://www.cnblogs.com/amikeco/p/14010989.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!