[MASM拾遗]Offset伪指令
Offset伪指令我一直都认为只是获取标识符在段中的偏移地址,但经研究,发现了部分违反直觉的细微区别:
1、在完整端声明(Full segment definition)的模式下
如果offset mygroup:myvar或offset mysegment:myvar,可通过端前缀来获取myvar与group开头位置的偏移地址或myvar与mysegment开头位置的偏移地址。
这里要注意的是offset并不受group的定义和assume的影响,因此无论myvar是否加入了组,只要offset myvar就只计算myvar与所在段的偏移地址,否则就加上段前缀mygroup:myvar或othersegment:myvar。
如下代码(Masm 5.00编译通过):
mygroup group datasg1,datasg2
assume cs:codesg,ds:mygroup
datasg1 segment public
myvar1 db 55,66
datasg1 ends
datasg2 segment public
myvar2 db 88,99
datasg2 ends
stacksg segment stack
db 256 dup(?)
stacksg ends
codesg segment
start:
mov al,myvar1
mov al,myvar2
mov ax,offset myvar1
mov ax,offset myvar2
mov ax,offset mygroup:myvar1
mov ax,offset mygroup:myvar2
mov ax,offset datasg1:myvar2
mov ax,4c00h
int 21h
codesg ends
end start
编译后的结果是:
2、在简单段声明(Simplified segment definition)的模式下
如果所属段与group起始位置未超过64K(即near),则offset返回myvar在group中的偏移地址;如果所属段与group起始位置未超过64K(即far),则返回myvar在segment中的偏移地址。
因为在简单段声明模式下,默认将段加入了组,并且offset的计算与group自动关联起来,而不用加段前缀。