大多数程序都包含代码、指令、栈;
为了程序设计上的清晰方便,一般会用不同的段来存放它们;
当然,也可以将它们都放在代码段;
1.代码段中使用数据
可以在代码段中利用指令dw(define word)来定义数据;
在代码段被编译连接成可执行程序后,当程序被运行,加载入内存时,会给dw定义的数据分配空间;
例如定义5个字型数据:
dw 01h,02h,03h,04h,05h
dw指令定义的数据在加载到内存后,内存地址的段地址可从cs中得到;
例如:5个数字的累加;
assume cs:code
code segment
dw 01h,02h,03h,04h,05h
start:mov bx,0
mov ax,0
mov cx,5
s:add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end start
这里在代码段中用dw定义的5个字型数据;
这5个数据的段地址为cs的值;
因为dw定义的数据处于代码段的最开始,所以偏移地址为0;
为了防止dw定义的数据被当做指令执行,可以使用程序入口标号;
程序入口标号可以随意字符串,例如:上面的代码中入口标号是"start";
有入口标号的程序在结束时,用end xxx 而不是 end,例如上面的end start;
end可以通知编译器程序的入口在哪,比如上面的代码中,表示start处的代码 mov bx,0 是程序的第一条指令;
2.代码段中使用栈
例如:需要将5个字型数据倒序存放;
思路:
先用dw定义几个5个目标数据;
然后用dw定义5个字作为栈空间,数值不重要可设为0;
ss:sp指向栈顶,这里定义了10个字,其中栈的偏移地址为 Ah~13h,因此栈顶偏移地址为14h;
依次将5个字入栈;
然后依次出栈,因为是先进后出所以出栈后的顺序会颠倒;
代码:
assume cs:code
code segment
dw 1h,2h,3h,4h,5h
dw 0,0,0,0,0
start: mov ax,cs
mov ss,ax
mov sp,14h
mov bx,0
mov cx,5
s: push cs:[bx]
add bx,2
loop:s
mov bx,0
mov cx,5
s0: pop cs:[bx]
add bx,2
loop:s0
mov ax,4c00h
int 21h
code ends
end start
3.数据、代码、栈放入不同的段
将数据、代码、栈都放在同一个段可能导致一些问题:
1】程序结构混乱:在编程时要注意何处是数据、何处是代码等问题;
2】段容量有限:8086模式中,一个段最多只有64kb;
可以使用多个段程序:
assume cs:code,ds:data,ss:stack
data segment
dw 1h,2h,3h,4h,5h
data ends
stack segment
dw 0,0,0,0,0
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,Ah
mov ax,data
mov ds,ax
mov bx,0
mov cx,5
s: push [bx]
add bx,2
loop s
mov bx,0
mov cx,5
s0: pop [bx]
add bx,2
loop s
mov ax,4cooh
int 21h
code ends
ends start
其中每个段的段名可以随意指定,例如上面的代码中数据段的段名为data,也可以叫其他名称;
段名可以用来代表这个段的段地址,例如 mov ax,data 表示将data段的段地址送入寄存器ax;
段的功能是在代码中用指令来指定的:例如 data段被用作数据段,是通过将段寄存器ds:[dx]指向data段的地址来实现的;