MASM中ORG偽指令的作用
??在學(xué)習(xí)16位MASM匯編時(shí),生成一個(gè)com格式的可執(zhí)行文件,需要在代碼的第一行寫上org 0100h,各處的資料解釋不盡相同,如:
??1、程序從0100h處開始執(zhí)行;
??2、告訴編譯器講程序加載到0100h;
??3、代碼的偏移地址整體向后移動(dòng)0100h,或段內(nèi)的代碼或數(shù)據(jù)從0100h開始放置。
??這些解釋在當(dāng)時(shí)的情況作用確實(shí)如此,但是org為什么有這么多功能呢,經(jīng)過(guò)讀取官方文檔才明白:
??org的作用很簡(jiǎn)單,就是告訴編譯器,當(dāng)編譯到org指令時(shí),org指令后面的代碼從org指定的偏移地址開始,即編譯器將org后面生成的機(jī)器碼,從org指定的偏移地址開始放置。官方文檔原文:ORG expression,Subsequent code and data offsets begin at the new offset specified set by expression。
??首先,MASM中所有的數(shù)據(jù)和代碼都必須屬于某個(gè)段(segment),段中的代碼和數(shù)據(jù)都是通過(guò)偏移地址(offset,段中代碼或數(shù)據(jù)相對(duì)于段首的距離)進(jìn)行訪問的,如:
datasg segment
msg1 db "hello"
msg2 db "word"
datasg ends
??如果沒有org偽指令,數(shù)據(jù)和代碼按順依次存儲(chǔ)和編址。該代碼msg1的偏移地址就是[0000],msg2的偏移地址是[5],因?yàn)?h'、'e'、'l'、'l'、'o'把前面5個(gè)空間占用了(地址從0開始編碼,即[0000]、[0001]、[0002]、[0003]、[0004]5個(gè)地址)。
如果改成如下代碼:
datasg segment
org 0005h
msg1 db "hello"
msg2 db "word"
datasg ends
??編譯器在編譯時(shí),就會(huì)從偏移地址[0005]處開始放置數(shù)據(jù),即'h'、'e'、'l'、'l'、'o'的偏移地址分別是[0005]、[0006]、[0007]、[0008]、[0009]。那前面的5個(gè)空間做什么用了呢,答案是:空著。所以,并不只是將地址從0005處開始編碼,而是真的把數(shù)據(jù)放到哪個(gè)位置去,后面的數(shù)據(jù)依次放置。
??那是不是數(shù)據(jù)整體偏移了呢,答案是:不完全對(duì),如下示例:
datasg segment
org 0005h
msg1 db "hello"
org 0002h
msg2 db "word"
datasg ends
??如果是數(shù)據(jù)整體后移,那就是msg1的地址是向后移動(dòng)5個(gè)即[0005],msg2的地址也向后移動(dòng)2個(gè),即[0009]+2=[000B]呢,答案是否定的。后面的msg2,會(huì)從[0002]處開始放置,顯然,會(huì)覆蓋msg1的數(shù)據(jù)。
??驗(yàn)證如下,如下代碼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個(gè)字節(jié)空著,msg2的數(shù)據(jù)覆蓋了部分msg1的數(shù)據(jù)。
??問題1:那com文件中org 0100h到底是不是告訴系統(tǒng)從0100h處開始執(zhí)行呢?
??答:當(dāng)然不是,系統(tǒng)是從0100h處開始執(zhí)行,但不是org 0100h導(dǎo)致的,是系統(tǒng)加載com文件就會(huì)從偏移地址0100h處執(zhí)行,無(wú)論該處是否有正確的代碼或編譯時(shí)是否有org指令。如何保證0100處有正確的代碼,org 0100h就能達(dá)到目的。哪怕org指令后是jmp都行,然后跳轉(zhuǎn)到正確的代碼地址處。16位cpu是從偏移地址0100h處執(zhí)行,那段地址呢,一段程序不是有好多段么,cs、ds、ss,是哪個(gè)段呢?答:com文件只有一個(gè)段,cs、ds、ss地地址都相同,所以不用指定。
??參考代碼如下:
assume cs:_text,ds:_text,ss:_text
_text segment
org 100h
begin:
jmp start
msg db "Hello,world!",13,10
lmsg equ $ - msg
start:
mov ah,40h
mov bx,1
mov dx,offset msg
mov cx,lmsg
int 21h
mov ax,4c00h
int 21h
_text ends
end begin
??問題2:mbr程序中的org 7c00h是不是道理一樣呢?
??答:當(dāng)然一樣,系統(tǒng)自檢后就是從7c00h處開始執(zhí)行,你只要在偏移地址7c00h處有正確的代碼,就可以繼續(xù)啟動(dòng)。電腦自檢完成后,加載mbr程序到內(nèi)存,程序的段地址置入[0000],從偏移地址[7c00]處開始啟動(dòng)os代碼。
??問題3:類似的功能的偽指令還有么?
??答:當(dāng)然有,如even和align偽指令。

浙公網(wǎng)安備 33010602011771號(hào)