[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自动关联起来,而不用加段前缀。

posted @ 2024-05-19 09:45  美洲象  阅读(15)  评论(0编辑  收藏  举报