欢迎关注博主的公众号:薛定谔的小鱼儿
(一)代码段和数据段同时存在
首先我们编写一个程序,将0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h累加并存放在ax中。
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
在有多个段存在时,可以用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
上述可以看出在存在数据段和代码段时,利用end表明程序的入口位置。
因此我们可以通过上述的例子了解到,当程序中存在数据和代码时,我们采用以下的架构完成:
assume cs:code
code segment
……
数据
……
start:
……
代码
……
code ends
end start
(二)在代码段中使用栈
例子:
利用栈,将程序定义的数据逆序存放。
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
?
codesg ends
end
那么我们如何完成程序?
先将定义的数据存放在cs:0-cs:F单元中,一共有8个字单元,将这8个字单元中的内容入栈,在依次出栈可以实现逆序存放。
代码:
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,0,0,0,0,0,0 //定义16个字形数据,将这段空间当做栈
start: mov ax,cs
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,8
s0: pop cs:[bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
codesg 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,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 s
s0: pop [bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
code ends
end start
注意:
mov ax,data
mov ds,ax
mov bx,ds:[6]
不可以替换成:
mov ds,data
mov bx,ds:[6]
原因:8086CPU不允许将一个数值送入段寄存器,程序中对段名的引用,如“mov ds,data”中的“data”将被编译器处理为一个段地址的数值。