实验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来实现大小写字母的相互转换。

posted @ 2021-11-08 20:14  May==  阅读(19)  评论(3编辑  收藏  举报