MASM中ORG伪指令的作用

发布时间 2023-08-31 20:37:11作者: 美洲象

  在学习16位MASM汇编时,生成一个com格式的可执行文件,需要在代码的第一行写上org 0100h,各处的资料解释不尽相同,如:

  1、程序从0100h处开始执行;

  2、告诉编译器讲程序加载到0100h;

  3、代码的偏移地址整体向后移动0100h,或段内的代码或数据从0100h开始放置。

  这些解释在当时的情况作用确实如此,但是org为什么有这么多功能呢,经过读取官方文档才明白:

  org的作用很简单,就是告诉编译器,当编译到org指令时,org指令后面的代码从org指定的偏移地址开始,即编译器将org后面生成的机器码,从org指定的偏移地址开始放置。

  首先,MASM中所有的数据和代码都必须属于某个段(segment),段中的代码和数据都是通过偏移地址(offset,段中代码或数据相对于段首的距离)进行访问的,如:

datasg segment
    msg1 db "hello"
    msg2 db "word"
datasg ends

  如果没有org伪指令,该代码msg1的偏移地址就是[0000],msg2的偏移地址是[5],因为'h'、'e'、'l'、'l'、'o'把前面5个空间占用了(地址从0开始编码,即[0000]、[0001]、[0002]、[0003]、[0004]5个地址)。

如果改成如下代码:

datasg segment
    org 0005h
    msg1 db "hello"
    msg2 db "word"
datasg ends

  编译器在编译时,就会从偏移地址[0005]处开始放置数据,即'h'、'e'、'l'、'l'、'o'的偏移地址分别是[0005]、[0006]、[0007]、[0008]、[0009]。那前面的5个空间做什么用了呢,答案是:空着。所以,并不只是将地址从0005处开始编码,而是真的把数据放到哪个位置去,后面的数据依次放置。

  那是不是数据整体偏移了呢,答案是:不完全对,如下示例:

datasg segment
    org 0005h
    msg1 db "hello"
    org 0002h
    msg2 db "word"
datasg ends

 如果是数据整体后移,那就是msg1的地址是向后移动5个即[0005],msg2的地址也向后移动2个,即[0009]+2=[000B]呢,答案是否定的。后面的msg2,会从[0002]处开始放置,显然,会覆盖msg1的数据。

  验证如下,如下代码masm5编译后,debug载入:

assume cs:codesg,ss:stacksg,ds:datasg
;--------------------------------------
stacksg segment stack
stacksg ends
;--------------------------------------
datasg segment
    org 0005h
    msg1 db "aaaaa"
    org 0002h
    msg2 db "bbbbb"

datasg ends
;--------------------------------------
codesg segment
    start:

    mov ax,datasg
    mov ds,ax
    
    mov ax,4c00h
    int 21h


codesg ends
end start

  

  datasg段的前2个字节空着,msg2的数据覆盖了部分msg1的数据。