下面的内容都是我自己的一些想法,可能不正确,如有錯,請指出來,我會及時更改。
首先,我先編寫一個main.asm彙編源程式,要明确的是,不同的彙編指令轉化成二進制機器指令時,會有多個位元組,不同指令所占用的位元組是不同的。知道占用多個位元組就可以了。
看下圖,反彙編下指令的位址和機器指令,我編寫的main.asm轉化為機器指令,指令的位址是從076B:0000開始的。

編譯
編譯将我所寫的main.asm檔案轉化為main.obj檔案,生成一個目标檔案。
轉化為目标檔案的規則:假設我有一條語句是jmp next反彙編之後,就是變成了jmp 2500,那麼這個2500就是相對我自己寫的代碼段的偏移位址。
再假設我有一條語句是 mov ax,Y 那麼轉化成機器語言之後,再反彙編就是
mov ax,[0002]就是相對資料段的偏移位址為2的内容送至ax。
雖然程式是按編譯->連結->裝入的方式執行的,但是可以先跳到裝入的内容看一下。
連結
就是将多個目标子產品連結成一個大目标子產品。
每個子產品中的指令位址都是從0開始的。
比如三個目标子產品A,B,C
A所有指令位址為0 - L-1, B所有指令位址為0 - M-1,C所有指令位址為0 - N-1。
裝入
這些内容都是按着時間線慢慢發展起來的,針對當時的不同的條件,所思考出的不同政策。
1.絕對裝入方式
隻适合運作單程式。
每次将程式裝入記憶體中初位址為R的地方,那麼執行jmp 2500就是跳到jmp R+2500的地方,繼續執行。
2.可重定位裝入方式
适用于多程式
可重定位就是給cpu配置兩個寄存器基址寄存器、變址寄存器
首先,OS會給程式配置設定一個起始位址,假設10000,儲存在基址寄存器中,從這個起始位址,将程式的所有指令依次放入記憶體中。那麼原來的指令jmp 2500放入記憶體中就會變成jmp 12500。
變址寄存器是存放代碼的長度,防止越界的。
3.動态運作時的裝入方式
考慮一個程式會被分成多個部分,而這些部分可能會被多次換出,又被多次換入,放入記憶體中的實體位址就會改變。顯然,可重定位裝入方式就不适用了。
那麼對應其解決的政策就是原本的指令jmp 2500依舊放入記憶體中,當程式運作時,再将其轉化為jmp12500執行,如果,這段代碼更改位址了,可能會執行jmp 32500(由這段代碼所在實體位址決定)。
再扯一點,因為隻有一個基址寄存器,當有多個程序在記憶體中,那麼應該儲存哪個程序的起始位址呢?
實際上,每次會給一個剛運作的程式配置設定一個起始位址,當程序變為阻塞、切換其他程序時,會将這個起始位址儲存在這個程序的PCB中。并且會把基址寄存器的内容修改為下一個将要運作程序的起始位址(在PCB中檢視是否有起始位址,沒有的話則系統配置設定一個)。
每個程序都有自己的PCB。