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

实验任务一

将下面的程序编译、链接,用debug加载、跟踪,然后回答问题。

 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 

①CPU执行程序,程序返回前,data段中的数据是多少?

②CPU执行程序,程序返回前,CS=____,SS=____,DS=____。

③设程序加载后,code段的段地址为X,则data段的段地址为____,stack段的段地址为____。


实现:

将代码编译、连接后,用debug工具调试:

①可以发现,data段的数据在执行程序后,程序返回前并未改变,仍是原始数据。

②从图中可以看出,CPU执行程序,程序返回前,CS=076C,SS=076B,DS=076A。

③进一步可以发现,若code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1。

实验任务二

将下面的程序编译、链接,用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段中的数据是多少?

②CPU执行程序,程序返回前,CS=____,SS=____,DS=____。

③设程序加载后,code段的段地址为X,则data段的段地址为____,stack段的段地址为____。

④对于如下定义的段:

name segment
    ...
name ends

如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为____.


实现:

将代码编译、连接后,用debug工具调试:

①与(1)的结果一样,data段的数据在执行程序后,程序返回前仍未改变,仍是原始数据。

②从图中可以看出,CPU执行程序,程序返回前,CS=076C,SS=076B,DS=076A。

③与(1)的结果一致,若code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1。

④对比(1)(2)可以发现,(1)中data段数据有16个字节,占用了16个字节空间,而(2)中data段数据只有4个字节,但实际上(2)也占用了16字节的空间,其中不足的部分都用0补全了。所以推测,若段中数据为N个字节,则该段实际占用的空间为  ([N/16]+1)*16 个字节([]为取整符号)。

实验任务三

将下面的程序编译、链接,用debug加载、跟踪,然后回答问题。

 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段中的数据是多少?

②CPU执行程序,程序返回前,CS=____,SS=____,DS=____。

③设程序加载后,code段的段地址为X,则data段的段地址为____,stack段的段地址为____。


实现:

将代码编译、连接后,用debug工具调试:

①可以发现,data段的数据在执行程序后,程序返回前并未改变,仍是原始数据。

②从图中可以看出,CPU执行程序,程序返回前,CS=076A,SS=076E,DS=076D。

③进一步可以发现,若code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4。

总结:对比(2)(3),发现它们仅仅是data段、stack段和code段的顺序交换了一下,其内容都一样,但是段地址间的相互关系却发生了变化。 进一步观察发现,各段段地址的大小关系与各段在代码中出现的先后关系是一致的,而相邻两段段地址的差值是由前段段占用内存空间大小决定的。实际上,各段在程序中出现的先后顺序是决定了各自被加载进内存的顺序。

实验任务四

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

答:如果将最后一条伪指令“end start”改为“end”,相当于没有指明程序入口,此时程序就会从加载进内存的第一个单元起开始执行。在(1)(2)题中,都是数据先加载进内存,CPU会误把数据也当成指令执行,最终不能保证被正确执行;而(3)题则是代码段先被加载进内存,因而可以被正确执行。

实验任务五

程序如下,编写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
10 c segment   ; 在集成软件环境中,请将此处的段名称由c→改为c1或其它名称
11   db 8 dup(0)
12 c ends        ; 改的时候要成对一起修改
13 code segment
14 start:
15        ;?
16 code ends
17 end start

实现:

此题需要存放数据的段有3个,即a、b、c,但是任意时刻,只有一个 ds 和 es 可用。通过前面的实验可以得知,a段的段地址和b段的段地址 是有联系的,此例中,由于a、b段的数据都小于16个字节,设a段的段地址为X,则b段的段地址为X+1。据此可以得到一种实现方案:

补充的代码为:

    mov ax,c
    mov ds,ax      ;将ds作为c段的段地址
    mov ax,a  
    mov es,ax      ;将es作为a段的段地址
    mov bx,0

    mov cx,8
s:  mov dl,es:[bx]
    add [bx],dl
    mov dl,es:[bx+16]  ;b:[bx]对应于 a:[bx+16]
    add [bx],dl
    inc bx
    loop s   

    mov ax,4c00h
    int 21h

可以看到,此方案成功实现了a段与b段依次相加的目的。

除此之外,还可以有另一种方案,即分阶段使用ds:

补充的代码为:

    mov ax,a
    mov ds,ax  ;ds作为逻辑段a
    mov ax,c 
    mov es,ax  ;es作为逻辑段c

;阶段一:将逻辑段a的数据复制到逻辑段c中
    mov bx,0
    mov cx,8
s1: mov al,[bx]
    mov es:[bx],al
    inc bx
    loop s1

    mov ax,b
    mov ds,ax  ;ds作为逻辑段b
;阶段二:将b段的数据依次加到c上
    mov bx,0
    mov cx,8
s2: mov al,[bx]
    add es:[bx],al
    inc bx
    loop s2

    mov ax,4c00h
    int 21h

可以看到,此方案实现了a段复制到c段b段加到c段上两个阶段的任务,最终也实现了将a、b段数据依次相加的目的。

