Z-80으로 간단한 컴퓨터 만들기 6
5.2. Assembly 언어
이제 프로그램을 작성하여 프로그램을 메모리에 써넣고, 시험을 수행하여야 한다. 프로그램을 작성하기 위해 먼저 Z80내부 레지스터들과 Assembly 언어에 대해 간략히 살펴본다. Z80 내부 레지스터는 그림 18에 나타내었다.
그림 18 Z80 내부 레지스터
내부 레지스터 중에 A는 Accumulator로 사용되는 레지스터로 CPU가 연산을 수행 했을 때 주로 그 결과는 A에 저장되게 되고, F는 Flag 레지스터로 연산의 결과에 대한 상태를 나타낸다, 여기서 상태라는 것은 연산 결과가 0인지를 나타내는 Zero Flag, 결과가 +인지 –인지를 나타내는 Sign Flag등이 있어서 연산의 결과에 따라 프로그램을 수행할 때 확인할 수 있는 레지스터이다. B, C, D, E, H, L 레지스터는 일반적으로 임시로 데이터를 저장하기 위해 쓰이는 레지스터이다. 그리고 16비트로 구성된 레지스터가 4개 있는데 그중에 IX, IY는 주소를 참조할 때 주로 쓰이는 레지스터이고, SP는 Stack을 지정할 때 쓰는 레지스터, PC는 현재 프로그램이 수행되고 있는 현재의 어드레스를 저장하고 있는 레지스터이다. 여기서 Stack은 프로그램 수행시 sub routine을 호출할 때 현재의 PC와 주요 레지스터들을 저장하고 다시 원래의 프로그램으로 돌아갈 때 원래의 레지스터 값을 복원하기 위해 사용되는 레지스터로 sub routine이 호출되면 PC는 자동으로 Stack에 저장되고, 이 외 사용자가 저장을 한 레지스터를 Stack에 저장한다. 그리고 Sub routine이 모두 수행되고 나면 사용자는 Stack에 저장된 레지스터를 복원하고, 원래의 프로그램으로 복귀하여야 한다. 원래의 프로그램으로 복귀할 때 CPU는 Stack에 저장된 PC가 지정하는 주소로 돌아간다. Assembly 언어는 이 레지스터들과 메모리를 관리하면서 프로그램의 구성하여야 한다.
Assembly 언어는 OP Code와 Operand로 구성된다. OP Code는 CPU의 동작을 지정하는 명령어이고 Operand는 이 동작의 대상이 되는 레지스터, 메모리, 데이터를 의미한다. OP Code는 1~2 byte로 구성되고, Operand도 1~2byte로 구성된다. 때로는 Operand 없이 OP Code 만 있을 수도 있다. OP Code의 종류는 데이터를 가져오고 저장하는 LOAD Group, 수치 연산이나 논리 연산을 수행하는 연산 그룹, Jump, Call, Return등의 프로그램 제어를 수행하는 그룹 등으로 구성된다. 여기서는 별도의 컴파일러를 사용하지 않기 때문에 Assembly로 프로그램을 작성한 뒤 그에 해당하는 Machine Language를 찾아서 메모리에 입력하여야 하기 때문에 Z80 데이터 시트에 나와 있는 명령어 일람표를 보고 Machine Language로 변환 하는 과정을 살펴본다. 그림 19에 Z80 명령어 중에서 8-Bit Load그룹이라는 것을 나타내었다.
그림 19 Z80 명령어 예
위 그림의 첫줄에 LD r, r’라는 Assembly 명령어에 대해 살펴보면, r <- r’라고 Symbolic Operation에 설명되어 있는데 이것은 레지스터 r’의 데이터를 레지스터 r에 Load 한다는 것을 도식적으로 표시한 것이다. r은 우측에 있는 comment에 나타낸 것처럼 Z80 내부 레지스터를 의미한다. 그래서 Assembly 언어로 프로그램을 작성할 때 LD A, B라고 쓰면 레지스터 B의 데이터를 레지스터 A로 옮기라는 의미가 되며, 이것을 OP Code로 변환하면, b’01111000(=h’78)이 된다. 이 명령어는 Operand가 필요하지 않기 때문에 이 1 바이트로 프로그램이 작성된다.
두 번째 줄에 있는 LD r,n은 레지스터 r에 사용자가 입력한 데이터 n을 LOAD 하라는 의미이며, 이것을 Assembly 언어로 표기하면 LD B, #12라고 표기하는데, #은 직접데이터를 의미한다. 이 것을 OP Code로 변환하면, b’00000110(=h’06) b’00010010(=h’12)로 된다. 직접 데이터를 입력하기 위한 Operand가 필요하여 2바이트로 프로그램이 구성된다는 의미이다. Z80 데이터 시트에는 그냥 n이라고 쓰여 있는데, #을 추가한 것은 앞에서 언급한 것처럼 직접데이터 임을 나타낸다. 이런 표시를 하는 것은 Operand가 레지스터 인지 인덱스 인지, 어드레스 인지 등을 구분하기 위한 것이다. Operand에 ()가 쳐져 있으면 괄호 안에 있는 어드레스에 있는 데이터를 의미하는 것이고, #이라고 되어 있으면 #뒤에 있는 것이 데이터라는 것을 의미한다. 또한 앞의 그림에서 Flag라고 표시되어 있는 부분이 있는데 이것은 이 명령어에 의해 변환되는 Flag를 의미한다. 이 그림에서는 모두 “·” 표시되어 있는데 이것은 이 명령어 수행 뒤에 Flag에 영향을 미치지 않는다는 의미이고, 명령어 세트 표를 보다보면 “↕” 표시가 있는 Flag가 있는데 이것은 해당 Flag가 명령어를 수행한 뒤 영향을 받는 다는 것을 의미한다. 그리고 위 그림의 표에서 No of T State라고 표시된 부분이 있는데 이것은 이 명령어를 수행하는 데 몇 clock 이 소요되는지를 나나타는 것이다. 즉 앞에서 살펴본 LD A, B는 4라고 써 있는데, 이는 4클럭이 소요된다는 것이다. 우리가 CPU 클럭을 2MHz를 사용하였다고 했을 때 한 클럭의 시간은 1/2000000이므로 한 클럭이 0.5usec이고 이 명령을 수행하는데 2usec가 걸린다는 것을 의미한다.
이제 실제로 프로그램을 작성하여 실행 시켜 보면서 그때그때 부가 설명을 하기로 한다.
5.3. 입출력 시험
입출력 시험은 데이터 스위치로 입력된 데이터를 Latch로 출력하여 LED를 On/Off 하는 프로그램을 작성하여 입출력 시험을 수행한다. Z80 명령어에는 입력 장치로부터 직접 데이터를 가져오는 입력 명령어, 출력장치로 데이터를 직접 출력하는 명령어가 구비되어 있으며 이때 입출력장치를 지정하는 것은 Address pin 8개를 이용하여 수행한다. 그러므로 입출력장치를 256개까지 사용할 수 있다. 여기서는 입출력장치가 각각 1개 밖에 없기 때문에 Address는 신경쓰지 않아도 된다. Assembly 언어로 작성한 프로그램을 다음과 같다.
LOOP IN A, (0) : 0번 입력장치에서 데이터를 가져와 reg A에 넣는다.
OUT (0), A : reg A의 데이터를 0번 출력장치로 출력한다.
JP LOOP : LOOP 로 Jump. 무한 루프 수행
위 프로그램을 Machine Language로 변환하면 다음과 같다.
LOOP IN A, (0) 0000 DB 00
OUT (0), A 0002 D3 00
JP LOOP 0004 C3 00 00
0007
중간에 있는 4자리 숫자는 메모리에 써 넣는 Address를 의미한다. 첫 번째 줄은 명령어가 2바이트를 사용하기 때문에 두 번째 줄의 Address가 0002가 된다. 이제 이 프로그램을 입력하는 절차와 시험하는 절차를 설명하면 다음과 같다.
① 보드에 전원을 인가하여 전원 LED가 점등되는지 확인한다.
② BUSRQ SW(SW2)를 ON 한다.
③ 어드레스 스위치를 0으로 한다. 즉 모두 On 한다. LED 상태를 확인한다.
④ 데이터 스위치를 b’11011011(=h'DB)로 한다. 즉 비트 5와 비트 2를 on하고 나머지는 off 한다. 보드를 제작할 때 스위치를 위로 올리면 off, 아래로 내리면 on이 되도록 조립하면, 위로 올렸을 때 1, 아래로 내렸을 때 0이 되도록 하여 숫자를 읽기 편하게 된다. 그리고 나서 write 스위치를 눌러 준다. - 이때 LED가 스위치의 값과 같아지는지 확인한다.
⑤ 어드레스 스위치를 h’0001로 한다.
⑥ 데이터 스위치를 h’00으로 하고 쓰기 스위치를 눌러 메모리 출력이 h’00이 되는지 확인한다.
⑦ 어드레스 스위치를 h’0006이 될 때까지 순차적으로 위의 Machine Language로 작성된 프로그램을 입력한다.
⑧ 입력이 완료되면 어드레스 스위치를 다시 h’0000부터 h’0006까지 바꾸어 주면서 프로그램이 정상적으로 입력되었는지 확인한다.
⑨ BUSRQ SW(SW2)를 off 하고 데이터 스위치를 on, off 하면서 데이터 스위치의 상태가 LED로 바로바로 출력되는지 확인한다. - 잘 안되면 Z80의 PC가 0으로 안되어 있는 경우가 있으므로 reset 스위치를 한번 눌러준다. 그러면 잘 될 것이다.
댓글
댓글 쓰기