包含多个段的程序:
如果我们需要的空间超过256个字节该怎么办?
程序取得空间的方法有2种:一是在加载程序的时候为程序分配,再就是程序在执行的过程中向系统申请。本书不讨论第二种方法。
1、在代码段中使用数据
例:累加 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
源程序:
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
mov bx,0
mov ax,0
mov cx,8
s:add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end
"dw" 即“define word”。使用dw定义了8个字型数据,所占内存空间大小为16字节。
注意:是字型数据所以要累加2,add bx,2
指明程序的入口所在使用start关键字。以上程序需要在debug中设置Ip的地址才能够执行。
程序6.2:
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
a
start: mov bx,0
mov ax,0
mov cx,8
s:add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end start
note:end 除了通知编译器程序结束外,还可以通知编译器程序的入口在什么地方。这一点是由可执行文件中的描述信息指明的。
安排程序的框架:
assume cs:code
code segment
:
:
数据
:
:
start:
:
:
代码
:
:
code ends
end start
2、在代码段中使用栈
利用栈,将程序中定义的数据逆序存放。
assume cs:codesg
codesg segment
dw 0123h,0456h,0abcdh,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
start: mov ax,cs
mov ss,ax
mov sp,30h ;设置栈顶ss:sp指向cs:30
mov bx,0
mov cx,8
s:push cs:[bx]
add bx,2
loop s
mov bx,0
mov cs,8
s0:pop cs:[bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
监测点6.1:
(1)下面的程序时间依次用内存0:0-0:15单元中的内容改写程序中的数据,完成程序:
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
start: mov ax,0
mov ds,ax
mov bx,0
mov cx,8
s: mov ax,[bx]
___________
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
我的解答:mov cs:[bx],ax
(2)下面的程序实现依次用内存0:0-0:15单元中的内容改写程序中的数据,数据的传送用栈来进行。栈空间设置在程序内。完成程序:
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0 ;10个字单元用作栈空间
start: mov ax,____
mov ss,ax
mov sp,____
mov ax,0
mov ds,ax
mov bx,0
mov cx,8
s: push [bx]
___________
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
我的解答:mov ax,cs;mov sp,14;pop cs:[bx]
6.3 将数据、代码、栈放入不同的段
用多个段来存放数据、代码和栈
如:程序6.4
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,0,0,0,0,0,0,0,0
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,20h ;设置栈顶ss:sp指向stack:20
mov ax,data
mov ds,ax ;ds指向data段
mov bx,0 ;ds:bx指向data段中的第一个单元
mov cx,8
s: push [bx]
add bx,2
loop s ;以上将data段的0~15单元中的8个字型数据依次入栈
mov bx,0
mov cx,8
s0: pop [bx]
add bx,2
loop s0 ;以上依次出栈8个字型数据到data段的0~15单元中
mov ax,4c00h
int 21h
code ends
end start
实验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
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)CPU执行程序,程序返回前,data段中的数据为多少?
答:d ds:0
23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 87 09
(2)CPU执行程序,程序返回前,cs=______、ss=_______、ds=_______.
答:cs=0BB6;ss=0BB5;ds=0BB4。
(3)设程序加载后,code段的段地址为X,则data段的段地址为_____,stack段的段地址为______.
答:data段为:x-1h,,stack段为:x-2h。。
(4)对于如下定义的段:
name segment
...
name ends
如果段中的数据占N个字节,则程序加载后,该段时间占有的空间为:_________.
答:始终为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 dst,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段中的数据为多少?
答:23 01 56 04 00 00 00 00-00 00 00 00 00 00 00 00
② CPU执行程序,程序返回前,cs=_______、ss=_______、ds=______。
答:cs=0BB4,ss=0BB8,ds=0BB7。
③ 设程序加载后,设code段的段地址为X,则data段的段地址为______,stack 段的段地址为_______。
答:data段为:x+4,,dtack段为:x+3。
(4)如果将(1)(2)(3)题中的最后一条伪指令“end start”改为“end”(也就是说,不知名程序的入口),则哪个程序仍然可以正确执行?请说明原因。
答:应该是第三个程序可以正常执行。因为第三个程序第一条指令就可以执行。并且指定了数据段和栈段。
(5)程序如下,编写code 段中的代码,将a段和b段的数据依次累加,将结果保存到C段中。
assume cs:ocde
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:
?
code ends
end start
答:
start: mov ax,a
mov es,ax
mov ax,b
mov ds,ax
mov ax,c
mov ss,ax
mov sp,16
mov ax,0
mov bx,0
mov cx,8
S: mov ax,0
mov al,es:[bx]
mov dx,0
mov dl,[bx]
add ax,dx
push ax
inc bx
loop s
mov ax,4c00h
int 21h
(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:
?
code ends
end start
答:
start: mov ax,a
mov ds,ax
mov ax,b
mov es,ax
mov ax,20h
mov ss,ax
mov sp,16
mov bx,0
mov cx,8
s: push [bx]
inc bx
loop s
mov cx,8
mov bx,0
s0: mov ax,0
pop ax
mov es:[bx],ax
inc bx
loop s0
mov ax,4c00h
int 21h