Ajou Univ. System Programming (SCE214) - SIC/XE Machine Practice
- Notion 정리글 >
- 교재 코드
- 기본 구조
- 기본콘솔 입출력
- 스택
- 2차원 배열
- ...
-
설치, 사용설명: http://jurem.github.io/SicTools/
-
환경: vmware 우분투 20.04 / WSL2 (win11이라면 wlsg로 사용 가능!)
-
리눅스 기준 세팅:
- git 설치하기
**sudo apt-get install git**
- vim 설치하기
**sudo apt-get install vim**
- java 설치하기
**sudo apt-get install openjdk-8-jdk**
- git 설치하기
-
sictool시뮬 실행:
**java -jar out/make/sictools.jar**
- START : 프로그램 이름, 시작주소
- END : 원시프로그램(source program)의 끝, 선택적으로 최초 실행할 명령어
- BYTE : 상수생성, 문자 or 16진수
- WORD : 1워드 정수 상수 생성 ⇒ 값 할당 되어있다
- RESB : 지시된 바이트 수 만큼 예약 ⇒ 값이 비어있다 0
- RESW : 지시된 워드 수 만큼 예약
-
SIC는
ALPHA RESW 1
-> 1byte 할당해서 ALPHA 변수 생성하는 식으로 상수 저장 -
SIC/XE는 #(immediate mode)를 붙이면 바로 값을 상수로 사용가능. 따라서 굳이 값을 변수에 저장할 필요 X (메모리를 거치지 않으므로 속도 증가)
-
ex1.asm
LDA FIVE .LOAD CONSTANT 5 INTO REGISTER A STA ALPHA .STORE IN ALPHA LDCH CHARZ .LOAD CHARACTER 'Z' INTO REGISTER A STCH C1 .STORE IN CHARACTER VARIABLE C1 ALPHA RESW 1 .ONE-WORD VARIABLE FIVE WORD 5 .ONE-WORD CONSTANT CHARZ BYTE C'Z' .ONE-BYTE CONSTANT C1 RESB 1 .ONE-BYTE VARIABLE
-
A : load 5 ⇒ store 5 ⇒ load ‘Z’ ⇒ store ‘Z’
ALPHA : 1 → 5 store
FIVE : 5 → 5 load
CHARZ : ‘Z’ → ‘Z’ load
C1 : 1 → ‘Z’ store
-
-
ex2.asm
LDA #5 .LOAD IMMEDIATE VALUE 5 INTO REGISTER A STA ALPHA .STORE IN ALPHA LDCH #90 .LOAD ASCII CODE FOR 'Z' INTO REGISTER A STCH C1 .STORE IN CHARACTER VARIABLE C1 ALPHA RESW 1 .ONE-WORD VARIABLE C1 RESB 1 .ONE-BYTE VARIABLE
- 5, ‘Z’를 변수에 넣지 않고 바로 이용 ⇒ # : 직접
-
ex3.asm
LDA ALPHA ADD INCR SUB ONE STA BETA LDA GAMMA ADD INCR SUB ONE STA DELTA ONE WORD 1 ALPHA WORD 7 .WORD: 값을 할당해서 들어있다 7 BETA RESW 1 .RESW: 초기화만, 값이 비어있다 0 GAMMA WORD 3 DELTA RESW 1 INCR RESW 1
int one = 1 int alpha = 7 int beta = 0 int gamma = 3 int delta = 0 int incr = 0 beta = 7+0-1 = 6 gamma = 3+0-1 = 2
-
ex4.asm
LDS INCR .S에 load하기, 계속 씀 LDA ALPHA ADDR S, A .A = S + A SUB #1 .# 직접 STA BETA LDA GAMMA ADDR S, A SUB #4 .4를 뺀다 STA DELTA ONE WORD 1 ALPHA WORD 7 BETA RESW 1 GAMMA WORD 3 DELTA RESW 1 INCR WORD 4 .INCR에 4로 초기화하기
-
#A : Immediate addressing, n=0, i=1
-
@A : Indirected addressing, n=1, i=0 ⇒ A에 저장된 값을 주소로 가지는 곳! A는 포인터, 가리키는 곳에 값을 저장 A에 저장이 아님
-
C언어 어셈블러 비교
int var = 10; int *addr = &var; *addr = 20;
LDA #10 STA VAR LDA #VAR STA ADDR LDA #20 STA @ADDR VAR RESW 1 ADDR RESW 1
-
반복문
SIC에선 TIX ELEVEN -> X값을 1 증가시키고 ELEVEN 변수의 값과 비교해서 결과를 SW 레지스터에 저장
SIC/XE에선 T레지스터를 이용해서 반복(레지스터 개수의 증가)
SIC에선 string을 저장하고자 할 때 변수 2개 필요
-
COMP, TIX
-
X 레지스터
-
J
LDX ZERO
MOVECH LDCH STR1, X
STCH STR2, X
TIX ELEVEN
JLT MOVECH
JEQ EQUAL
EQUAL TIX ELEVEN
JGT FIN
FIN TIX ELEVEN
STR1 BYTE C'TEST STRING'
STR2 RESB 11
ZERO WORD 0
ELEVEN WORD 11
- stdin(0) , stdout(1) 장치 연결. ⇒ 입력, 출력 가능
- input, output 한번에 1byte씩만 전송. ⇒ 여러 바이트는 반복으로 처리해야함.
- A 레지스터 마지막 1btye 사용.
- 2^8개 디바이스 지원
- TD INDEV < : 준비, = :준비x
- RD INDEV
- WD INDEV
- 콘솔에 A입력
INLOOP TD INDEV .TEST 입력장치
JEQ INLOOP .LOOP 장치 준비될 때 까지
RD INDEV .READ 입력장치에서 A 레지스터로 1 바이트
STCH DATA .STORE 읽은 거 바이트
OUTLP TD OUTDEV .TEST 출력장치
JEQ OUTLP .LOOP 장치 준비될 때 까지
LDCH DATA .LOAD A 레지스터로
WD OUTDEV .WRITE 출력장치로 1 바이트
INDEV BYTE 0 .INPUT DEVICE NUMBER
OUTDEV BYTE 1 .OUTPUT DEVICE NUMBER
DATA RESB 1 .ONE-BYTE VARIABLE
- JSUB ALPHA
- L 레지스터에 현재 pc값을 저장
- RSUB
- JEQ랑 비슷, 기능은 거의 같은데 하나의 루틴으로 의미있음. 무한루프 가능
JSUB READ .CALL READ SUBROUTINE
.SUBROUTINE 100바이트 RECORD 읽기
READ LDX ZERO .INITIALIZE INDEX REGISTER을 0으로
RLOOP TD INDEV .TEST 입력장치
JEQ RLOOP .LOOP IF DEVICE IS BUSY
RD INDEV .READ A 레지스터로 1바이트
STCH RECORD, X .STORE RECORD로
TIX K100 .ADD 1 TO INDEX REGISTER AND COMPARE NEW VALUE TO 100
JLT RLOOP .LOOP INDEX VALUE가 100보다 작으면
RSUB
INDEV BYTE 0 .INPUT DEVICE NUMBER
RECORD RESB 100 .100BYTE BUFFER FOR INPUT RECORD
ZERO WORD 0
K100 WORD 100
JSUB READ .CALL READ SUBROUTINE
.SUBROUTINE 100바이트 RECORD 읽기
READ LDX #0 .INITIALIZE INDEX REGISTER을 0으로
LDT #100 .INITIALIZE T 레지스터 100으로
RLOOP TD INDEV .TEST 입력장치
JEQ RLOOP .LOOP IF DEVICE IS BUSY
RD INDEV .READ A 레지스터로 1바이트
STCH RECORD, X .STORE RECORD로
TIXR T .ADD 1 TO INDEX REGISTER AND COMPARE NEW VALUE TO 100
JLT RLOOP .LOOP INDEX VALUE가 100보다 작으면
RSUB
INDEV BYTE 0 .INPUT DEVICE NUMBER
RECORD RESB 100 .100BYTE BUFFER FOR INPUT RECORD
- JSUB 현재 지점 저장해놓고 바로 이동!
- @TOP 은 포인터!
- PUSH, POP은 TOP을 +3 -3 주소값을 바꿔준다.
MAIN START 1000
FIRST JSUB STKINIT
LDA #1 .PUSH START
STA @TOP .TOP이 가리키는 곳에 저장, TOP에 저장이 아님
JSUB PUSH
LDA #2
STA @TOP
JSUB PUSH
LDA #3
STA @TOP
JSUB PUSH
JSUB POP .POP START
LDA @TOP .포인터 값으로 넣는다
STA OUT1
JSUB POP
LDA @TOP
STA OUT2
JSUB POP
LDA @TOP
STA OUT3
A J A .여기서 멈춤
STKINIT LDA #STACK .STACK INIT #STACK이 주소를 가져오는거?
STA TOP
RSUB
PUSH LDA TOP
ADD #3
STA TOP
RSUB
POP LDA TOP
SUB #3
STA TOP
RSUB
OUT1 RESW 1
OUT2 RESW 1
OUT3 RESW 1
TOP RESW 1
STACK RESW 10000
- 1차원으로 2차원 표현하기
- arr[2][1] = arr + 2 * (sizeof element * sizeof Cols) + 1 * (sizeof element)
- 1개 크기 3word
- ex)
- 피보나치 구현하기
- +jsub 다른곳에서 가져온다.
# assembler 실행하기 -> obj파일 만들기
java -cp out/make/sictools.jar **sic.Asm** tests/linker/stack/main.asm
java -cp out/make/sictools.jar **sic.Asm** tests/linker/stack/stack.asm
# linker 실행하기
java -cp out/make/sictools.jar **sic.Link** -o **out.obj** tests/linker/stack/main.obj tests/linker/stack/stack.obj
- main.asm
main START 0
EXTREF stinit
EXTREF push
EXTREF pop
.init the stack at #256
LDA #256
+JSUB stinit
.push 0x11 0x22 0x33 0x44 to stack
LDA #17
+JSUB push
LDA #34
+JSUB push
LDA #51
+JSUB push
LDA #68
+JSUB push
.pop them back and store them to memory again
+JSUB pop
STA res1
+JSUB pop
STA res2
+JSUB pop
STA res3
+JSUB pop
STA res4
halt J halt
res1 WORD 170
res2 WORD 170
res3 WORD 170
res4 WORD 170
- stack.asm
stack START 0
EXTDEF stinit
EXTDEF push
EXTDEF pop
. starts the stack at the address in A
stinit STA stackptr
RSUB
. pushes the content from A to stack
push STA @stackptr
LDA stackptr
ADD #3
STA stackptr
RSUB
.pops the top element to A
pop LDA stackptr
SUB #3
STA stackptr
LDA @stackptr
RSUB
stackptr RESW 1
END stack
- main.obj
- 링크하기전에 문자열로 되어있다. +JSUB라서 주소를 몰?루
Hmain 0000000000**4E** Rpop push stinit T0000001D0101004B1000000100114B1000000100224B1000000100334B10000001 T00001D020044 T00001F1D4B1000004B1000000F20184B1000000F20144B1000000F20104B100000 T00003C120F200C3F2FFD0000AA0000AA0000AA0000AA **M00000405+stinit M00000B05+push M00001205+push M00001905+push M00002005+push M00002405+pop M00002B05+pop M00003205+pop M00003905+pop** E000000
- stack.obj
Hstack 000000000027 Dpop 000015push 000006stinit000000 T0000001D0F20214F00000E201B0320181900030F20124F000003200C1D00030F20 T00001D0106 T00001E060220034F0000 E000000
- out.obj
- 이제 없어졌다.
Hout 000000000075 T0000001D0101004B1000'4E'0100114B1000'54'0100224B1000'54'0100334B1000'54'01 T00001D020044 T00001F1D4B1000544B1000'63'0F20184B1000'63'0F20144B1000'63'0F20104B1000'63' T00003C120F200C3F2FFD0000AA0000AA0000AA0000AA T0000'4E'1D0F20214F00000E201B0320181900030F20124F000003200C1D00030F20 T00006B0106 T0000'6C'060220034F0000 M00000405 M00000B05 M00001205 M00001905 M00002005 M00002405 M00002B05 M00003205 M00003905 E000000