在前面的程序中,只有一个代码段。现在有一个问题是,如果程序需要其他空间来存放数据,使用哪里呢?
程序取得所需空间的方法有两种,一是在加载程序的时候为程序分配,再就是在程序执行的过程中向系统申请。我们若要一个程序在被加载的时候取得所需空间,则必须要在源程序中作出说明。我们通过在源程序中定义段来进行内存空间的获取。
在代码段中使用数据
如果要编程计算以下8个数据的和,结果存在ax寄存器中:
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
这样编译连接出来的程序直接执行可能会存在一些问题,应为程序并不是从我们希望的入口开始运行,所以我们可以进行以下修改:
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
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
此时程序执行时CS:IP最初指向Start的位置。
在代码段中使用栈:
如果将上个程序的要求改为:利用栈,将程序中定义的数据逆序存放。
我们可以这样来写这段程序:
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0
start: mov ax,cx
mov ss,ax
mov sp,30h
mov bx,0
mov cx,8
s: push cs:[bx]
add bx,2
loop s
mov bx,0
mov cx,0
s0: pop cs:[bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
code ends
end start
将数据,代码,栈放入不同的段
在上面的程序中我们将数据和栈还有代码全部放在了一个段里,我们在编程的时候要注意何处是栈,何处是代码,这样做明显会有两个问题:
(1)把他们放到一个段中使程序显得混乱
(2)如果数据过多超过了64kb,就不能放到一个段中
所以我们需要用多个段来存放数据,代码,和栈。
我们来看以下程序:
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
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,20h
mov ax,data
mov ds,ax
mov bx,0
mov cx,8
s: push [bx]
add bx,2
loop s0
mov bx,0
mov cx,8
s0: pop [bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
code ends
end start
现在,程序中有多个段了,如何访问段中的数据呢?当然要通过地址,而地址是分为两部分的,即段地址和偏移地址。在程序中,段名就代表了段地址,所以“mov ax,data”代表将名称为“data”的段的段地址送入ax中。注意"mov ds,data"指令是错误的,CPU不允许段寄存器直接接受一个具体数值。
伪指令"assume cs:code,ds:data,ss:stack"是将cs,ds,ss分别和code,data,stack段相连。