实验3 多个段的汇编源程序编写与调试
1. 实验任务1
源代码文件task1.asm:
1 assume cs:code, ds:data 2 data segment 3 db 'Nuist' 4 db 2,3,4,5,6 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 12 mov ax, 0b800H 13 mov es, ax 14 15 mov cx, 5 16 mov si, 0 17 mov di, 0f00h 18 s: mov al, [si] 19 and al, 0dfh 20 mov es:[di], al 21 mov al, [5+si] 22 mov es:[di+1], al 23 inc si 24 add di, 2 25 loop s 26 27 mov ah, 4ch 28 int 21h 29 code ends 30 end start
1)阅读源程序,从理论上分析源代码的功能,尤其是line15-25,循环实现的功能是什么,逐行理解每条指令的功能。
源代码的主要功能:将数据段前五个字节单元“Nuist”转换为大写和数据段后五个字节单元中的数据一起保存至附加段中在屏幕上显示。
15 mov cx, 5 //设置循环次数为5 16 mov si, 0 //将0送到si 17 mov di, 0f00h //设置起始内存单元地址 18s: mov al, [si] //将数据段前五个字节的内存单元[si]送入al 19 and al, 0dfh //将字母将转换为大写 20 mov es:[di], al //将结果保存至附加段 21 mov al, [5+si] //将指针指向后五个字节的内存单元[5+si] 22 mov es:[di+1], al //将数据段后五个字节中相应的数据保存至大写字母后面 23 inc si //si加1 24 add di, 2 //di加2 25 loop s //循环
2)使用masm、link对task1.asm进行汇编、链接,得到可执行文件task1.exe,运行并观察结果。

3)使用debug工具对程序进行调试,执行到程序返回前,即line27之前,观察结果。

4)修改line4里5个字节单元的值,重新汇编、链接、运行,观察结果。
修改后的源代码如下:
1 assume cs:code, ds:data 2 data segment 3 db 'Nuist' 4 db 2,3,4,5,6 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 12 mov ax, 0b800H 13 mov es, ax 14 15 mov cx, 5 16 mov si, 0 17 mov di, 0f00h 18 s: mov al, [si] 19 and al, 0dfh 20 mov es:[di], al 21 mov al, [5+si] 22 mov es:[di+1], al 23 inc si 24 add di, 2 25 loop s 26 27 mov ah, 4ch 28 int 21h 29 code ends 30 end start
重新汇编、链接、运行,结果如下:

5)基于观察,分析、猜测这里的数值作用是什么。
分析可能是用来改变显示内容的颜色。
2. 实验任务2
已知数据段data中定义字节数据如下:
data segments db 23,50,66,71,35 data ends
编写程序,在屏幕上以十进制整数形式打印输出这5个两位数。
1)源代码如下:
1 assume cs:code,ds:data 2 data segment 3 db 23,50,66,71,35 4 data ends 5 code segment 6 start: 7 mov ax,data 8 mov ds,ax 9 mov di,0 10 mov cx,5 11 12 s1: mov ah,0 13 mov al,ds:[di] 14 mov bl,10 15 div bl 16 mov ds:[10+di],al 17 mov ds:[11+di],ah 18 19 mov ah,2 20 mov dl,ds:[10+di] 21 add dl,30h 22 int 21h 23 24 mov ah,2 25 mov dl,ds:[11+di] 26 add dl,30h 27 int 21h 28 29 mov ah,2 30 mov dl," " 31 int 21h 32 33 inc di 34 loop s1 35 36 mov ax,4c00h 37 int 21h 38 code ends 39 end start
2)运行结果截图如下:

3. 实验任务3
源代码如下:
1 assume cs:code, ds:data, ss:stack 2 data segment 3 dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h 4 data ends 5 6 stack segment 7 dw 0, 0, 0, 0, 0, 0, 0, 0 8 stack ends 9 10 code segment 11 start: mov ax,stack 12 mov ss, ax 13 mov sp,16 14 15 mov ax, data 16 mov ds, ax 17 18 push ds:[0] 19 push ds:[2] 20 pop ds:[2] 21 pop ds:[0] 22 23 mov ax,4c00h 24 int 21h 25 26 code ends 27 end start
回答教材中①②③三个问题。
①:反汇编查看data段中数据的截图。验证观察到的结果和理论分析是否一致。
1)在CPU执行程序,程序返回前,data段中数据为: 0123H,0456H,0789H,0ABCH,0DEFH,0FEDH,0CABH,0987H。
2)汇编、链接后查看到的:
3) 反汇编后查到的:

