0%

System Software

Simplified Instruction Computer 簡化指令電腦(SIC)

Standard model (SIC) 標準版本

Two versions of SIC

  • standard model (SIC) 標準版本
  • extension version (SIC/EX) EX版本
    • extra equipment 更多設備指令
    • extra expensive 更貴
    • upward compatible 向上兼容

Memory

  • 8-bit bytes 由byte組成
  • 3 consecutive bytes form a word 連續三個byte形成word
  • 32758(2^15) bytes in the computer memory 電腦裡有32768個bytes

Register

Data format

  • Integers are stored as 24-bit binary number 整數以24bit的二進制表示
  • For negative values, use 2’s complement to represent 用2的補數表示負數
  • Character stored by ASCII code 字元以ASCII表示
  • No floating-point 沒有浮點數

Instruction formats

可拆分為

8 bit opcode

1 bit x 用來表示是否為索引定址模式

15 bit address 因為記憶體大小為2^15 bytes 因此15個bits 就可以表示所有記憶體位置

模式 指定 目標位址的算法
直接 x=0 目標位址 =位址
索引 x=1 目標位址 =位址 +(X暫存器的值)

Instruction set

  • Load and Store 載入和儲存暫存器
    • LDA, LDX, STA, STX 載入,儲存一個word進暫存器
    • LDCH, STCH 載入,儲存一個byte進暫存器並且多餘空間補0
  • Integer arithmetic operation 整數算數運算指令
    • ADD, SUB, MUL, DIV
  • Comparison 比較大小
    • COMP, compares the value in register A with a word in memory and sets a condition code CC
  • Conditional jump instructions 條件跳躍指令
    • JLT, JEQ, JGT (<,=,>)
    • Test the setting of CC and jump accordingly
1
2
COMP 	0030	//比較A暫存器跟記憶體0030位置的大小 並將結果存在CC
JLT 3120 //檢視CC是否符合JLT 若符合則將PC改為3120
  • Subroutine jump 副程式跳躍
    • JSUB, jump to subroutine 跳到副程式
    • RSUB, jump to the address of register L 跳到暫存器L
    • Use register L to store return address 使用暫存器L存取回傳位址
  • No memory to memory move instruction

Input and Output

  • Starts from the 8 rightmost bits of register A
  • All device have a 8 bits device code
  • SIC have 3 I/O instruction
    • TD(Test Device)
    • RD(Read Device)
    • WD(Write Data)

Directive

定義資料儲存空間的指示

  • START, END 程式開始、結束地方

  • WORD 保留一個word的空間當作常數

  • RESW 保留一個以上的word的空間當作變數

  • BYTE, RESB 保留一個byte的空間

1
2
3
4
ALPHA	RESW	3	//ALPHA的位址保留3個word大小
FIVE WORD 5 //FIVE的位址放入5
CHARZ BYTE C'Z' //CHARZ的位址放入Z
C1 RESB 1 //c1的位址保留1個BYTE大小

Extension version (SIC/EX) EX版本

Memory

  • 1048576(2^20) bytes in the computer memory 電腦裡有32768個bytes

Register

Instruction format

Addressing modes

  • 格式3 Base relative 相對於基底(n = 1, i = 1, b = 1, p = 0)
    • TA = (B) + disp (0 < disp < 4095)
  • 格式3  Program-counter relative 相對於PC暫存器(n = 1, i = 1, b = 0, p = 1)
    • TA = (PC) + disp (-2048 < disp < 2047)
  • 格式3 Direct(n = 1, i = 1, b = 0, p = 0)
    • TA = disp (0 < disp < 4095)
  • 格式3 Indirect(n = 1, i = 0, x = 0)
    • TA = (disp) 去disp位址取真正要跳的位址
  • 格式3 Immediate(n = 0, i = 1, x = 0)
    • operand = disp
  • 格式3 Indexing(n = i, x = 1)
    • TA = (X) + Original TA
  • 格式4 Extended(e = 1)
  • 格式3 Simple
    • n = i = 0 時 = SIC版本
    • n = i = 1 時 = XE版本

