1. 50H - 40H
문제 : 2052H 주소에 data 50H가, 2051H 주소에 data 40H이 저장되어 있다.
50H - 40H의 값을 2053H 주소에 저장해라.
-> 뺄셈은 무조건 A(accumulator)에서 실행 가능하다.
-> 40H를 먼저 A로 가져와 B로 옮겨두고, 50H를 A로 가져온다. 그런 후 A에서 B를 빼면 결과가 나온다.
LDA 2052H
MOV B, A
LDA 2051H
SUB B
STA 2053H
만약 이 코드를 읽고, address bus를 채워 넣으라 하면 다음과 같다.
2. 옛날 호텔 제어 system
-> IN 00H : input 포트로부터 00H를 받아서 무조건 A에 저장하라는 명령어.
-> 그걸 그대로 output 포트로 내보내면 된다.
IN 00H
OUT 00H
JMP 2000H
만약 이 코드를 읽고, address bus를 채워 넣으라 하면 다음과 같다.
<JMP 명령어>
JMP xxxxH : 아무 조건 없이 xxxxH로 jump해서 xxxxH의 명령어를 수행하는 명령어다.
타이밍도는 아래와 같다.
-> 3개의 machine cycle이 끝나면, 다음으로는 2000H의 명령어 cycle이 그려진다.
<조건부 JMP 명령어>
1) R(라디오)가 무조건 켜짐을 유지하게 하려면, 다음과 같이 (OR)을 사용하면 된다.
2) A(에어컨)이 무조건 꺼짐을 유지하게 하려면, 다음과 같이 (AND)를 사용하면 된다.
JP, JM : 각각 양수, 음수일 때만 xxxxH로 점프
JZ, JNZ : 각각 0일 때만, 0이 아닐 때만 xxxxH로 점프
JPE, JPO : 패리티가 각각 짝수, 홀수일 때만 xxxxH로 점프
JC, JNC : carry가 있을 때만, 없을 때만 xxxxH로 점프
타이밍도는 아래와 같다.
-> 조건이 맞으면 <JMP xxxxH>와 타이밍도가 같다. 10개의 T cycle을 가진다.
-> 조건이 맞지 않다면 7개의 T cycle을 가진다.
-> 조건이 맞지 않을 경우, 다음 PC 값으로 넘어가야 한다.
(ex) 2000H에서 조건부 jump 수행, 맞지 않음 -> 2001H로 넘어감
(ex) 20FFH에서 조건부 jump 수행, 맞지 않음 -> 2100H로 넘어감
-> 이와 같이 운 나쁘면 3개의 CLK가 사용될 수 있으므로 PC만 증가시키는 M2 cycle을 둔다.
3. 2개 data의 합이 FF 이하일 때만 합을 출력, 초과하면 0 출력하는 system
1. 크냐 작냐를 비교한다. -> JC, JNC를 둘 다 사용하며 비교해보자.
2. 클 때의 경우를 실행한다.
3. 작을 때의 경우를 실행한다.
// JC를 사용하여 코드 구현
IN 04H
MOV B, A
IN 05H
ADD B
JC *
** OUT 01H
HLT
* MVI A, 00H
JMP **
//JNC를 사용하여 코드 구현
IN 04H
MOV B, A
IN 05H
ADD B
JNC *
MOV A, 00H
* OUT 01H
HLT
-> 두번째 상황이 더 simple함을 알 수 있다.
-> 참고로 HLT : 종료 구문이다.
4. delay routine [신호등 깜빡임]
B에 data FFH를 집어 넣어 00H가 될 때까지 반복하는 시스템을 만들어보자.
코드는 아래와 같다.
MVI B, FFH
* DCR B
JMZ *
-> B의 값이 FFH, FEH ,FDH ... 00H로 반복되며 감소하는 것을 알 수 있다.
-> B의 값이 00H가 되면, JMZ의 조건을 만족하지 못하므로 jump구문이 실행되지 않는다.
5. 보행자 신호등
<첫번째 시도 : no delay>
* MVI A, 01H
OUT 00H
MVI A, 02H
OUT 00H
JMP *
-> 너무 빨라서 빨강, 초록이 동시에 켜진다.
<두번째 시도 : contain delay>
MVI C, xxH
* DCR C
JMZ * // 1씩 감소를 반복하는 반복문 코드
-> 이 코드를 활용하여 보행자 신호등 프로그램을 구현해보자.
<세번째 시도 : 01H를 5초, 02H를 3초로 지정>
// main 함수
* MVI A, 01H
OUT 00H
MVI B, 05H
CALL sub
MVI A, 02H
OUT 00H
MVI B, 03H
CALL sub
JMP *
// subroutine <sub>
** MVI C, xxH
* DCR C
JNZ *
DCR B
JNZ **
RET
<네번째 시도: 좀 더 보완>
// main 함수
* MVI A, 01H
OUT 00H
MVI B, 05H
CALL sub
MVI A, 02H
OUT 00H
MVI B, 03H
CALL sub
JMP *
// subroutine <sub>
PUSH PSW
PUSH B
** MVI C, xxH
* DCR C
JNZ *
DCR B
JNZ **
POP B
POP PSW
RET
-> Subroutine documentation
서브루틴의 특징, 필요한 것들을 저장해 둘 때 관리가 편한 '문서화'
(1) function, 기능 : 1초 delay
(2) Used reg(사용하거나 값이 바뀌는 reg) : F, B, C
(3) IN/OUT parameter : IN은 B, OUT은 없다.
(4) other subroutine : 없다.
-> Nesting 기법
subroutine이 또다른 subroutine을 호출한다.
한 번 call할 때마다 Stack이 2byte씩 쓰인다. -> main까지 침범하게 됨
따라서 Stack이 있는 만큼만 CALL이 가능하다는 제한이 따른다.
'KNU_study > 마이크로프로세서' 카테고리의 다른 글
마이크로프로세서 암기노트(중간고사) (0) | 2023.04.21 |
---|---|
마이크로프로세서(17) Stack과 Subroutine (0) | 2023.04.21 |
마이크로프로세서(15) I/O interface (1) | 2023.04.21 |
마이크로프로세서(14) 타이밍도 (1) | 2023.04.21 |
마이크로프로세서(13) 어셈블러 명령어2 (0) | 2023.04.21 |