实验3 多个段的汇编源程序编写与调试
一、实验目的
二、实验准备
三、实验内容
实验任务1
1 assume cs:code, ds:data 2 data segment 3 db 'Nuist' 4 db 5 dup(2) 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 ;//设置循环次数为5,因为nuist有五个字母 16 mov si, 0 ;//设置数据段地址偏移量 17 mov di, 0f00h ;//设置es附加段的地址偏移量 18 s: mov al, [si] ;//将数据段偏移地址为si的数据存入al 19 and al, 0dfh ;//dfh=11011111B,将al中的ASCII码的第五个位置为0,变为大写字母 20 mov es:[di], al ;将al存入偏移地址为di的附加段中 21 mov al, [5+si] ;将偏移地址为5+si的地址存入al 22 mov es:[di+1], al ;将al存入附加端偏移地址为di+1的内存 23 inc si ;si自加1 24 add di, 2 ;di+2 25 loop s ;循环s 26 27 mov ah, 4ch 28 int 21h 29 code ends 30 end start
使用masm、link对task1.asm进行汇编、链接,得到可执行文件task1.exe,运行并观察结果。

-g运行至27行处

修改成db 2,3,4,5后执行结果如下图

这里的数值的作用是修改显存显示内容的颜色。
实验任务2
task2.asm代码:
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 cx,5 10 mov bx,0 11 s: mov ah,0 12 mov al,ds:[bx] 13 mov dl,10 14 div dl 15 16 mov ds:[5],al//放商 17 mov ds:[6],ah //放余数 18 mov ah,2 19 mov dl,ds:[5] 20 add dl,30h//加30h,变为ASCII码值 21 int 21h 22 mov ah,2 23 mov dl,ds:[6] 24 add dl,30h 25 int 21h 26 mov dl,20h //输出空格,空格的ASCII为20h 27 int 21h 28 inc bx 29 loop s 30 31 mov ax,4c00h 32 int 21h 33 code ends 34 end start
使用masm、link工具对task2.asm进行汇编和链接

成功输出5个数
实验任务3
task3.asm源代码:
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 code ends 26 end start
使用masm、link工具对task3.asm进行汇编和链接

①CPU执行程序,程序返回前,data段中的数据:0123H, 0456H, 0789H, 0ABCH, 0DEFH, 0FEDH, 0CBAH, 0987H
②CPU执行程序,程序返回前,cs=076CH,ss=076BH,ds=076AH

③设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1
实验任务4
将下面的程序编译、连接,用Debug加载、跟踪,然后回答问题。
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

②CPU执行程序,程序返回前,可以得出cs=076CH,ss=076BH,ds=076AH
③设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1
④如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为(floor(N/16)+1)*16(向下取整)。
最少占用16个字节,然后以16的倍数增加,16 32 48
实验任务5
task5.asm源代码:
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

②CPU执行程序,程序返回前,cs=076AH,ss=076EH,ds=076DH
③设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4
实验任务6
如果将(1)、(2)、(3)题中最后一条伪指令“end start”改为“end”(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因。
答:第三题可以正确执行(task5.exe),因为如果他end start去掉,那么程序就会从默认的入口开始执行,默认的入口为code段,所以会从code段开始执行,
data段和stack段正好在code后面所以可以正确运行。
实验任务7
task7.asm源代码:
1 assume cs:code 2 a segment 3 db 1,2,3,4,5,6,7,8 4 a ends 5 b segment 6 db 1,2,3,4,5,6,7,8 7 b ends 8 c segment 9 db 8 dup(0) 10 c ends 11 code segment 12 start: 13 mov bx,0 14 mov cx,8 15 16 s: mov si,a 17 mov ds,si 18 mov al,ds:[bx] 19 20 mov si,b 21 mov ds,si 22 add al,ds:[bx] 23 24 mov si,c1 25 mov ds,si 26 mov ds:[bx],al 27 inc bx 28 loop s 29 30 mov ah,4ch 31 int 21h 32 code ends 33 end start
查看数据段c1的数值如下,成功相加

实验任务8
程序如下,编写code段中的代码,用push指令将a段中的前8个字型数据,逆序存储到b段中。
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 b segment 6 dw 8 dup(0) 7 b ends 8 code segment 9 start: 10 mov ax,b 11 mov ss,ax 12 mov sp,10h 13 mov ax,a 14 mov ds,ax 15 mov si,0 16 mov cx,8 17 s: push ds:[si] 18 add si,2 19 loop s 20 mov ah,4ch 21 int 21h 22 code ends 23 end start
反汇编,执行:

查看内存:

已完成逆序存储。
浙公网安备 33010602011771号