实验3 多个段的汇编源程序编写与调试

一、实验目的

1. 理解和掌握将数据、代码、栈放入不同逻辑段的程序的编写和调试  2. 理解具有多个段的汇编源程序对应的目标程序执行时,内存分配方式  3. 掌握大小写字符的转换方法、数字字符和数值之间的转换方法
4. 理解并掌握各种寻址方式的灵活应用
5. 掌握汇编指令loop, and, or,div, mul的用法  

二、实验准备

复习教材chapter 6-8章。
  • chapter 6 包含多个段的程序
  • chapter 7 更灵活的定位内存地址的方法 
  • chapter 8 数据处理的两个基本问题
   

三、实验内容

1. 实验任务1

使用任意文本编译器,录入汇编源程序task1.asm。

 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
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

阅读源程序,从理论上分析源代码的功能,尤其是line15-25,循环实现的功能是什么,逐行理解每条指令的功能。

  • 使用masm、link对task1.asm进行汇编、链接,得到可执行文件task1.exe,运行并观察结果。
  • 使用debug工具对程序进行调试,执行到程序返回前,即line27之前,观察结果。
  • 修改line4里5个字节单元的值,重新汇编、链接、运行,观察结果。
1 db 5 dup(2)
2 --> 改成:
3 db 2,3,4,5,6
基于观察,分析、猜测这里的数值作用是什么。  

2. 实验任务2

已知数据段data中定义字节数据如下:

1 data segments
2       db 23,50,66,71,35
3 data ends

编写程序,在屏幕上以十进制整数形式打印输出这5个两位数。

提示:

1个两位数如何输出
思路如下:

实验3 多个段的汇编源程序编写与调试

具体处理步骤如下:
第1步,利用除法指令div,计算出每个数位上的数值。
第2步,利用数值和数字字符之间ascII码的关系,把数值→数字字符
第3步,利用系统功能调用int 21h中的2号子功能,输出单个字符。


int 21h中的2号子功能说明如下:
功能:输出单个字符
用法:

1 mov ah,2
2 mov d1,xx      ;xx是待输出的字符,或其ASCII码值
3 int 21h

5个两位数如何输出
利用loop指令,以及,灵活的寻址方式。

 

3. 实验任务3

教材「实验5 编写、调试具有多个段的程序」(1)

程序源码见task3.asm。 

 

4. 实验任务4

教材「实验5 编写、调试具有多个段的程序」(2) 

程序源码见task4.asm。

 

5. 实验任务5

教材「实验5 编写、调试具有多个段的程序」(3)

程序源码见task5.asm。 

 

6. 实验任务6

教材「实验5 编写、调试具有多个段的程序」(4) 

 

7. 实验任务7

教材「实验5 编写、调试具有多个段的程序」(5) 

程序源码见task7.asm。

注*: 如果在集成软件环境下编写、汇编这个实验任务,请将段名为c的逻辑段,名称改为c1或别的标识 符。由于早期一些指令集中使用c指代寄存器,如不更正,有些汇编器在汇编时会报错。

1 c segment      ;段名称改成c1或别的合法的标识符
2      ...
3 c ends            ;c1

8. 实验任务8

教材「实验5 编写、调试具有多个段的程序」(6)

程序源码见task8.asm。

 

四、实验结论

1. 实验任务1

task1:

 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
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

使用masm,link对task1.asm进行汇编,链接,得到可执行文件,运行并观察结果:

实验3 多个段的汇编源程序编写与调试

 使用debug工具对程序进行调试:

实验3 多个段的汇编源程序编写与调试实验3 多个段的汇编源程序编写与调试

 修改line4里5个字节单元的值,重新汇编、链接、运行,观察结果。

1 db 5 dup(2)
2 --> 改成:
3 db 2,3,4,5,6

实验3 多个段的汇编源程序编写与调试

 猜想:修改之后字符颜色发生了变化,内容没有变化。通过分析可以得到: db 5 dup(2) 表示分配5个字节内存空间并初始化为2, db 2,3,4,5,6 表示分配5个字节内存空间并相应的赋值为2,3,4,5,6。通过上面的结果观察可知,修改的数值对应着字符的颜色,对内容并无影响。

 

2. 实验任务2

 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

 实验3 多个段的汇编源程序编写与调试

 实验3 多个段的汇编源程序编写与调试

 

 

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

实验3 多个段的汇编源程序编写与调试

实验3 多个段的汇编源程序编写与调试

(1)运行之后,发现数据段的内容并没有改变:

(2)在程序返回前,cs=076C,ss=076B,ds=076A (3)设程序加载后,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

实验3 多个段的汇编源程序编写与调试

 

 (1)data段数据并未发生变化:0123h,0456h

(2)在程序返回前,cs=076C,ss=076B,ds=076A

(3)设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1

(4)对于如下定义的段:

1 name segment
2   ...
3 name ends

如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为 16×(N/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

实验3 多个段的汇编源程序编写与调试

(1)CPU执行程序,程序返回前,data段中的数据为 0123H,0456H

(2)CPU执行程序,程序返回前,cs=076AH,ss=076EH,ds=076DH。

(3)设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4。

 

6. 实验任务6

如果将(1)、(2)、(3)题中的最后一条伪指令“end start”改为“end”(也就是说,不指明程序的入口),则哪个程序仍然可以运行?请说明原因。

答:只有任务5的汇编程序可以正常执行。因为任务5程序的代码段定义于数据段和栈段之前,在顺序执行的过程中会首先执行code segment,而不会因执行了data segment和stack segment导致程序出现不符合预期的情况。

 

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 c1 segment   ; 在集成软件环境中,请将此处的段名称由c→改为c1或其它名称
11   db 8 dup(0)
12 c1 ends
13 
14 code segment
15 start:
16       mov ax,a
17       mov ds,ax
18       mov cx,8
19       mov si,0
20 
21 s:   mov ax,[si]
22       add ax,[si+10H]
23       mov [si+20H],ax
24       inc si
25       loop s
26       mov ax,4c00h
27       int 21h
28 code ends
29 end start

实验3 多个段的汇编源程序编写与调试

实验3 多个段的汇编源程序编写与调试

 

 

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  
15        mov ax,b
16        mov ss,ax
17        mov sp,16
18        mov si,0
19  
20        mov cx,8
21  
22 s:     push ds:[si] 
23        add  si,2
24        loop s
25        mov ax,4c00h
26        int 21h
27 code ends
28 end start

实验3 多个段的汇编源程序编写与调试

 

 

 

上一篇:Session原理


下一篇:C++中关于内存的总结