汇编中的一些个人问题整理

1.段中的实际数据大小与占用空间大小问题 :

 

对于如下定义的段:
   name segment
   ....
   name ends
如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为_____. 
答案:
        (N/16+1)*16 [说明:N/16只取整数部分]    或   (N+15)/ 16 ,对16取整
       在8086CPU架构上,段是以paragraph(16-byte)对齐的。程序默认以16字节为边界对齐,所以不足16字节的部分数据也要填够16字节。“对齐”是alignment,这种填充叫做padding。16字节成一小段,称为节。

详解:
一、这首先要从8086处理器寻址原理说起。
      8086这种处理器有二十根地址线(20个用于寻址的管脚),可以使用的外部存储器空间可达1MB(00000H~FFFFFH)。 但是,8086内部的寄存器都是16位的,用任何一个寄存器(比如BX或SI),都无法直接寻址8086所支持的1M地址空间,因为16位寄存器只能表示640KB的空间范围(0000~FFFFH)。
      所以,Intel想了一个方法,设计出了CS/DS/ES/SS这几个段地址寄存器,用段地址寄存器与普通寄存器组合,来寻址1MB的地址范围,即:对于CPU取指来说,用CS:IP组合来寻址下一个要执行的指令(也在存储器中);对于堆栈操作PUSH/POP来说,用SS:SP组合来表示当前栈指针(栈也在存储器中);对于数据操作指令来说,用默认的DS/ES或指定的段地址(段前缀指令)与偏移量寄存器组合寻址。
组合后的实际地址=段寄存器内容×16+偏移量寄存器内容
      从这个公式可以看到,每一个段的地址都对齐在16的倍数上。比如DS=1234H,则这个段就从 1234H×16+0000H=12340H开始,最大到1234H×16+0FFFFH=2233FH为止。
二、对同一个内存地址,有不同的段:偏移量组合方法,比如2233FH这个地址,既可以表示为1234H:0FFFFH(在1234H段中),也可以表示为2233H:0000FH(在2233H段中)。
那么,如果汇编程序中有下面两个连续的段定义,汇编编译程序会怎么做呢?
name1 segment
d1 db 0
name1 ends
name2 segment
d2 db 0
name2 ends
  编译程序可以将name1和name2编译成一个段,d1和d2在内存中连续存放,这样可以节省内存空间。比如编译程序以name1为基准,将name1作为一个段的起始,程序加载后会被放在xxxx0H的地方,那么d1就放在该段偏移地址为0字节的位置,d2就放在该段偏移为1字节的位置。
  这样的处理方式虽然可能会节省一点内存空间,但是对于编译器的智能化要求太高了,它必须将源程序中所有引用到name2和d2的地方,全部调整为以name1段为基准,这实在是太难了,而且也节省不了几个字节的空间,编译器是不会干这种吃力不讨好的事的。
      编译器实际的处理方式是将name1中的所有内容放在一个段的起始地址处,name2里的所有内容放在后续一个段的起始地址处(这也是汇编指令segment的本义:将不同数据分段)。这样,即使name1中只包含一个字节,也要占一个段(16个字节),所以,一个段实际占用的空间=(段中字节数+15)/ 16。
  所以, 8086处理器的内部寻址原理和汇编程序编译器共同决定了segment定义的段必须放在按16的倍数对准的段地址边界上,占用的空间也是16的倍数。
2.mov ax, @data 中@的作用:
    

   这里的@是一个字符,MASM使用它与datacode等一起使用表示程序定义的数据段(data)、代码段(code)的段地址。类似“seg data”的功能。 

   上述指令的功能就是获得当前程序的数据段地址,并传送给数据段DS寄存器保存。这样,程序中访问存储器操作数时,默认情况下就会从DS指定的数据段进行存取。 

   在32Windows中的平展存储模型中,用户不必关心段寄存器的设置问题,所以,这样的程序中就不需要上述指令。 

   在16DOS平台中,需要用户程序明确设置DS,所以当程序使用数据段、需要访问数据段中的数据,往往需要设置DS。如果在16DOS平台中,不访问数据段(或者没有数据段、或者以其他形式访问数据段的数据),可以不设置DS。如果使用MASM 6.x支持的.startup语句,该语句包含有对DS设置的功能,也不必如上设置DS

(参考http://www2.zzu.edu.cn/qwfw/faqs/list.asp?id=425  )

(另:一个好的学习网站,其中的问题多是些常见的:http://www2.zzu.edu.cn/qwfw/index.asp

----------------------
(未完待续)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
汇编语言是一种低级的计算机语言,它直接与计算机硬件进行交互。下面是汇编语言的基础知识整理: 1. 汇编语言的作用:汇编语言用于编写底层程序,如操作系统、驱动程序和嵌入式系统等。 2. 汇编语言的特点:汇编语言是一种符号化的机器语言,使用助记符来代替二进制指令,使程序更易读和理解。 3. 寄存器:寄存器是汇编语言最基本的数据存储单元,用于存储数据和执行运算。常见的寄存器有通用寄存器、指针寄存器和标志寄存器等。 4. 指令:汇编语言的指令是对计算机硬件进行操作的命令。指令包括数据传输指令、算术运算指令、逻辑运算指令和控制指令等。 5. 内存访问:汇编语言通过内存地址来读取和存储数据。内存地址由段地址和偏移地址组成,通过段地址和偏移地址可以唯一确定内存的一个位置。 6. 标志位:标志位是标记计算机状态的标志位,用于判断运算结果是否满足某些条件。常见的标志位有零标志位、进位标志位和溢出标志位等。 7. 标号和跳转:汇编语言可以使用标号来标记程序的位置,通过跳转指令可以根据条件或无条件地跳转到指定的标号处。 8. 子程序和栈:子程序是一段独立的代码块,可以在程序被多次调用。栈是一种后进先出的数据结构,用于保存程序执行过程的临时数据和返回地址。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值