Skip to main content

大戰系統程式 - 控制段組譯與連結載入

前面我們講了基本的組譯流程,而這篇主要要講的是怎麼樣合併兩個程式,因為通常我們寫完的程式碼不會只有一份檔案,而是會有數份。

這裡的細節爆炸多,所以一定要仔細看。第一步的組譯過程和之前一樣,我會把不一樣的地方寫出來,其它相同的地方不會再重複。

下方的內容如果有錯誤,歡迎來信更正!

組譯

下方的題目取自席家年教授的練習題,如有侵權請來信告知!

題目 PDF 下載

下方為練習卷 練習卷

可以發現到有兩份程式碼需要組譯,而且兩份程式碼裡面都出現了之前沒有出現的字。第一個步驟就是先把位址寫一寫,這裡位址和之前一樣。

第一份程式:

地址標記符號指令運算元
0000TSTPGMSTART0
EXTDEFREF4
EXTREFNXTREF
...
0029REF1LDX#ENDA-TSTA
002CREF2LDATSTA,X
002FREF3+LDSNXTREF-24
0033REF4EQU*
...
0050TSTAEDU*
...
0084ENDAEDU*
0084REF5WORDTSTA+8
0087RESB12
0093ENDREF1

上面這張表格跟之前的其實沒有什麼差別,但可以發現到有兩個比較特別的是 EXTDEF 和 EXTREF,這兩個就是外部引用的程式。

還有一個東西是 EDU,後面的運算元是一個 *,而這個我們就當成保留,不佔用空間。

第二份程式碼發現到地址幫我們上好,但我一樣寫在下面。

地址標記符號指令運算元
0000NXTPGMSTART0
EXTDEFNXTREF
...
0052NXTREFLDANXTREF+20
0055NXT1LDB#NXTREF
...
0090NXT2WORDNXT2-6
0093RESW5
00A2END

接下來就是把目地的碼算出來,過程跟之前都一樣。

第一份程式碼:

地址標記符號指令運算元目地碼
0000TSTPGMSTART0
EXTDEFREF4
EXTREFNXTREF
...
0029REF1LDX#ENDA-TSTA050034
002CREF2LDATSTA,X03A021
002FREF3+LDSNXTREF-246F1FFFF8
0033REF4EQU*
...
0050TSTAEDU*
...
0084ENDAEDU*
0084REF5WORDTSTA+8000058
0087RESB12
0093ENDREF1

第二份程式碼:

地址標記符號指令運算元目地碼
0000NXTPGMSTART0
EXTDEFNXTREF
...
0052NXTREFLDANXTREF+20032011
0055NXT1LDB#NXTREF692FFA
...
0090NXT2WORDNXT2-600008A
0093RESW5
00A2END

目的程式

跟之前一樣會有兩份目的程式,但這裡跟之前不太一樣,差別在於有 EXTREF 和 EXTDEF,這兩個都會生成比較特別的紀錄。

第一份

先從第一份程式碼開始,一樣的先從表頭紀錄開始

H,TSTPGM,000000,000093

接下來我們會有兩種新的紀錄,分別是 D 紀錄和 R 紀錄,D 紀錄在代表的是自己給別人用的程式,而 R 紀錄正好相反,代表的是自己使用別人的程式。

先寫 D 紀錄,要依序寫入的資訊如下:

  • 開頭字母 D
  • 六格的標紀符號,對應到 EXTDEF 後面所寫的標紀錄號
  • 六格的標紀符號所在位址

D,REF4☐☐,000033

再來寫 R 紀錄,和 D 紀錄相同,要依序寫入的資訊如下:

  • 開頭字母 R
  • 六格的標紀符號,對應到 EXTREF 後面所寫的標紀符號

R,NXTREF

接下來的本文紀錄和之前相同,下面不再重複。

T,000029,0A,050034,03A021,6F1FFFE8

T,000084,03,000058

再來是修正紀錄基本上和之前一樣,但是有一個紀錄不太一樣。

注意到標紀位址在 REF3 那一行,可以發現到計算的時候使用到了 NXTREF 這個標紀符號,仔細看就會發現到這個使用到了 EXTREF 所標紀的符號,所以修正紀錄也要基於 NXTREF,而不是 START 的 TSTPGM,換句話說就是這裡是基於外部的程式。

M,000030,05,+NXTREF

還有一行需要修正的是 REF5,這行的話沒有什麼特別的,修正紀錄如下:

M,000084,06,+TSTPGM

最後的結束紀錄和之前一樣,沒什麼特別的

E,000029

第二份

表頭紀錄如下:

H,NXTPGM,000000,0000A2

D 紀錄如下:

D,NXTREF,000052

本文紀錄如下:

T,000052,06,032011,692FFA

T,000090,03,00008A

修正紀錄一個,如下:

M,000090,06,+NXTPGM

結束紀錄就一個 E

連結載入

接下來就是要模擬在電腦中實際載入兩份程式碼之後會發生的事,假設載入的起始位址的 5000。

而外部符號表要處理的地方比較多,控制段其實就是程式的外稱,像 TSTPGM 指的就是第一份程式碼。符號名稱就是 EXTDEF 後面寫的標紀符號,位址的話就是 START 的位址跟 END 的位址,長度就是兩者相減。

第二份程式碼跟第一份的步驟相同,但是位址要接在第一份之後。

控制段符號名稱位址長度
TSTPGMREF45000~509393
NXTPGMNXTREF5093~50E5A8

實際上執行的時候修正紀錄就會發揮作用,下面舉幾個例子,也就是練習卷的題目。

REF3 +LDS NXTREF-24 載入到記憶體的位址為 502F,修正後的目的碼為 6F1050CD

目的碼的算法就是看修正紀錄怎麼寫就怎麼做,像這題的修正紀錄是 M,000030,05,+NXTREF,所以我們要做的就是把 1FFFF8 拿出來加上 NXTREF,而 NXTREF 的值為 50E5,可以對應到剛剛的外部符號表。

REF5 WORD TST+8 載入到記憶體的位址為 5084,修正後的目的碼為 005058

NXT1 LDB #NXTREF 載入到記憶體的位址為 50E8

而最後,程式開始的地方就是第一條本文記錄開始的地方,需要注意一下要再加上初始地址,得到 5029