MASM汇编中使用标号的三种方式
在Masm中,标号有3种形式:
1、带冒号的标号,
2、不带冒号的标号,
3、位于segment关键字前面的标号。
这3种标号,可通过直接引用名称或通过offset和seg伪指令来引用。大部分教程中都解释为取标号处的偏移地址和段地址,但稍有细微的区别:
通过代码实例,假设有汇编代码如下:
datasg segment
dataName dw 1234h
datasg ends
codesg segment
;-----------------------------------------------------------------
start:
jmp start
mov ax,offset start
mov ax,seg start
;-----------------------------------------------------------------
mov ax,dataName
mov ax,offset dataName
mov ax,seg dataName
;-----------------------------------------------------------------
mov ax,datasg
mov ax,offset datasg
mov ax,seg datasg
codesg ends
end start
1、带冒号的标号(主要作用是代表偏移地址),定义标号label:
代码的7、8行效果是相同的,取偏移地址;第9行是取start所在段的段地址。
mov ax,start会提示类型不对,因为start处并未定义数据的长度(如:db、dw等),但改成mov ax,word ptr start就可以,
2、不带冒号的标号(主要作用是代表变量及其长度),定义变量variable:
代码的11行是取dataName的值,12行是取dataName的偏移地址,13行是取dataName的段地址。
这种定义的标号还可以直接通过mov ax,dataName[bx]或mov ax,[dataName+2]等变址寻址的方式进行访问(注意变量的类型长度)。dataName默认按定义的类型进行操作,如果想访问数组dataName第1个元素(从0开始),则地址需+2,因为dataName定义的是word类型。
3、在segment关键字前面(主要作用是代表段地址):
其中15和17行效果是相同,取段地址;
16行表示masm编译到这段代码时,从本语句所在的段codesg的开始计算,到offset引用的datasg段最近的代码的偏移地址,即dataName dw123h的下一个字节(如果在编译器时,offset引用的段的代码已经编译完成,则表示段的长度;如果该段尚未完全编译完成,比如该段有多个段,或offset语句位于引用的段内:如本例codesg,则值为0。本例mov ax,offset datasg,ax的值是4,如果是offset codesg,则ax的值是0)。官方文档描述如下:For a segment name,the return value is the offset from the start fo the segment(本例指codesg) to the most recent bye generated for that segment(本例指datasg).
注意:在定义了.model的情况下,如果segment属于一个group,那么offset获的值是segment的结束地址,而不是开始地址。如果要引用segment的开始地址,通过group名称。如assume ds:dgroup。
★重要补充:
带冒号的标号不能跨段进行引用,但不带冒号的却可以。因为不带冒号的默认为数据,可通过ds、es进行定位。所以数据段都用不带标号的,带标号的只用来表示代码位置。
masm中不带标号的默认就是数据,带标号的默认就是代码地址。