实验2 多个逻辑段的汇编源程序编写与调试
实验结论
1. 实验任务1
任务1-1
task1_1.asm源码
1 assume ds:data, cs:code, ss:stack 2 3 data segment 4 5 db 16 dup(0) ; 预留16个字节单元,初始值均为0 6 7 data ends 8 9 stack segment 10 11 db 16 dup(0) ;预留16个字节单元,初始值均为0 12 13 stack ends 14 15 code segment 16 17 start: 18 19 mov ax, data 20 21 mov ds, ax 22 23 mov ax, stack 24 25 mov ss, ax 26 27 mov sp, 16 ; 设置栈顶 28 29 mov ah, 4ch 30 31 int 21h 32 33 code ends 34 35 end start
task1_1调试到line17结束、line19之前截图
问题回答
① 在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = __076A__, 寄存器(SS) = ___076B_, 寄存器(CS) = _076C___
② 假设程序加载后,code段的段地址是X,则,data段的段地址是_X-2___, stack的段地址是
_X-1___。
任务1-2
任务task1_2.asm源码
1 assume ds:data, cs:code, ss:stack 2 3 data segment 4 5 db 4 dup(0) ; 预留4个字节单元,初始值均为0 6 7 data ends 8 9 stack segment 10 11 db 8 dup(0) ; 预留8个字节单元,初始值均为0 12 13 stack ends 14 15 code segment 16 17 start: 18 19 mov ax, data 20 21 mov ds, ax 22 23 mov ax, stack 24 25 mov ss, ax 26 27 mov sp, 8 ; 设置栈顶 28 29 mov ah, 4ch 30 31 int 21h 32 33 code ends 34 35 end start
task1_2调试到line17结束、line19之前观察寄存器DS, CS, SS值的截图
问题回答
① 在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = _076A___, 寄存器(SS) = _076B___, 寄存器(CS) = __076C__
② 假设程序加载后,code段的段地址是X,则,data段的段地址是_X-2___, stack的段地址是
_X-1___。
任务1-3
任务task1_3.asm源码
1 assume ds:data, cs:code, ss:stack 2 3 data segment 4 5 db 20 dup(0) ; 预留20个字节单元,初始值均为0 6 7 data ends 8 9 stack segment 10 11 db 20 dup(0) ; 预留20个字节单元,初始值均为0 12 13 stack ends 14 15 code segment 16 17 start: 18 19 mov ax, data 20 21 mov ds, ax 22 23 mov ax, stack 24 25 mov ss, ax 26 27 mov sp, 20 ; 设置初始栈顶 28 29 mov ah, 4ch 30 31 int 21h 32 33 code ends 34 35 end start
task1_3调试到line17结束、line19之前观察寄存器DS, CS, SS值的截图
问题回答
① 在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = __076A__, 寄存器(SS) = __076C__, 寄存器(CS) = __076E__
② 假设程序加载后,code段的段地址是X,则,data段的段地址是__X-4__, stack的段地址是
__X-2__。
任务1-4
任务task1_4.asm源码
1 assume ds:data, cs:code, ss:stack 2 3 code segment 4 5 start: 6 7 mov ax, data 8 9 mov ds, ax 10 11 mov ax, stack 12 13 mov ss, ax 14 15 mov sp, 20 16 17 mov ah, 4ch 18 19 int 21h 20 21 code ends 22 23 data segment 24 25 db 20 dup(0) 26 27 data ends 28 29 stack segment 30 31 db 20 dup(0) 32 33 stack ends 34 35 end start
task1_4调试到line17结束、line19之前观察寄存器DS, CS, SS值的截图
问题回答
① 在debug中将执行到line9结束、line11之前,记录此时:寄存器(DS) = __076C__, 寄存器(SS) = __076E__, 寄存器(CS) = _076A___
② 假设程序加载后,code段的段地址是X,则,data段的段地址是__X+2__, stack的段地址
是__X+4__。
任务1-5
基于上述四个实验任务的实践、观察,总结并回答:
① 对于如下定义的段,程序加载后,实际分配给该段的内存空间大小是__((FLOOR)N/16+1)*16__。
xxx segment
db N dup(0)
xxx ends
② 如果将程序task1_1.asm, task1_2.asm, task1_3.asm, task1_4.asm中,伪指令 end start 改成end , 哪一个程序仍然可以正确执行。结合实践观察得到的结论,分析、说明原因。
task1_4.asm可以正确执行,不写start,程序会从头开始执行,写start,程序会从start:标号处开始执行。以task1_2为例,去掉start后如图所示:
用r命令查看cs:ip的内容,发现其指向的是物理地址为076A0H的内容 0000,
说明,将end stack改为end后,程序将从头开始执行。
2. 实验任务2
汇编源代码
1 assume cs:code 2 3 code segment 4 5 start: 6 7 mov ax,0b8f0h 8 9 mov es,ax 10 11 mov bx,0 12 13 mov cx,160 14 15 s: mov word ptr es:[bx],0403h 16 17 inc bx 18 19 inc bx 20 21 loop s 22 23 24 25 mov ax,4c00h 26 27 int 21h 28 29 code ends 30 31 end start
运行结果截图
3. 实验任务3
补充完整后的汇编源代码
1 assume cs:code 2 3 data1 segment 4 5 db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers 6 7 data1 ends 8 9 10 11 data2 segment 12 13 db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0 ; ten numbers 14 15 data2 ends 16 17 18 19 data3 segment 20 21 db 16 dup(0) 22 23 data3 ends 24 25 26 27 code segment 28 29 start: 30 31 mov bx,0 32 33 mov cx,10 34 35 s:mov dx,0 36 37 38 39 mov ax,data1 40 41 mov ds,ax 42 43 add dl,[bx] 44 45 46 47 mov ax,data2 48 49 mov ds,ax 50 51 add dl,[bx] 52 53 54 55 mov ax,data3 56 57 mov ds,ax 58 59 mov [bx],dl 60 61 inc bx 62 63 loop s 64 65 66 67 mov ah,4ch 68 69 int 21h 70 71 code ends 72 73 end start
在debug中加载、反汇编、调试截图
要求给出,在数据项依次相加之前,查看逻辑段data1, data2, data3对应的内存空间数据原始值的debug命令和截图
以及,依次相加之后,查看逻辑段data1, data2, data3对应的内存空间数据原始值的debug命令和截图
4. 实验任务4
补充完整后的汇编源代码
1 assume cs:code 2 3 4 5 data1 segment 6 7 dw 2, 0, 4, 9, 2, 0, 1, 9 8 9 data1 ends 10 11 12 13 data2 segment 14 15 dw 8 dup(?) 16 17 data2 ends 18 19 20 21 code segment 22 23 start:mov ax,data1 24 25 mov ds,ax 26 27 28 29 mov ax,data2 30 31 mov ss,ax 32 33 mov sp,16 34 35 36 37 mov bx,0 38 39 mov cx,8 40 41 s:push [bx] 42 43 inc bx 44 45 inc bx 46 47 loop s 48 49 50 51 mov ah, 4ch 52 53 int 21h 54 55 code ends 56 57 end start
在debug中加载、反汇编、调试截图
要求给出,在程序退出前,使用d命令查看数据段data2对应的内存空间的截图。
5. 实验任务5
task5.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
运行结果截图
使用debug工具对程序进行调试,使用g命令一次性执行到程序返回前(即ine25执行之后、line27
执行之前)的截图
源代码中line19的作用是?
And al,0dfh是将第五上的数值设为零,若是小写字母,它的第五位为1,遇到该指令,将1变为0,即-32,变为对应的大写字母,大写字母则不发生改变。
源代码中data段line4的字节数据的用途是?
将line4里5的字节单元的值都改为2是,NUIST都变为绿色,如图所示:
可以推测,line4中的内容存放在高地址单元,指定显示字符的显示属性,如颜色等。
6. 实验任务6
task6.asm源代码
1 assume cs:code, ds:data 2 3 data segment 4 5 db 'Pink Floyd ' 6 7 db 'JOAN Baez ' 8 9 db 'NEIL Young ' 10 11 db 'Joan Lennon ' 12 13 data ends 14 15 16 17 code segment 18 19 start: 20 21 mov ax,data 22 23 mov ds,ax 24 25 mov bx,0 26 27 mov cx,4 28 29 s:or byte ptr [bx],20h 30 31 add bx,16 32 33 loop s 34 35 36 37 mov ah, 4ch 38 39 int 21h 40 41 code ends 42 43 end start
在debug中加载、反汇编、调试截图
要求给出,在程序退出前,使用d命令查看数据段data对应的内存空间的截图。
7. 实验任务7
task7.asm源码
1 assume cs:code, ds:data, es:table 2 3 data segment 4 db '1975', '1976', '1977', '1978', '1979' ;20个字节单元 5 dw 16, 22, 382, 1356, 2390 ;10个字节单元 6 dw 3, 7, 9, 13, 28 ;10个字节单元 7 data ends 8 9 table segment 10 db 5 dup( 16 dup(' ') ) ; 11 table ends 12 13 code segment 14 start: 15 mov ax,table 16 mov ds,ax 17 18 mov ax,data 19 mov es,ax 20 21 mov bx,0 22 mov cx,5 23 mov si,0 ;table偏移地址 24 25 s:mov ax,es:[bx] ;年份 26 mov [si],ax 27 mov ax,es:[bx+2] 28 mov [si+2],ax 29 add bx,4 30 add si,16 31 loop s 32 33 mov bx,20 34 mov cx,5 35 mov si,0 36 s1:mov ax,es:[bx];收入 37 mov [si+5],ax 38 mov word ptr [si+7],0000h 39 add si,16 40 add bx,2 41 loop s1 42 43 mov bx,30 44 mov cx,5 45 mov si,0 46 s2:mov ax,es:[bx] 47 mov [si+10],ax 48 add si,16 49 add bx,2 50 loop s2 51 52 mov cx,5 53 mov si,5 54 s3:mov ax,[si] 55 mov dx,[si+2] 56 div word ptr [si+5] 57 mov [si+8],ax 58 add si,16 59 loop s3 60 61 mov ah, 4ch 62 int 21h 63 code ends 64 end start
调试截图
查看table段原始数据信息截图
在debug中运行到程序退出之前,使用d命令查看table段对应的内存空间的截图,确认信息是
否按要求结构化地写入到指定内存
实验总结
通过本次实验,我有了如下收获:
①使用寄存器相对寻址方式时,只能使用BX,BP,SI,DI,即方括号里必须是变址(index,指SI,DI)或基址寄存器(base,指BX,BP)寄存器。
②8086的显存空间的地址是B8000H~BFFFFH,共32KB空间,为80x25彩色字符模式的显示缓冲区。向这个地址空间写入数据,写入的内容将立即出现在显示器上。
③ word ptr指定访问的内存单元为一个字单元,byte ptr则表示指定访问的内存单元为一个字节单元
④ 在遇到大小写字母问题时,可以熟练使用and,or命令指定特定位置为0,1来实现大小写字母的相互转换。