• 汇编语言---关于自定义的段占用内存空间


    汇编语言---关于自定义的段占用内存空间在王爽汇编实验5(2)中有这样一个问题:
    对于如下定义的段:
    name segment
       ...
    name ends
    如果段中的数据占N个字节,则程序加载后,其实际占用空间

    当时在做这道题时候,只是通过debug加载多个类似程序,然后观察,得出实际占用空间为16;([N/16]+1)字节。即对于设定的段空间,如果在预设时候的数据不足16字节;则给其分配空间为m{m=([N/16]+1)},编译器会自动给其增补内存空间。
    当时只是以为这就是规则,而没有深入去考虑为什么制定这样的规则?
    对于程序而言,数据段的设置是为了方便使用,而使用数据段则需要知道其段地址。
    举例如下:
    a segment
    db 16 dup(0)
    a ends
    b segment
    db 23 dup(0)
    c ends
    c segment
    db 38 dup(0)
    c ends
    以上ac三个数据段实际占用的内存空间分别为16、32、48byte。程序加载后内存空间分配如下:
    ds:0~0ffh ------>psp
    ds:100h~10fh ------>a段
    ds:110h~12fh------> b段
    ds:130h~15fh ------>c段
    由上可见,ac段的地址范围分别可以表示如下:
    (ds+10):0~0fh------>a段
    (ds+11):0~1fh------>b段
    (ds+13):0~2fh------>c段
    即ac段的段地址可以分别表示为(ds+10)(ds+11)(ds+13);写到这里,有些人可能会问:abc段地址同样可以设置为ds啊,只需要偏移地址对应起来就可以啊。这当然没错;可只有当设为(ds+10)(ds+11)(ds+13)时候,对应的(段地址:0)才能指向各区的首地址,而段地址选用ds的话,各区的首地址偏移地址分别为100h110h130h。
    再回想一下汇编程序中的常用做法,如下例:
    assume cs:codesg,ds:data1,es:data2
    data1 segment
       db 2 dup (0)
    data1 ends
    data2 segment
       db 4 dup (0)
    data2 ends
    codesg segment
        mov ax,data1
        mov ds,ax
        mov bx,0
        mov ax,data2
        mov es,ax
        mov bp,0
        ......
    codesg ends
    在编译器处理过程中‘data1'这个标号已经对应了data1这个数据区的段地址,并且该段地址使得该区首单元的偏移地址为0。
    假设,编译器不增补至16的整数倍字节。那么上面这个程序中的data1data2如何设置段地址才能使得首地址偏移地址为0?答案是:有些情况下做不到。因为如果不增补的话,data1地址范围为(ds+100h):0~(ds+100h):1;data2地址范围为(ds+100h):2~(ds+100h):5;对于data1段来说,可以做到,设段地址为(ds+100h)即可使其首单元偏移地址为0;而对于data2段来说,无论怎么样设置段地址,其首单元偏移地址总不会为0.
    通过上面的分析,基本上可以总结出以下几方面:
    1、段空间首单元的偏移地址设为0,在很多时候都可以方便我们的编程设计,理清思路;但不是所有的情况都方便,或者说不是所有情况都必须使首单元的偏移地址设0.
    2、在需要设0,或者说设0方便的情况下,编译器提供了"将程序中的各段空间增补为16的整数倍字节"的功能,其原因就是为了使该段首单元偏移地址可以设为0,同时用相应标号如"codesg"、"datasg"预存可以使其首单元偏移地址为0的段地址。举例如下:
    assume cs:codesg,ds:a,es:b
    a segment
       db 2 dup (0)
    a ends

    b segment
       db 4 dup (0)
    b ends

    codesg segment
        mov ax,a
        mov ds,ax
        mov bx,0
        mov ax,b
        mov es,ax
        mov bp,0
        ......
    codesg ends
    3、在不需要设0,或者说设0并不方便的情况下,则可以用如下数据定义格式:
    assume cs:codesg,ds:datasg
    datasg segment
       db 2 dup (0)     ;a区
       db 4 dup (0)     ;b区
    datasg ends

    codesg segment
        mov ax,datasg
        mov ds,ax
        mov bx,0
       ......
    codesg ends
    4、补充说明:
    对于assume cs:codesg,ds:datasg语句,编译器并不会执行设置cs和ds的功能,只是"假设";真正实现cs对应codesg,使ds对应datasg的语句分别是"end start"(注明程序开始入口)和"mov ax,datasg/mov ds,ax"语句。

  • 相关阅读:
    https://blog.csdn.net/yongchaocsdn/article/details/53355296
    P1526 [NOI2003]智破连环阵 [搜索+剪枝(二分图)]
    AT2165 Median Pyramid Hard [二分答案]
    翻煎饼 [迭代加深搜索+剪枝]
    P2962 [USACO09NOV]灯Lights [高斯消元+异或方程组 / 折半搜索]
    P5025 [SNOI2017]炸弹 [线段树优化建图 + Tarjan]
    Tarjan [割点, 缩点, 桥(待填坑)]
    线段树优化建图学习笔记
    P5468 [NOI2019]回家路线 [斜率优化dp]
    CF573E Bear and Bowling [平衡树+动态规划]
  • 原文地址:https://www.cnblogs.com/tsembrace/p/3267160.html
Copyright © 2020-2023  润新知