Instruction set

  • New Load and Store 載入和儲存暫存器
    • LDB, STB…
  • Floating-point arithmetic 浮點數算數運算指令
    • ADDF, SUBF, MULF, DIVF
  • 格式2 Register move 暫存器移動
    • RMO
  • 格式2 Register-Register arithmetic 暫存器對暫存器計算
    • ADDR, SUBR, MULR, DIVR
  • Supervisor call 系統呼叫指令
    • SVC

Code sample

求目的位址以及載入暫存器的值

1
2
3
4
5
6
7
-Hex-	  -op-	 -nixbpe-	-disp-
032600 000000 1 1 0 0 1 0 0110 0000 0000 //Program-counter relative
03C300 000000 1 1 1 1 0 0 0011 0000 0000 //Base relative
022030 000000 1 0 0 0 1 0 0000 0011 0000 //Indirect
010030 000000 0 1 0 0 0 0 0000 0011 0000 //Immediate
003600 000000 0 0 0 0 1 1 0110 0000 0000
0310C303 000000 1 1 0 0 0 1 0000 1100 0011 0000 0011

Load and Store

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-----------------------SIC版本-----------------------
LDA FIVE //將FIVE位址的值存入A暫存器
STA ALPHA //將A暫存器的值存入ALPHA位址
LDCH CHARZ //從CHARZ位址讀一個字元進暫存器A
STCH C1 //把暫存器A的字元存入C1位址
.
.
.
ALPHA RESW 3 //ALPHA的位址保留3個word大小
FIVE WORD 5 //FIVE的位址放入5
CHARZ BYTE C'Z' //CHARZ的位址放入Z
C1 RESB 1 //c1的位址保留1個BYTE大小
-----------------------XE版本-----------------------
LDA #5 //#為立即值(Immediate) 將5存入A暫存器
STA ALPHA //將A暫存器的值存入ALPHA位址
LDCH #90 //將ASCII=90的字元存進暫存器A
STCH C1 //把暫存器A的字元存入C1位址
.
.
.
ALPHA RESW 3 //ALPHA的位址保留3個word大小
C1 RESB 1 //c1的位址保留1個BYTE大小

Arithmetic operation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//已將ALPHA,BETA,INCR變數值讀入
-----------------------SIC版本-----------------------
LDA ALPHA //將ALPHA位址的值存入A
ADD INCR //暫存器A += INCR
SUB ONE //暫存器A -= 1
STA BETA //將暫存器A的值存入BETA位址
LDA GAMMA //將GAMMA位址的值存入A
ADD INCR //暫存器A += INCR
SUB ONE //暫存器A -= 1
STA DELTA //將暫存器A的值存入DELTA位址
.
.
.
ONE WORD 1
ALPHA RESW 1
BETA RESW 1
GAMMA RESW 1
DELTA RESW 1
INCR RESW 1
-----------------------XE版本-----------------------
LDS INCR //將INCR位址的值存入S
LDA ALPHA //將ALPHA位址的值存入A
ADDR S, A //S + A 後放回A
SUB #1 //暫存器A -= 1
STA BETA //將暫存器A的值存入BETA位址
LDA GAMMA //將GAMMA位址的值存入A
ADDR S, A //S + A 後放回A
SUB #1 //暫存器A -= 1
STA DELTA //將暫存器A的值存入DELTA位址
.
.
.
ALPHA RESW 1
BETA RESW 1
GAMMA RESW 1
DELTA RESW 1
INCR RESW 1

Looping and indexing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-----------------------SIC版本-----------------------
LDX ZERO //初始化X暫存器為0
MOVECH LDCH STR1, X //從暫存器A讀取index為X的一個char進去
STCH STR2, X //將暫存器A index為X的char存入STR2
TIX ELEVEN //先將X暫存器值+1後跟ELEVEN比對 值放入CC
JLT MOVECH //如果CC是小於則跳回MOVECH
.
.
.
STR1 BYTE C'TEST STRING' //將後面字串丟入STR1
STR2 RESB 11
ZERO WORD 0
ELEVEN WORD 11
-----------------------XE版本-----------------------
LDT #11 //初始化T暫存器為11
LDX #0 //初始化X暫存器為0
MOVECH LDCH STR1,X //從暫存器A讀取index為X的一個char進去
STCH STR2,X //將暫存器A index為X的char存入STR2
TIXR T //先將X暫存器值+1後跟T暫存器值比對 值放入CC
JLT MOVECH //如果CC是小於則跳回MOVECH
.
.
.
STR1 BYTE C'TEST STRING'
STR2 RESB 11

