#### 段 编制程序时要把存储器分成段 **代码段**:代码段是用来存放程序的指令序列,代码段的段地址存放在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开始计算。