汇编实验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 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, 0cbah, 0987h(未产生改变)
- CPU执行程序,程序返回前,cs = 076C、ss = 076B、ds = 076A.(如下)
- 设程序加载后,code段的的段地址为X,则data段的段地址为 X-2 ,stack段的短地址为 X-1 .(此问由上一题可得,code段的段地址即为cs,data段的段地址为ds,stack段的段地址为ss)
(2)源代码:
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
- CPU执行程序,程序返回前,data段中的数据为多少?
0123h, 0456h
- CPU执行程序,程序返回前,cs = 076C、ss = 076B、ds = 076A.
- 设程序加载后,code段的的段地址为X,则data段的段地址为 X-2 ,stack段的段地址为 X-1 .
(前三问与第一个实验结果本质相同,故不作重复说明)
- 对于如下定义的段:
name segment
...
name ends
若段中的数据占N个字节,则程序加载后,该段实际占有的空间为(N / 16 + 1) * 16 字节.(现计算机内存最小单位为16字节,即所占空间必为16的整数倍)
(3)源代码:
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
- CPU执行程序,程序返回前,data段中的数据为多少?
0123h, 0456h
- CPU执行程序,程序返回前,cs = 076A、ss =076E、ds = 076D.
- 设程序加载后,code段的的段地址为X,则data段的段地址为 X+3,stack段的段地址为 X+4.
(4)若将(1)(2)(3)中的最后一条伪指令“end start”改为“end”(即不指名程序入口),则哪个程序 仍可以正确执行?说明原因。
书上了解到,伪指令end start是让程序从start处开始执行,若舍掉,即不指名程序入口,程序将默认从首个单元开始执行,三个程序的主要差别在于代码段的顺序不同,(1)和(2)开头的数据会被当做指令,故仅有(3)能够正确执行。
(5)
基本思路,分两次循环来完成,一次循环送值,一次循环相加
完整代码如下:
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 ; 在集成软件环境中,请将此处的段名称由c→改为c1或其它名称 db 8 dup(0) c ends ; 改的时候要成对一起修改 code segment start: mov ax,a mov ds,ax mov ax,c mov es,ax mov bx,0 mov cx,8 s1: mov al,[bx] mov es:[bx],al inc bx loop s1 mov ax,b mov ds,ax
mov bx,0 mov cx,8 s2: mov al,[bx] add es:[bx],al inc bx loop s2 mov ax,4c00h int 21h code ends end start
相加之前es段中的值:
执行相加后:
完成!
此实验中有一点需注意,曾将指令
mov al,[bx]
mov es:[bx],al
写作:mov es:[bx], [bx],结果汇编时报错。
遗忘知识点:给四个段寄存器ds,ss,es,cs复制必须要借由数据寄存器间接送值
(6)
上次遇到用栈没想出来,这次再试试看
完整代码如下:
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 8 dup(0) b ends code segment start: mov ax,a mov ds,ax mov ax,b mov ss,ax mov sp,20h mov bx,0 mov cx,10h s: push ds:[bx] inc bx inc bx loop s mov ax,4c00h int 21h code ends end start
执行push指令之前:
执行之后:
完成!
中间有一个问题,就是ip的值,一开始填的是20h,结果发现将数据传进了ss:0010~ss:0020中,后来经同学提醒才得已改正。