MASM中ORG僞指令的作用

  在學習16位MASM彙編時,生成一個com格式的可執行文件,需要在代碼的第一行寫上org 0100h,各處的資料解釋不盡相同,如:

  1、程序從0100h處開始執行;

  2、告訴編譯器講程序加載到0100h;

  3、代碼的偏移地址整體向後移動0100h,或段內的代碼或數據從0100h開始放置。

  這些解釋在當時的情況作用確實如此,但是org爲什麼有這麼多功能呢,經過讀取官方文檔才明白:

  org的作用很簡單,就是告訴編譯器,當編譯到org指令時,org指令後面的代碼從org指定的偏移地址開始,即編譯器將org後面生成的機器碼,從org指定的偏移地址開始放置。官方文檔原文:ORG expression,Subsequent code and data offsets begin at the new offset specified set by expression。

  首先,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的數據。

  問題1:那com文件中org 0100h到底是不是告訴系統從0100h處開始執行呢?

  答:當然不是,系統是從0100h處開始執行,但不是org 0100h導致的,是系統加載com文件就會從偏移地址0100h處執行,無論該處是否有正確的代碼或編譯時是否有org指令。如何保證0100處有正確的代碼,org 0100h就能達到目的。哪怕org指令後是jmp都行,然後跳轉到正確的代碼地址處。16位cpu是從偏移地址0100h處執行,那段地址呢,一段程序不是有好多段麼,cs、ds、ss,是哪個段呢?答:com文件只有一個段,cs、ds、ss地地址都相同,所以不用指定。

  問題2:mbr程序中的org 7c00h是不是道理一樣呢?

  答:當然一樣,系統自檢後就是從7c00h處開始執行,你只要在偏移地址7c00h處有正確的代碼,就可以繼續啓動。電腦自檢完成後,加載mbr程序到內存,程序的段地址置入[0000],從偏移地址[7c00]處開始啓動os代碼。

  問題3:類似的功能的僞指令還有麼?

  答:當然有,如even何align僞指令。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章