汇编实验报告5
实验5 编写、调试具有多个段的程序
(1) 将下面的程序编译连接,用debug加载、跟踪,然后回答问题:
;----------------------------------------------------------
;ex5a1.asm
;------------------------------------------------------------
;AUTHOR:IT007
;DATE:2007/11/11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
mov ds,ax
push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]
mov ax,4c00h
int 21h
code ends
end start
①cpu执行程序,程序返回前,data段中的数据为多少?
答: 0123h,0456h,0789h,0abch,0defh,0fedh,0cabh,0987h
②CPU执行程序,程序返回前,cs=13D5,ss=13D4,ds=13D3.
③设程序加载后,code段的段地址为x,则data段的段地址为x-12h,stack段的段地址为x-2h.
(2) 将下面的程序编译连接,用debug加载、跟踪,然后回答问题:
;----------------------------------------------------------
;ex5a2.asm
;------------------------------------------------------------
;AUTHOR:IT007
;DATE:2007/11/11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h
data ends
stack segment
dw 0,0
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,data
push ds:[0]
mov ax,4c00h
int 21h
code ends
end start
①cpu执行程序,程序返回前,data段中的数据为多少?
答:23 01 56 04
②cpu执行程序,程序返回前, cs=13D5,ss=13D4,ds=13D3
.
③设程序加载后,code段的段地址为x,则data段的段地址为x-12h,stack段的段地址为x-2h.
④对于如下定义的段:
name segment
………
name ends
如果段中的数据占n个字节,则程序加载后,该段实际占有的空间为n个字节.
(3) 将下面的程序编译连接,用debug加载、跟踪,然后回答问题:
;----------------------------------------------------------
;ex5a3.asm
;------------------------------------------------------------
;AUTHOR:IT007
;DATE:2007/11/11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
assume cs:code,ds:data,ss:stack
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,data
push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]
mov ax,4c00h
int 21h
code ends
data segment
dw 0123h,0456h
data ends
stack segment
dw 0,0
stack ends
end start
①cpu执行程序,程序返回前,data段中的数据为多少?
答:23 01 56 04
②cpu执行程序,程序返回前,cs=13D3H,ss=13D7H,ds=13D6H.
③设程序加载后,code段的段地址为x,则段的段地址为x-10h,stack段的段地址为x-10h。
(4) 如果将1、2、3题中的最后一条伪指令”end start”改为”end”(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因。
答:第3个程序可以正常运行,因为在前两个程序都未指定程序的入口,
而程序的前面一部分为数据,即非程序,当程序被加载入内存时,CS:
IP指 向这些数据,即把这些数据当作指令来执行,这样可能会引发
意想 不到的后果, 严重的甚至可能导致死机。而第3个程序CS:
IP指向程序的第一条指令,因 为数据段定义在程序的末尾,因而程
序可以正常执行。
(5) 程序如下,编写code段中的代码,将a段和b段中的数据依次相加,将结果存到c段中。
;----------------------------------------------------------
;ex5a5.asm
;------------------------------------------------------------
;AUTHOR:IT007
;DATE:2007/11/11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
assuem cs:code,ds:a,es:b
a segment
db 1,2,3,4,5,6,7,8
a ends
b segment
db 1,2,3,4,5,6,7,8
b ends
c segment
db 0,0,0,0,0,0,0,0
c ends
code segment
start:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;以下为我添加的代码
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,a
mov ds,ax
mov ax,b
mov es,ax
mov bx,0
mov di,0
mov cx,8
mov ax,0
s: mov al,[bx]
add al,es:[bx]
mov [bx+32],al
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end start
(6) 程序如下,编写code段中的代码,用push指令将a段中word数据,逆序存储到b段中。
;----------------------------------------------------------
;ex5a6.asm
;------------------------------------------------------------
;AUTHOR:IT007
;DATE:2007/11/11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
assume cs:code
a segment
dw 1,2,3,4,5,6,7,8
a ends
b segment
dw 0,0,0,0,0,0,0,0
b ends
code segment
start:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;以下为我添加的代码
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,a
mov ds,ax
mov ax,b
mov ss,ax
mov sp,10h
mov bx,0
mov cx,8
s:
push [bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end start
总结:经过实验5,我掌握了以下知识:
①我学会了如何将一个段和附加寄存器关联,并将之设置为附加数据段
②我学会了如何使用END伪指令设置IP为一个程序的入口的偏移地址
③我学会了如何程序的数据的段并不是一定要放在程序的前面,它也可以放在程序的末尾,只是这时程序的IP即为程序的入口的偏移地址。
④我学会了如何依次将两个数组的元素相加,并把结果依次存储到另一个数组中去。
⑤我学会了如何使用MOV指令将一个字节单元的内存传送到8位寄存器中去。
⑥我学会了如何使用ADD指令将一个字节型单元的内容加到一个8位寄存器中去。
⑦我学会了如何读取附加段字节型单元的内容到一个8位寄存器中去。
⑧我学会了如何使用循环(至少执行一次的循环)。
⑨我学会了如何使用PUSH指令将一个数组的元素逆序COPY到一个堆栈(或说为数组应该也没什么大碍吧)中去。
心得:在这次实验当中,可以说作为一个初学者该犯的错误我都犯了,比如:试图将一个字型单元的内容读取到一个堆栈中去(这明显是不支持的嘛,PUSH指令怎么说也是一个字操作指令:),还有就是试图使用字操作指令进行字节操作(这明显是不能实现的嘛:),不过只要想相应的寄存器改为8位寄存器就支持了,还有就是忘了在程序的最后加上返回系统的指令(一个程序运行结束之后如果不返回调用它的程序,或操作系统或DEBUG,那么它该去哪里呢?我不知道,也许会发生意想不到的事情吧:)。
这次实验最大的收获就是终于掌握了独立编写一个汇编程序的能力,能解决一些日常遇到的小问题,如将一个数组逆序,将一个数组的元素COPY到另一个数组中去。在使用PUSH指令的过程中也让我更加深刻理解了堆栈的运行机制。