实验任务六

程序如下,编写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        ;?
13 code ends
14 end start

实现:

补充的代码为:

    mov ax,a
    mov ds,ax
    mov ax,b
    mov ss,ax  ;将b段设置为栈
    mov sp,16  ;栈顶为16
    mov bx,0

    mov cx,8
s:  push [bx]
    add bx,2
    loop s

    mov ax,4c00h
    int 21

在push之前,b段的内容都为0,入栈全部结束后,b段逆序存储了a段的前8个字节。

原文地址:https://www.cnblogs.com/kevin234/p/10010873.html

时间: 2024-07-29 21:47:27

实验五:编写、调试具有多个段的程序的相关文章

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

实验1 assume cs:code,ds:data,ss:stack data segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h data ends stack segment dw 0,0,0,0,0,0,0,0 stack ends start: mov ax,stack mov ss,ax mov sp,16 mov ax,data mov ds,ax push ds:[0] push ds:[2] pop ds:[2]

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

南京信息工程大学实验报告 实验名称   实验 5 编写.调试具有多个段的程序 实验日期  12.2 得分 学院   计软院 专业   计科 年级   2017级 班次    6班 姓名    江轲禹 学号    20171308227 一.实验目的 1. 理解和掌握将数据.代码.栈放入不同段的程序的编写和调试 2. 理解具有多个段的汇编源程序对应的目标程序执行时,内存分配方式 二.实验准备 1. 结合第6章教材和课件,复习第6章内容 2. 复习第3章「栈」的知识 三.实验内容 教材133实验 5

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

实验结论 实验1 1.实验代码 assume cs:code,ds:data,ss:stack data segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h data ends stack segment dw 0,0,0,0,0,0,0,0 stack ends start: mov ax,stack mov ss,ax mov sp,16 mov ax,data mov ds,ax push ds:[0] push ds:[2

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

四.实验结论 1 (1)cpu执行程序,程序返回前,data段中的数据为:23 01 56 04 89 07 bc 0a ef 0d ed 0f ba 0c 87 09 如下图所示: (2)cpu执行程序,程序返回前,cs=076c,ss=076b,ds=076a 如下图所示 (3)设程序加载后,code段的段地址为x,则data段的段地址为x-2h,stack段的段地址为x-1h 因为data一共占16个字节,stack一共占16个字节. 2 (1)cpu执行程序,程序返回前,data段中的数

【实验五】编写、调试具有多个段的程序

四.实验结论 *任务(1)(2)(3)基本步骤相同,这里只列举出(1)的实验步骤 步骤一:把要使用的代码粘贴到masm文件夹中. 步骤二:编译.连接.用debug调试. 步骤三:用r命令查看哥寄存器的值. cs是code的段地址,ds是data的段地址,ss是stack的段地址.这是因为代码前面的声明:   assume cs:code, ds:data, ss:stack 步骤四:用u命令反汇编,注意反汇编是code段,所以u命令后接的应该是cs. 步骤五:用g命令执行,根据反汇编得到的代码,

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

1.将下面的程序编译.连接.用Debug加载.跟踪,然后回答问题. assume cs:code,ds:data,ss:stack data segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h data ends stack segment dw 0,0,0,0,0,0,0,0 stack ends code segment start: mov ax,stack mov ss,ax mov sp,16 mov ax,data m

汇编试验五:编写、调试具有多个段的程序

ds 数据段放入数据正确: 两次push 操作后,ss栈段正确: 由于pop 操作顺序,ds数据段并没有发生改变: Source Code: assume cs:code, ds:data, ss:stack data segment dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H data ends stack segment dw 0,0,0,0,0,0,0,0 stack ends code segment start: mov ax,

汇编语言实验五

实验任务一 1.利用debug加载.跟踪程序 (1)先利用r命令来查看各个寄存器的值 (2)从cx中可知道程序的长度,用cx中的值减去20h(数据段和栈段已分配的空间)得到代码段的长度,用u命令精确反汇编 (3)先执行到000D之前,看看ds是否已成功指向数据段 (4)从上图可以看到ds已指向数据段,然后我们接着执行到程序返回前,即到001D之前,再查看一次数据段的内容 (5)从上图可以看到,数据段没有发生变化 2.书上的问题解答: (1)程序返回前,data段中的数据为 23 01 56 04

包含多个段的程序

在前一章我们提到0:200~0:2FF地址空间是相对安全的,但是这段空间的容量只有256个字节. 在操作系统中只要是通过操作系统申请的空间就都是安全的,操作系统负责给程序分配安全的空间.在操作系统允许的情况下,程序可以取得任意数量的空间. 按程序获取所需空间的时间,获取空间方法可分为两种: 在加载程序的时候为程序分配 在程序执行的过程中向系统申请 本书中不论描述第二种 对于汇编程序,如果需要他在被加载的时候取得所需的空间,就必须要在源程序中做出说明,对于汇编源程序来讲就是在汇编源程序中做出相应段