编制程序时要把存储器分成段

代码段:代码段是用来存放程序的指令序列,代码段的段地址存放在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开始计算。