Input and output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
INLOOP	TD	INDEV	//測試輸入裝置
JEQ INLOOP //迴圈直到輸入裝置準備好
RD INDEV //讀一個字元進入暫存器A
STCH DATA //把暫存器A的字元存入DATA位址
.
.
OUTLP TD OUTDEV //測試輸入裝置
JEQ OUTLP //迴圈直到輸入裝置準備好
LDCH DATA //從DATA位址讀一個字元進暫存器A
WD OUTDEV //將字元輸出
.
.
INDEV BYTE X'F1' //輸入裝置代號F1
OUTDEV BYTE X'05' //輸出裝置代號05
DATA RESB 1

Subroutine call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
-----------------------SIC版本-----------------------
JSUB READ //呼叫READ副程式
.
.
.
.
READ LDX ZERO //初始化X暫存器為0
RLOOP TD INDEV //測試輸入裝置
JEQ RLOOP //迴圈直到輸入裝置準備好
RD INDEV //讀一個字元進入暫存器A
STCH RECORD,X //把暫存器A的字元存入RECORD位址
TIX K100 //先將X暫存器值+1後跟K100比對 值放入CC
JLT RLOOP //如果CC是小於則跳回RLOOP
RSUB //離開副程式
.
.
.
INDEV BYTE X'F1' //輸入裝置代號F1
RECORD RESB 100
.
ZERO WORD 0
K100 WORD 100
-----------------------XE版本-----------------------
JSUB READ
.
.
.
.
READ LDX #0
LDT #100
RLOOP TD INDEV
JEQ RLOOP
RD INDEV
STCH RECORD,X
TIXR T
JLT RLOOP
RSUB
.
.
.
INDEV BYTE X'F1'
RECORD RESB 100

Assembler組譯器

Role of Assembler

Basic SIC assembler directive

參照這裡的Directive

Fundamental functions of assembler

  1. 將助憶碼轉換成對應的機器語言 EX:STL -> 14
  2. 把符號運算元轉換成對應的位址 EX:RETADR -> 1033
  3. 依照格式建立指令
  4. 將程式內的常數資料轉換成機器內部的表示方式 EX:EOF -> 454F46
  5. 產生目的馬程式和組譯列表

Address translation problem

  • Foward reference 前向參考問題: 程式涉及一個尚未定義的標記符號

Two pass assembler

  1. 先走訪並記錄程式裡面每一行指令的記憶體位址
  2. 組譯指令產生目的碼

  • 運算碼表 (Operation Code Table; OPTAB)
    • 儲存助憶指令與機器碼之關連
    • 使用Hash Table,使用助憶碼作為key
    • 第一回合用來檢驗運算碼及計算指令長度
    • 第二回合用來轉換運算碼至機器碼
    • Static結構
  • 符號表 (Symbol Table; SYMTAB)
    • 儲存Labels的代表位址
    • 包含Labels名稱、位址、長度、型態和error flags
    • 使用Hash Table加速
    • Dynamic結構
  • 程式計數器 (Location Counter ; LOCCTR)
    • 初始值為START指派的值
    • 記錄下一個指令的位址
  • Intermediate file
    • 由pass1寫入並當pass2的input
    • 包含:
      • 在pass1所得到的記憶體位址
  • pass1

    主要找出label與addr對應的位置建立SYMTABLE

  1. 判斷指令長度(透過OPTAB)
  2. 計算LOCCTR
  3. 將lable的地址保存到SYMTABLE
  4. 處理pseudo instruction
  • pass2

    產生obj

  1. 透過SYMTAB帶入pass1沒有處理的symbol
  2. 透過OPTABLE產生機器碼
  3. 計算LOCCTR
  4. 產生pseudo定義的數據如BYTE, WORD
  5. 處理pass1未處理的pseudo

