汇编语⾔程序设计实验3多个段的汇编源程序编写与调试汇编语⾔程序设计实验3 多个段的汇编源程序编写与调试⼀、实验⽬的
1. 理解和掌握将数据、代码、栈放⼊不同逻辑段的程序的编写和调试
2. 理解具有多个段的汇编源程序对应的⽬标程序执⾏时,内存分配⽅式
3. 掌握⼤⼩写字符的转换⽅法、数字字符和数值之间的转换⽅法
4. 理解并掌握各种寻址⽅式的灵活应⽤
5. 掌握汇编指令loop, and, or,div, mul的⽤法
⼆、实验内容及结果
(⼀)实验任务⼀
使⽤任意⼀款⽂本编辑器,编写8086汇编源程序task1.asm。
源代码如下:
assume cs:code, ds:data
now什么意思
data gment
db 'Nuist'
db 5 dup(2)
data ends
code gment
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,循环实现的功能是什么,逐⾏理解每条指
令的功能。
使⽤masm、link对task1.asm进⾏汇编、链接,得到可执⾏⽂件,运⾏并观察结果。
使⽤debug⼯具对程序进⾏调试,执⾏到程序返回前,即line27之前,观察结果。
timer修改line4⾥5个字节单元的值,重新汇编、链接、运⾏,观察结果。
1、具体的汇编、链接过程可以参考《汇编语⾔程序设计实验2 汇编源程序编写与汇编、调试》。运⾏⽂件,得到结果:
2、使⽤debug⼯具对程序进⾏调试
⾸先使⽤r命令查看寄存器中的值,再使⽤g命令执⾏到程序返回前,即line27之前,结果如下所⽰:
3、修改line4⾥5个字节单元的值:
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 gments
db 23, 50, 66, 71, 35
data ends
编写程序,在屏幕上以⼗进制整数形式打印输出这5个两位数。程序如下所⽰:assume cs:code,ds:data
data gmentpierre
db 23,50,66,71,35
data ends
code gment
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)
代码为:
odor
assume cs:code, ds:data, ss:stack
data gmentegr
dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
data ends
stack gment
dw 0, 0, 0, 0, 0, 0, 0, 0
stack ends
code gment
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 gment
mov ax, 20h
mov ds, ax
mov bx, 0
mov cx, 40hcouture
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 gment
dw 0123h, 0456h
data ends
stack gment
dw 0, 0
stack ends
code gment
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 gment
......
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 gment
start: mov ax,stack
there is no planmov 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 gment
dw 0123h, 0456h
data ends
stack gment
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 gment
db 1,2,3,4,5,6,7,8
a ends
b gment
db 1,2,3,4,5,6,7,8
b ends
cz gment
db 0,0,0,0,0,0,0,0
cz ends
code gment
start:
mov ax,a
mov ds,ax ;ds指向a段
mov ax,b
mov es,ax ;es指向b段