②:反汇编调试截图,即:在debug中,执行到程序返回前的调试截图。
由上图可知:CPU执行程序,程序返回前,cs=076CH,ss=076BH,ds= 076AH。
③:设程序加载后,code段的段地址为X,则data段的段地址为 X-2,stack段的段地址为X-1 。
4. 实验任务4
源代码如下:
1 assume cs:code, ds:data, ss:stack 2 data segment 3 dw 0123h, 0456h 4 data ends 5 6 stack segment 7 dw 0, 0 8 stack ends 9 10 code segment 11 start: mov ax,stack 12 mov ss, ax 13 mov sp,16 14 15 mov ax, data 16 mov ds, ax 17 18 push ds:[0] 19 push ds:[2] 20 pop ds:[2] 21 pop ds:[0] 22 23 mov ax,4c00h 24 int 21h 25 26 code ends 27 end start
回答教材中①②③④四个问题。
①CPU执行程序,程序返回前,data段中的数据为:0123H,0456H
②;反汇编调试截图,即:在debug中,执行到程序返回前的调试截图。

CPU执行程序,程序返回前,cs=076CH,ss=076BH,ds=076AH。
③设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1。
④:对于如下定义段:
name segment ... name ends
如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为(N/16+1)*16
5. 实验任务5
源代码如下:
1 assume cs:code, ds:data, ss:stack 2 3 code segment 4 start: mov ax,stack 5 mov ss, ax 6 mov sp,16 7 8 mov ax, data 9 mov ds, ax 10 11 push ds:[0] 12 push ds:[2] 13 pop ds:[2] 14 pop ds:[0] 15 16 mov ax,4c00h 17 int 21h 18 19 code ends 20 data segment 21 dw 0123h, 0456h 22 data ends 23 24 stack segment 25 dw 0,0 26 stack ends 27 end start
回答教材中①②③三个问题。
①:CPU执行程序,程序返回前,data段中的数据为:0123H,0456H
②反汇编调试截图,即:在debug中,执行到程序返回前的调试截图。


CPU执行程序,程序返回前,cs=076AH,ss=076EH,ds=076DH。
③设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4。
6. 实验任务6
如果将任务三到任务五的“end start”改为“end”,则哪个程序可以正常执行?说出原因?
答:只有任务5的汇编程序可以正常执行。因为若不指明入口位置,则程序会从所分配的空间开始执行,由于任务3和4的开头是数据段,会被当成指令读入;而任务5程序的代码段定义于数据段和栈段之前,在顺序执行的过程中会首先执行代码段,这样就不会因执行了数据段和栈段导致程序没有正常执行了。
7. 实验任务7
源代码如下:
1 assume cs:code 2 a segment 3 db 1,2,3,4,5,6,7,8 4 a ends 5 6 b segment 7 db 1,2,3,4,5,6,7,8 8 b ends 9 10 c segment ; 在集成软件环境中,请将此处的段名称由c→改为c1或其它名称 11 db 8 dup(0) 12 c ends 13 14 code segment 15 start: 16 mov ax,a 17 mov ds,ax 18 mov ax,b 19 mov es,ax 20 mov ax,c 21 mov ss,ax 22 mov bx,0 23 mov cx,8 24 s: mov ax,[bx] 25 mov ss:[bx],ax 26 mov ax,es:[bx] 27 add ss:[bx],ax 28 inc bx 29 loop s 30 mov ax,4c00h 31 int 21h 32 code ends 33 end start
附上在debug环境中,执行到程序返回前,查看逻辑段c的数据的截图,以此验证所编写的程序正确实现了题目要求。

反汇编:

运行至程序返回前,查看逻辑段c的数据:

8. 实验任务8
源代码如下:
1 assume cs:code 2 a segment 3 dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh 4 a ends 5 6 b segment 7 dw 8 dup(0) 8 b ends 9 10 code segment 11 start: 12 mov ax,a 13 mov ds,ax 14 mov ax,b 15 mov bx,0 16 mov ss,ax 17 mov sp,16 18 mov cx,8 19 s: push [bx] 20 add bx,2 21 loop s 22 mov ax,4c00h 23 int 21h 24 code ends 25 end start
附上在debug环境中,执行到程序返回前,查看逻辑段c的数据的截图,以此验证所编写的程序正确实现了题目要求。


浙公网安备 33010602011771号