汇编语言(第三版)王爽著(实验五)编写、调试具有多个段的程序
一、实验目的
掌握在Debug中使用命令进行汇编指令编程及执行
二、实验设备与环境
计算机
DOS操作系统或 Windows 操作系统
MASM.EXE, LINK.EXE, DEBUG.COM 或宏汇编集成环境
三、实验内容、程序清单及运行结果
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
mov ds,ax
push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]
mov ax,4c00h
int 21h
code ends
end start
(1)Data段的数据没变
(2)cs=076ch、ss=076bh、ds=076ah
(3)设code段的段地址为x,则data段的段地址为x-2,stack段的段地址为x-1
2. 将下面的程序编译、连接,用debug加载、跟踪,然后回答问题
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
mov ds,ax
push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]
mov ax,4c00h
int 21h
code ends
end start
(1)Data段的数据没变
(2)cs=076ch、ss=076bh、ds=076ah
(3)设code段的段地址为x,则data段的段地址为x-2,stack段的段地址为x-1
(4)如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为:
⌈N/16⌉*16字节,N除于16向上取整乘以16(此答案用书上的程序并不能完全证明,所以要自己改变data段、code段、stack段的数据长度使其超过16个字节,进行一系列的对比实验方可得出)
3. 将下面的程序编译、连接,用debug加载、跟踪,然后回答问题
assume cs:code,ds:data,ss:stack
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
data segment
dw 0123h,0456h
data ends
stack segment
dw 0,0
stack ends
end start
ip=20h+2=22h=34,⌈34/16⌉*16=48=30h,076ah(cs)+3=076dh(ds)
(1)Data段的数据没变
(2)cs=076ah、ss=076eh、ds=076dh
(3)设code段的段地址为x,则data段的段地址为x+3,stack段的段地址为x+4
4.如果将1、2、3题中的最后一条伪指令“end start”改为“end”(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因
解:第3个程序仍然可以正确执行,因为当exe文件被加载进内存中,首先将cs:ip指向程序的首地址,而第3个程序的程序中一开始定义的是代码段,所以cs:ip也就自然的指向了指令的首地址。第1和第2个程序的程序中一开始定义的是数据段,所以cs:ip自然指向了数据的首地址而非指令,数据段反汇编出来的是一堆杂乱的指令,所以不可执行
5. 程序如下,编写code段的代码,将a段和b段中的数据依次相加,将结果存到c段中。
assume cs:code
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
sub bx,bx
mov cx,8
s: mov al,ds:[bx]
add al,ds:[bx+16]
mov ds:[bx+32],al
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end start
由1,2,3题可以对每段的空间有明确的判断,所以可以直接用立即数进行定位a,b,c段个占16个字节
6.程序如下,编写code段的代码,用push指令将a段中的前8个字型数据,逆序存储到b段中。
assume cs:code
a segment
dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh
a ends
b segment
dw 0,0,0,0,0,0,0,0
b ends
code segment
start: mov ax,a
mov ds,ax
sub bx,bx
mov ax,b
mov ss,ax
mov sp,16
mov cx,8
s:push ds:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end start
对栈的操作都是字,不能是字节。标号并不能说明什么,关键是代码段将它装填为什么
- 实验结论、实验体会
第一、第二、第三题:
如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为:
⌈N/16⌉*16字节,N除于16向上取整乘以16,这是这几个实验得到的最重要的结论
第四题:
定义的段在不同的位置,有不同的效果,如代码段定义在最开始,即使不写start:入口程序也可以执行,但如果代码段不在最开始,则必须写上start:告诉dos程序的执行开始位置,但建议都写上
第五题:
通过之前得出的结论,可以实现立即数的偏移量定位
第六题:
对栈的操作都是字,不能是字节。标号并不能说明什么,关键是代码段将它装填为什么
要想得到好的结果,就要进行大量的实验和推理
其它实验:
汇编语言(第三版)王爽著(实验五)编写、调试具有多个段的程序