• 包含多个段的程序


    大多数程序都包含代码、指令、栈;
    为了程序设计上的清晰方便,一般会用不同的段来存放它们;
    当然,也可以将它们都放在代码段;
     
    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段的地址来实现的;
     
     
  • 相关阅读:
    如何快速的开发一个完整的iOS直播app(采集篇)
    直播相关讲解 视频直播技术大全、直播架构、技术原理和实现思路方案整理
    mybatis中的数据源和连接池
    Java8新特性终极指南
    实战!日志打印的15个好建议
    我在腾讯这一年、如何防止订单重复支付?|掘金一周 07.27
    JSON.parse(JSON.stringify()) 实现对对象的深拷贝
    JSON.parse(JSON.stringify(obj))实现深拷贝
    前端深拷贝和浅拷贝
    深入解析JSON.stringify和JSON.parse
  • 原文地址:https://www.cnblogs.com/ShiningArmor/p/11076674.html
Copyright © 2020-2023  润新知