段
编制程序时要把存储器分成段
代码段 :代码段是用来存放程序的指令序列,代码段的段地址存放在CS中,偏移地址在IP中。处理器将CS:IP所指向的内容视为指令。
数据段 :数据段存放当前运行程序所用的数据,段地址存放在DS中。
附加段 :附加段是附加的数据段,也用于数据的保存。另外,串操作指令将附加段作为其目的操作数的存放区域,附加段的段地址存放在ES。
堆栈段 :堆栈段是堆栈所在的主存区域。堆栈段的段地址存放在SS中,堆栈指针寄存器SP指向堆栈栈顶的偏移地址。
NASM使用汇编指令“SECTION”或“SEGMENT”来定义段,其一般格式是:
SECTION段名称
或
SEGMENT段名称
Intel处理器要求段在内存中的起始物理地址起码是16字节对齐的。意思是必须是16的倍数或者说该物理地址能被16整除。 相应的,汇编源代码中的各个段,也有对齐方面的要求。具体做法是在段定义中使用“align=”子句,用于指定某个SECTION的汇编地址对齐方式。
例:
align = 16 ;16字节对齐 align = 32 ;32字节对齐
获取段的汇编地址 :
在NASM中,可以用一下方法获取段的汇编地址:
section.段名称.start
注意:
虽然定义了段,但是引用某个标号时,该标号处的汇编地址依然是从整个程序的开头计算的,而不是从段的开头计算的。 使用`vstart=`可以解决这个问题。例:
SECTION data align=16 vstart=0 string :db 0 mov ax, string
则段data中的string的汇编地址将从该段开始计算,而且是从0开始计算。传送到ax中的数值是标号string相对于段data起始处的长度。
如果是这样的:
vstart=0x7c00
则该段的所有汇编地址都将从0x7c00开始计算。