实验5 编写、调试具有多个段的程序

练习1:

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

  用r指令查看stack段地址076B,由于stack内是8字即16个字节。所以data区短地址是076A,刚好数据区也是16个字节,用d 076A:0 F查看数据元素。

  用u指令反汇编代码,得到代码段最后是076A:001D。用g命令执行该代码。

  

  可以得到CS=076C,SS=076B,DS=076A。假设CODE段的段地址为X,则DATA段的段地址为 X-2 ,STACK段的段地址为 X-1 

练习2: 

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

  用d查看076A:0 F可知data数据区在076A:0 3

  

  发现此处数据区没有变化,CS=076C,SS=076B,DS=076A。假设CODE段的段地址为X,则DATA段的段地址为 X-2 ,STACK段的段地址为 X-1 

同第一题结果一样。但此处的栈空间和数据区间都没有达到8个字即16个字节。那么段中数据占N个字节,则程序加载后,该段实际占有的空间为 (N/16+1)*16 。

当N被16整除时: 占有的空间为(N/16)*16

当N不被16整除时: 占有的空间为(N/16+1)*16,N/16取最小正整数,还有一个余数,余数肯定小于16,加上一个1,再乘16字节。

程序加载后分配空间是以16个字节为单位的,也就是说如果不足16个字节的也分配16个字节。 

练习3:

 1 assume cs:code, ds:data, ss:stack
 2 code segment
 3 start:  mov ax,stack
 4         mov ss, ax
 5         mov sp,16
 6         mov ax, data
 7         mov ds, ax
 8         push ds:[0]
 9         push ds:[2]
10         pop ds:[2]
11         pop ds:[0]
12         mov ax,4c00h
13         int 21h
14 code ends
15 data segment
16   dw 0123h, 0456h
17         data ends
18 stack segment
19   dw 0,0
20         stack ends
21 end start
View Code

  

  由此可知stack的段地址即SS=076E,data的段地址为076D,代码段的段地址CS=076A。

  

  数据data区没有改变,原数据详细地代码请展开练习3 下面的代码。

假设CODE段的段地址为X,则DATA段的段地址为 X+3 ,STACK段的段地址为 X+4 

练习4:

  将1、2、3中最后最后一条伪指令“end start”改为“end”(也就是说,不指明程序的入口),会怎么样?

  

  实验证明,只有第三个程序,是能够正常运行。

  如果不指明入口位置,则程序从所分配的空间开始执行。只有第三个是以代码段开始,则不会将其他数据段当成代码段执行。

练习5:

编写code段中代码,将a段和b段中的数据依次相加,将结果存到C段中。

 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 c segment   
10   db 8 dup(0)
11 c ends       
12 code segment
13 start:
14        mov ax,a
15        mov ds,ax
16        mov ax,b
17        mov es,ax
18        mov ax,c
19        mov ss,ax
20        mov bx,0
21        mov cx,8
22 z:    mov al,[bx]
23        add al,es:[bx]
24        add ss:[bx],al
25        inc bx
26        loop z
27        mov ax,4c00h
28        int 21h
29 code ends
30 end start
View Code

  

  实现功能。

练习6:

   编写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 
 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 ss,ax
16 mov sp,10H
17 mov bx,0
18 mov cx,8
19 z:push [bx]
20 add bx,2
21 loop z  
22 mov ax,4c00h
23 int 21h
24 code ends
25 end start
View Code

  

  实验成功。

实验总结与感受:

  这个章节内容很少,确实很少,但实验不少。本章主要是综合运用前面的内容,定义栈,使用段地址加偏移地址,进行访问,存储等等。

  程序一步步走向成熟,代码越来越多,期待编写自己第一个不用在debug中调试才能看见效果的有意义的程序。

  

原文地址:https://www.cnblogs.com/auspice/p/10012320.html