Addressing mode

  • 間接定址(@)、立即定址(#)、索引定址(,x)都必須指定
  • 若沒有使用extended(+)
    • 先試著使用PC定址
    • 若超出範圍則試著使用Base定址
    • 若兩者都不適用則會生成錯誤訊息

Programing relocation

assembler透過obj檔告訴loader程式那些地方需要被修正

SIC版本:

由於很多指令都是直接定址,若被載入到不同位址較易被影響

透過obj檔指令進行修正

XE版本:

由於很多指令都是透過PC相對定址,若被載入到不同位址較不易被影響

若從5000開始

則4B101036修正成4B106036

Sysmbol-Defining Statements

  • 定字 Literal
  • 符號定義敘述 EQU&ORG
  • 運算式 Expression
  • 程式區段 Program blocks
  • 控制區段與程式連結 Control Sections and Program Linking

Literal

  • 直接將常數運算元的值當成指令的一部份
  • 避免在程式的其他區段定義這常數,並給予常數一個標記
  • 使用 “=”來做判定
  • LTORG為希望literal被放置在目的程式的位置
  • 範例:
    • 45行的LDA 組譯器會將他轉成
      LDA EOF
      EOF BYTE C’EOF’ <–這句塞在下一個LTORG指示的位址,若到程式結束前還沒有LTORG則寫在程式最後這兩行,所以機器碼其實跟沒有使用定字的機器碼一樣
Literal table(LITTLAB)
  • literal-name, oprend-value, length, assingned-address

  • Pass 1

    • 先在LITTAB 中建立literal-name, oprend-value, length, assingned-address且暫不指定位址
    • 當碰到LTORG 敘述時,對尚未指定位址的每一個literals指定一個位址給他
  • Pass 2

    • 對每一個碰到的定字運算元,搜尋LITTAB
    • 使用BYTE 或WORD 敘述,產生對應值
    • 對於定字產生修改紀錄(modification record),用以表示在程式 中的位址
Code

EQU&ORG

EQU
  • 定義符號(symbol)並指定數值 類似於宣告變數
1
2
3
4
5
105	0036	BUFFER	RESB	4096
106 1036 BUFEND EQU * // *號為當前位址 1036並非是location而是後面EQU算出來的結果
107 1000 MAXLEN EQU BUFEND-BUFFER // 1000並非是location而是後面EQU算出來的結果
-------------------------------
BUFEND-BUFFER = 1036 - 0036 = 1000H = 4096
ORG(origin)
  • 將位置計數器(LOCCRT) 的值重新設定為所指定值

考慮以下標籤

SYMBOL 6 BYTES

VALUES 1 WORD

FLAGS 2 BYTES

  • 使用EQU
1
2
3
4
STAB	RESB	1100
SYMBOL EQU STAB
VALUE EQU STAB+6
FLAGS EQU STAB+9
  • 使用ORG
1
2
3
4
5
6
STAB	RESB	1100
ORG STAB //讓LOCCRT回到STAB
SYMBOL RESB 6
VALUE RESW 1
FLAGS RESB 2
ORG STAB+1100 //讓LOCCRT回到STAB+1100

Expression

  • 運算式可以分成絕對運算式(A)或是相對運算式(R)

Program blocks

  • 在每一行原始程式中,給定一個相對位址和一個區塊號碼

  • 對於絕對符號,不需要區塊號碼,例:line107

  • 指令的實際位址 = Block address + 該指令在block中的位址

  • Pass 1

    • 每一個程式區塊有一個別的位址計數器(location counter)
    • 每一個標記(label)所被指定的位址相對於包含它的區塊開始位址
    • 在第一次執行的結束,對於每一個區塊之位址計數器的最新值表示這個區塊的長度
    • 組譯器然後能夠在目的程式中指定每個程式區塊一個開始位址
  • Pass 2

    • 每一個符號的位址能夠利用所指定區塊的起始位址加上這個符號相對於此區塊的相對位址計算出來
  • 使用Program blocks的好處

    • 不需要使用Extend指令格式
    • 不需要使用基底(Base)定址
    • 增加程式可讀性
  • Obj檔

Control section

  • 控制區塊(control section)是程式的一部份,並且在經過組譯後仍然保有原來的本質
  • 不同的控制段通常是扮演副程式,或程式內的邏輯單元
  • 使用外部定義EXTDEF(External defination)、外部參考EXTREF(External reference)
EXTDEF & EXTREF
  • EXTDEF name [,name]
    • 對外開放這個程式區段的某些指示
  • EXTREF name [,name]
    • 引用其他程式區段的指示
Code

Obj

Assembler design options

One-pass assembler

  • Forward reference problem

  • 兩種主要類型

    • 直接在記憶體裡產生目的碼
    • 先產生obj檔之後再給載入器執行
  • Load-and-Go assembler

    • 在記憶體產生目的碼以便立即執行

    • 不需要載入器

    • 對程式開發和測試有幫助

    • 避免不必要的耗損

    • Forward reference在Load-and-Go assembler的處理方法

      x代表預留記憶體位址RESW類的

Multi-pass assembler

Code sample

SIC版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
COPY	START	1000	//程式進入點 開始位置=1000
FIRST STL RETADR //儲存Return address進L暫存器
CLOOP JSUB RDREC //進入RDREC副程式
LDA LENGTH //將LENGTG讀入暫存器A
COMP ZERO //測試EOF(LENGTH 是否= 0)
JEQ ENDFIL //jump如果EOF
JSUB WRREC //進入WRREC副程式
J CLOOP //迴圈
ENDFIL LDA EOF
STA BUFFER
LDA THREE
STA LENGTH
JSUB WRREC
LDL RETADR
RSUB //返回主程式
EOF BYTE C'EOF'
THREE WORD 3
ZERO WORD 0
RETADR RESW 1
LENGTH RESW 1
BUFFER RESB 4096
.
.
.
RDREC LDX ZERO //初始化暫存器X = 0
LDA ZERO //初始化暫存器A = 0
RLOOP TD INPUT //測試輸入裝置
JEQ RLOOP //迴圈直到輸入裝置準備好
RD INPUT //讀入一個字元進入暫存器A
COMP ZERO //跟0比較
JEQ EXIT //如果EOF跳出迴圈
STCH BUFFER,X //把暫存器A的字元存入BUFFER位址
TIX MAXLEN //先將X暫存器值+1後跟MAXLEN比對 值放入CC
JLT RLOOP //如果CC是小於則跳回RLOOP
EXIT STX LENGTH //儲存長度
RSUB //返回主程式
INPUT BYTE X'F1'
MAXLEN WORD 4096
.
.
.
WRREC LDX ZERO
WLOOP TD OUTPUT
JEQ WLOOP
LDCH BUFFER,X
WD OUTPUT
TIX LENGTH
JLT WLOOP
RSUB
OUTPUT BYTE X'05'
END FIRST

XE版本


1
2
3
12	0003		LDB	#LENGTH	69202D	//立即定址
--------------------------------------
disp = LENGTH - PC = 0033 - 0006 = 002D

69202D -> 011010 0 1 0 0 1 0 0000 0010 1101


1
15	0006	CLOOP	+JSUB	RDREC	4B101036	//擴充格式

4B101036 -> 010010 1 1 0 0 0 1 0000 0001 0000 0011 0110


1
70	002A		J	@RETADR	3E2003	//間接定址

3E2003 -> 001111 1 0 0 0 1 0 0000 0000 0011


1
2
12	0003		LDB	#LENGTH	69202D
13 BASE LENGTH

BASE是directive,代表BASE暫存器內容可以使用,並且指定BASE為0033


1
2
3
4
165	104E		TIXR	T	B850
--------------------------------------
disp = BUFFER - PC = 0036 - 1051 = -101B > PC定址範圍 -> 嘗試使用Base定址
disp = BUFFER - Base = 0036 - 0033 = 3 -> 使用Base定址

1
2
3
4
5
175	1056	EXIT	STX	LENGTH	134000
--------------------------------------
disp = LENGTH - PC = 0033 - 1059 = -1026 > PC定址範圍 -> 嘗試使用Base定址

disp = LENGTH - Base = 0033 - 0033 = 0 -> 使用Base定址