# System Programming
## CH1 SIC/XE
3/12
具有計算浮點數的簡化指令計算機
### Memory
: 2^20 bytes
因為Memory被擴大,所以addressing modes 和 Instruction Format等等都要改
### Registers
一樣有A,X(陣列),L(Function),SW(IF),PC
多一些暫存器,B,S,T,F(支援浮點數)
### Data Format
Interger / Character
等等基本的都差不多
## **Instruction Format**
+ Relative addressing
+ Extend the address field to 20 bits
```
Format 1: op 1 byte
Format 2: op 1 byte .. r1..r2 和Memory無關
Format 3:因為一個OP code 他的第七第八個的bit都為0
--> 0x18 0001 1000
0x9c 1001 1100
op 6 bits + nixbpe + disp 12 bits
Format 4:op 6 bits + nixbpe + addressing mode 20 bits
```
不同的Format 和 PC+多少有關
### Instruction set
新的暫存器
多了浮點數運算
多了Register Move(RMO)
## **Addressing mode**
指令會存取到memory 例如ADD,m 會可能是Format 3 or 4
```
e : Format 3 or 4
x, b, p:決定到哪個MEMORY的address抓資料回來計算
x類似於陣列的索引
b, p
0, 0:disp/address通常發生在format 4
1, 0:Target Address: base+ disp + x
0, 1:Target Address: PC + disp + x
```
考試考Target Address

B = 0x006000
PC = 0x003000
X = 0x000090
b = 0 p = 1 address/disp = 0x300 TA = 3000 +600
b = 1 p = 0 address/disp = 0x300 TA = 6000+ 300 +90
b = 0 p = 1 address/disp = 0x30 TA = 3000 + 30
B = 0 p = 0 address/disp 0x30 TA = 30
b = 0 p = 1 address/disp 0110 0000 0000
n i = 0 是SIC
TA = 011 0 1 1 0110 0000 0000
b = 0 p = 0 n i = 1 0xC303 TA = C303
考試考Value load 看怎麼用:

n i = 1 到3600 存資料 = 103000
n i = 1 到6390 = 00C303
n = 1 i = 0 Target 3030 看到 003600這個Address
所以到003600拿真正的值回來
n = 0 i = 1 後面的30 immediate就直接是30
n i = 0 Target = 3600 103000
n i = 1 Target = C303 C303
```
n, i:決定資料怎麼用
0 0: SIC(op後面bit都是0)加上前面的BIT是ㄨ
1 1: Simple 裡面的值直接用 ex:ADD THREE ADD 3
##0 0 1 1只差在00是SIC的指令
0 1: Immediate 直接將後面的disp視為value,所以沒有存取任何memory ex: ADD #3
->存放的值是 Value
1 0: Indirect 指標的概念,它裡面的值是一個Memory的Address ex: J @THREE
->存放的值是 Address
```
## **CH2 Assembler Design**
One-Pass Assembler:會產生forward reference
**Two-Pass Assembler**:
讓Pass1做SYMTAB,把FIRST THREE FIVE RESULT那些有LABLE的MEMORY ADDRESS先算出來
Pass2:tranfer to mechine code

### Data Structure
pass1:create symbol table
有Op code 和direct假指令
```
first ifelse
var startingaddr = 0x1000
var LOCCTR = Startingaddr
second ifelse
把重複的SYMBOL用掉
然後把每一個指令的address+3包含假指令
只要找的到的都可以加
如果是RESW就要看他有幾個word
以此類推
若不是假指令或OPCODE就是寫錯了
最後將LOCCTR-starting address = program length
存在H record
```
pass2:
```
找symtab若寫錯了要告訴你寫錯了
如果沒事就直接轉
如果遇到RESW or RESB不用做任何事
word and byte需要有地方存
如果超過60bits就把新的一行寫入T record
```
## Run Assembler
python 3 assembler.py addexample.asm
Assembler
(1)OPCode -> Machine Code
(2)Opreand(Memory Address)
(3)Genereate Object Code
Object Codse (Test)
H /T/E Record
Python List[ ]
Python Diectory
Two Pass Assembleer
Pass1:把lable的記憶體位置算出來,並建立SYMTAB
//只要有label就會產生address
Pass2:將組與轉成機器碼並產生Object File
```
#pass1
for line in lines:
t = sicasmparser.decompositLine(line)
if t == None:
continue
if t[1] == "START":
STARTING = int(t[2],16)
LOCCTR = STARTING
if t[1] == "END":
proglen = LOCCTR - STARTING
break
if t[0] != "None" // has label
if t[0] in SYMTAB:
print("Your assembly code has problem.")
continue
SYMTAB[t[0]] = LOCCTR
if sic.isInstruction(t[1]) == True:
LOCCTR = LOCCTR + 3
elif t[1] == "WORD":
LOCCTR = LOCCTR + 3
elif t[1] == "RESW":
LOCCTR = LOCCTR + (int(t[2])*3) //string to integer and multiple 3
elif t[1] == "RESB":
LOCCTR = LOCCTR + int(t[2])
elif t[1] == "BYTE":
if t[2][0] == 'C':
LOCCTR = LOCCTR + (len(t[2])) - 3
if t[2][0] == 'X':
LOCCTR = LOCCTR + ((len(t[2] -3)/2)
print(SYMTAB)
```
```
```