包含多个段的程序
程序取得所需空间有两种方法:
- 加载程序时为程序分配。
- 程序执行过程中向系统申请。。也就是动态获取。
之前的章节只有代码段,这里开始引入数据段和栈段。
在代码段中使用数据
新的指令dw
define word, 定义一个字。
ax 存放8个数的和。
assume cs:code
code segment
dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0997h
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
这个程序其实是无法运行的。
因为cs:ip 指向的并不是要执行的指令mov bx,0
而是定义的数据0123h
。
解决办法是 使用end
伪指令的另一个用法,end xxx
指定程序的入口。xxx为自定义的名字。
上述代码改为
assume cs:code
code segment
dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
main: 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 main
这样cs:ip 执行的第一条指令就变成了main指向的指令mov bx,0
。
在代码段中使用栈
关键代码就一个。通过dw 定义来开辟内容。
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 #这32个字节就可以 当成栈来使用。感觉用16个字节就够了,不晓得为啥搞32个。
将数据、代码、栈放入不同的段
把数据、代码、栈放到一个段的问题:
- 程序显得混乱
- 如果数据、栈和代码需要的空间超过64KB, 就不能放到一个段中了。(这是8086模式的限制,一个段的容量最大为64KB)
使用多个段的示例:
assume cs:code, ds:data, ss:stack ;定义了三个段 code,data,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 # stack 段的首地址
mov ss,ax
mov sp, 20h;
mov ax, data ;
mov ds, ax; ds指向data 段的首地址
mov bx,0
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; 出栈,把数据放回到data段。 如此就把数据逆序了。
mov ax, 4c00h
int 21h
code ends
end start