包含多个段的程序

大多数程序都包含代码、指令、栈;
为了程序设计上的清晰方便,一般会用不同的段来存放它们;
当然,也可以将它们都放在代码段;
 
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段的地址来实现的;
 
 
原文地址:https://www.cnblogs.com/ShiningArmor/p/11076674.html