LAB‎ > ‎

Lab 10

10. Local Array

1) 아래 프로그램을 역 번역하여 고급언어로 표현하시오. (아래 HINT 1 참조)
2) 아래 프로그램을 RUNTIME으로 시작해서 MAIN 함수를 호출하고 MAIN에서 메세지를 출력하는 함수(F_OUT_MSG)를 호출하는 구조로 바꾸시오. 이 때 프로그램에서 나오는 배열 중 MSG를 MAIN 함수 안에서 선언된 지역변수로 바꾸시오. MAIN 함수가 호출되면 상수 "20181015"에서 값을 읽어서 해당 지역변수 배열을 초기화 한다. 지역변수이므로 Base Register Addressing(%)을 사용한다.(아래 HINT 2 참조)
3) V08에서는 함수를 호출하려면 여러 명령어를 조합하여 리턴주소를 스택에 넣거나 꺼내거나 해야 한다. 아래와 동일하게 동작하는 CALL, RTN 명령어의 Flow를 Register Register Transfer Form 으로 표혀하시오.

SETRTNNEAR RTN0// CALL MAIN
PUSHR
JMPMAIN
RTN0

POPR// RETURN
JMP*R

// 7 segments IO, V08
SEG_IOSTART200
MMIO_BASEEQU0// not real location, for TEST
MMIO_SEG_DATAEQUMMIO_BASE+10// IO Address for 7 segments
MMIO_SEG_STATEEQUMMIO_BASE+11
MMIO_SEG_CMDEQUMMIO_BASE+12
LDA #1
STA MMIO_SEG_STATE// allways ready, for TEST
LDA SEG_ON_ALL// Turn on 7 segments device
STA MMIO_SEG_CMD
LDA ="0"
MOVD2 A
LDA ="9"
MOVD3 A
LDA #0
MOVX A// i=0
DO_WHILE
LD A MSG_LENGTH
CMPX A// i < MSG_LENGTH
SKN
JMPEND_WHILE
// IF
LDA @MSG// A <- *MSG (or MSG[i])
MOVD0 A
CMPD0 D2// Char >= BASE
SKZP
JMPELSE
CMPD0 D3// Char <= END
SKZN
JMPELSE
// THEN
MOVA D2
NEGA
ADDA D0// A <- Char-BASE
MOVD1 A
LDA P_SEG_CONV
ADDD1 A// D1 <- &SEG_CONV+(Char-BASE)
MOVD0 *D1// D0 <- SEG_CONV[Char-BASE]
JMPEND_IF
ELSE
LDA =0b01000000// 하이픈 '-'
MOVD0 A
END_IF
MOVA D0
LDA MASK_READY
MOVC A
LOOP_READYLDA MMIO_SEG_STATE
ANDA C
SKNE
JMPLOOP_READY// wait until ready
MOVA D0
STA MMIO_SEG_DATA
LDA SEG_WRITE
ADDA X
STA MMIO_SEG_CMD
INCX
JMPDO_WHILE
END_WHILE
COB
P_SEG_CONVBOXSEG_CONV
SEG_CONVBOX0b00111111//0
BOX0b00000110//1
BOX0b01011011//2
BOX0b01001111//3
BOX0b01100110//4
BOX0b01101101//5
BOX0b01111101//6
BOX0b00000111//7
BOX0b01111111//8
BOX0b01101111//9
MSGBOX"20181015"
MSG_LENGTHBOX$-MSG
// Command for 7 segments
SEG_WRITEBOX0100
SEG_ONBOX0200
SEG_OFFBOX0300
SEG_ON_ALLBOX0992
SEG_OFF_ALLBOX0993
MASK_READYBOX001// Mask bits 
LTORG
END

HINT 1: 전역 변수 배열 msg[];

#define MMIO_BASE      100                    // 당분간은 0으로 한다.

#define MMIO_SEG_DATA  MMIO_BASE+10

#define MMIO_SEG_STATE MMIO_BASE+11

#define MMIO_SEG_CMD    MMIO_BASE+12


// Conversion Table to 7 Segments from numbers

unsigned int * p_seg_conv = seg_conv;

unsigned int seg_conv[10] = {0b00111111, 

                                              0b00000110,

                                              0b01011011,

                                              0b01001111,

                                              0b01100110,

                                              0b01101101,

                                              0b01111101,

                                              0b00000111,

                                              0b01111111,

                                              0b01101111 };


// Commands for 7 Segments

unsigned int SEG_WRITE=0100;

unsigned int SEG_ON=0200;

unsigned int SEG_OFF=0300;

unsigned int SEG_ON_ALL=0992;

unsigned int SEG_ON_OFF=0993;


unsigned int MASK_READY=0001;


char msg[8]=“20181015”;   // 실제 c/c++과는 달리 끝에 null character(’\0’)를 넣지 않고 8개 문자만 넣는다.

                                           // 초기값을 가진 전역 변수이므로 초기화된 상태로 미리 배치된다.

 

main() {

     …

     asm(LD A SEG_ON_ALL; ST A MMIO_SEG_CMD); // Turn all 7 segments

     …

     while ( …) {

          …

          if ( … ) {

               …

          }

          else {

               …

          }


     // 7 segment로 출력


     }

}


HINT2: 지역 변수 배열 msg[]

// Runtime System

SEG_IOSTART200
RUNTIMELDA BOTTOM// SP <-- BOTTOM
MOVSP A
LDA #0// LD B #0
MOVB A
DECSP // room for return value of MAIN
SETRTNNEAR RTN0// CALL MAIN
PUSHR
JMPMAIN
RTN0
COB
BOTTOMBOX600


#define MMIO_BASE      100                    // 당분간은 0으로 한다.

#define MMIO_SEG_DATA  MMIO_BASE+10

#define MMIO_SEG_STATE MMIO_BASE+11

#define MMIO_SEG_CMD    MMIO_BASE+12


// Conversion Table to 7 Segments from numbers

unsigned int * p_seg_conv = seg_conv;

unsigned int seg_conv[10] = {0b00111111, 

                                              0b00000110,

                                              0b01011011,

                                              0b01001111,

                                              0b01100110,

                                              0b01101101,

                                              0b01111101,

                                              0b00000111,

                                              0b01111111,

                                              0b01101111 };


// Commands for 7 Segments

unsigned int SEG_WRITE=0100;

unsigned int SEG_ON=0200;

unsigned int SEG_OFF=0300;

unsigned int SEG_ON_ALL=0992;

unsigned int SEG_ON_OFF=0993;


unsigned int MASK_READY=0001;


main() {

char msg[8]=“20181015”;     // msg[]는 지역 변수이므로  Activation Record에 자리를 잡아야 하고

                                            // 8개 값을 하나씩 차례로 써주어서 초기화 한다.

                                            // 이 때 초기값(“20181015”)은 상수로서 전역 변수처럼 미리 배치 되어있다.


     asm(A=out_msg(8,msg); OUT);

}


out_msg(int length, char msg[]) {

     …

     asm(LD A SEG_ON_ALL; ST A MMIO_SEG_CMD); // Turn all 7 segments

     …

     while ( …) {

          …

          if ( … ) {

               …

          }

          else {

               …

          }


     // 7 segment로 출력


     }

     return cnt;  // 출력된 수를 리턴

}


Comments