Lab & Homeworks‎ > ‎

Lab & Homeworks 2017

1. [HW1] Sum(1..n) 프로그램 및 기본 명령어 완성
  1. n 값을 입력 받아 1 부터 n 까지의 합을 구해 출력하는 프로그램을 LMC 10개의 명령어를 이용하여 작성하고 실행하시오.
  2. lmc.c의 LittleMan() 의 기본 명령어 중 빠진 명령어 2,4,9 를 구현해 넣고 컴파일한 후 Sum 프로그램을 다시 실행시키시오.
    • 참고할 페이지: 모듈 --> CPU --> LittleMan    Click here!
    • 컴파일하는 방법: make
<< 리포트 내용 >>
  1. LMC 기계어로 작성된 프로그램에 니모닉 및 주석을 단 프로그램 (예:  299   STA 99  // A 값을 99번지에 저장, 99번지는 int n;를 뜻함)
  2. 해당 프로그램을 LMC 머신에서 실행시키는 과정을 설명 (프로그램을 메일박스로 옮기는(Loading) 과정. 예: Tape booting ...)
  3. 생각해보기(리포트에 포함)
  • 상수 1과 변수 n을 메일 박스의 어디에 배치할 것인가?
<<제출 방법>>
  • 사이버캠퍼스(http://ecampus.kookmin.ac.kr)에 온라인으로 제출하고 마감일 강의 시작 전에 출력물 제출

2. [LAB] 확장된 명령어 사용

  1. 다음 프로그램을   OoAa Type 명령어를 사용하지 말고 확장된 명령어들(OoRR, OoRMFA, OORMD)로 다시 작성하여 실행 하시오. 
    •  IN   10  // 510
       STA  11  // 211
       IN   10  // 510
       STA  12  // 212
       SUBA 11  // 411
       SKN      // 803
       JMP  09  // 909
       LDA  11  // 111
       SUBA 12  // 412
       OUT  12  // 612
       COB      // 700
       BOX  0   // 000
       BOX  0   // 000
      
       
    • Memory Mapped IO를 사용하시오.
      예    LD  A  92000100       ==>   1300  0100  9200
    • I/O를 제외하고는 모두 Relative Addressing(OORMD)을 사용하시오
    • 상수  변수는 2개의 BOX 표현해야 한다. (낮은 자리가 낮은 주소로.. )
          90:  DBOX  12345678  ==> 90: 5678,  91:1234
  • 생각해보기
- Skip on Condition & JMP의조합을 어떤 Conditional Jump 바꿀 것인가?
- SKIP3 를 사용할 경우 후속 명령어가 3 BOX 미만인 경우 어떻게 처리하였는가?

   <<제출 방법>>
  • 제출하지 않고 자율 실습 (But 시험문제와 관련 있음)

3. [LAB] Addressing Mode - LD 명령어 구현
  1. LD 명령어를 모든 Addressing Mode에서 동작하도록 확장하시오.
  2. 모든 경우를 테스트할 수 있는 간단한 테스트 LMC 프로그램을 작성하여 실행시키시오.
  • 참고: 강의 노트: Addressing Mode
  • 참고: 교재 7장 pp221-231 특히 p230의 getTargetAddress()
  • 처음에 LMC 모니터를 실행시키려면 cassette/BOOT의 내용이 "9710 0700"이어야 한다.
<< 실습 내용 >>
  1. 구현 내용 설명
  2. 테스트 계획 및 테스트 프로그램 설명 및 실행 예
  3. 생각해 보기 - 테스트 프로그램들을 LMC에 어떻게 로딩하여 실행했는지 설명
<<제출 방법>>
  • 제출하지 않고 자율 실습 (But 시험문제와 관련 있음)
4. [LAB] IO in Text Mode
1. 텍스트 모드의 터미널에서 입출력
  • mainboard/CMOS의 내용
# IO.Addr  Type            R/W     Opt.
10             KEYBOARD              mode=D
12             SCREEN                  mode=D        // Decimal mode or Debug mode
30             TAPE                       deck=cassette cassette=BOOT     // BOOT의 내용은 9710 0700
    • CMOS가 위와 같을 때 다음과 같이 실행해보시오. 출력 결과는?
    Monitor> edit 100 1305 0063 0000 0612 9710 0700
    Monitor> dasm 100 6
    Monitor> run 100
    • CMOS를 아래와 같이 변경해서 다시 부팅(./lmc 재실행)하고 다시 실행해보시오.
    # IO.Addr  Type            R/W     Opt.
    10             KEYBOARD              mode=T
    12             SCREEN                  mode=T        // Text mode - 현실의 모든 터미널은 텍스트 모드 임 (Ex. Putty)
    30             TAPE                       deck=cassette cassette=BOOT     // BOOT의 내용은 9710 0700
    • 참고: '?' 문자의 ASCII 코드 값은 십진수로 63이다. 교재 p409,.p410
    2. 아래 프로그램을 번역하여 텍스트 모드에서 실행해보시오
    SAMPLE START 0
    KEYBOARD EQU 10
    SCREEN EQU 12
    QUESTION BOX '?' // ASCII Code 63
    FIRST MOVH A, QUESTION
    OUT SCREEN
    JSUB READ_BOX
    MOV DATA1, A
    MOVH A, QUESTION
    OUT SCREEN
    JSUB READ_BOX
    MOV DATA2, A
    SUB A, DATA1
    SKN3
    JUMP LAST
    MOV A, DATA1
    SUB A, DATA2
    LAST JSUB OUT_BOX
    INT 10
    COB
    DATA1 RESDBOX 1
    DATA2 RESDBOX 1
    NUM RESDBOX 1
    RESDBOX 1
    READ_BOX MOV C, #4
    MOV A, #0
    MOV NUM, A
    RLOOP IN KEYBOARD
    CMP A, #'0' // ASCII Code 48
    JN READ_RETURN
    CMP A, #'9' // ASCII Code 57
    JP READ_RETURN
    SUB A, #'0'
    MOV D, A
    MOV A, NUM
    MUL #10
    ADD A, D
    MOV NUM, A
    JLOOP RLOOP
    READ_RETURN MOV A, NUM
    RSUB READ_BOX
    RESDBOX 1
    OUT_BOX MOV D, A
    DIV #1000
    ADD A, #'0'
    OUT SCREEN
    MOV A, D
    DIV #100
    DIV #10
    MOV A, X
    ADD A, #'0'
    OUT SCREEN
    MOV A, D
    DIV #10
    DIV #10
    MOV A, X
    ADD A, #'0'
    OUT SCREEN
    MOV A, D
    DIV #10
    MOV A, X
    ADD A, #'0'
    OUT SCREEN
    RSUB OUT_BOX
    END FIRST
    • 필요하면 어셈블러를 사용하시오. (pp330,331)
    3. 이 프로그램을 BIOS를 사용하여 다시 작성하시오. (이 때 터미널은 텍스트 모드가 아니어도 됨)
    • 교재 p272 부터 참고
    • 위 함수 READ_BOX, OUT_BOX를 아래 BIOS로 대치 가능
    정수 입력 
       LD  A  #10     // Keyboard 장치
       INT 1             // A에 정수가 입력되어 있음
       // 1305 0010 0000 9701

    정수 출력
       LD  X  A     // 출력할 정수 값이 A에 있었다면... (다른 레지스터나 메모리에 있어도 됨)
       LD  A  #12     // SCREEN 장치로 출력
       INT 11           
      // 1240 1305 0012 0000 9711

    5. [HW2] Hand compile - insertion sort
    1. insertion sorting 프로그램을 hand-compile하여 실행하시오.
    • sorting 할 숫자는 배열에 들어있음 (DBOX type)
    • 이 배열의 초기 값은 상수이어도 되고 프로그램 초기에 입력받아도 됨
    • 프로그램 끝 부분에서 sorting된 결과를 출력하야 함
    • 컴파일된 LMC 기계어 코드를 "insertionsort.lmc"라는 이름의 tape에 담은 후 교재 p359에 나오는 LOAD 명령어로 로딩해도 됨
      LOAD DEV <io addr>  <target-address>
    • 이 때 CMOS 의 내용을 아래와 같이 하고 BOOT에는 Monitor 진입하는 코드(9710)만 남겨놓는다.
    #IO.Addr Type     R/W   Opt...
    10       KEYBOARD       mode=D
    12       SCREEN         mode=D
    30       TAPE     RW    cassette=BOOT
    40       TAPE     RW    cassette=insertionsort.lmc
     for i = 1 to length(A) - 1
        x = A[i]
        j = i
        while j > 0 and A[j-1] > x
            A[j] = A[j-1]
            j = j - 1
        end while
        A[j] = x
     end for
    
     출처: https://en.wikipedia.org/wiki/Insertion_sort
    • A[j] 는 *(A+j*2) 와 같음
        즉 
      A는 배열 A의 시작 주소, 정수는 2 BOX이므로 곱하기 2, A+j*2는 주소이므로 indirect addressing(*)
    • j*2 j+j 로 하는 것이 간편하고 빠름
    <<제출 방법>>
    • 사이버캠퍼스(http://ecampus.kookmin.ac.kr)에 온라인으로 제출하고 마감일 강의 시작 전에 출력물 제출

    6. [HW3] Subroutine Program
    1. Sum(1..n) 프로그램을 3개의 함수로 나누고 main에서는   3 함수를 호출하는 구조로 바꾸시오.
     main() {
        n = data_in();
        total = sum(n);
        print(total);
     }
      1. Memory Mapped IO를 사용하시오.
        예    LD  A  92000100       ==>   1300  0100  9200
      2. 상수  변수는 2개의 BOX 표현해야 한다. (낮은 자리가 낮은 주소로.. )
            90:  DBOX  12345678  ==> 90: 5678,  91:1234
      3. JCALL/JRET, JSUB/RSUB, CALL/RET 명령어에서 Return address를 저장했던 방식 참고
        2. Report 내용
    • 재구성된 Sum(1..n) 프로그램 (니모닉과 주석으로 표현)
    •  Sum(1..n)프로그램을 의사 C로 표현
    • 생각해보기
             - 위 C 프로그램 LMC 코드 바꿀 때 상수변수파라미터반환값 등을 어떻게 표현 또는 처리 하였는가?
        3. 제출방법
    • 사이버캠퍼스(http://ecampus.kookmin.ac.kr)에 온라인으로 제출하고 마감일 강의 시작 전에 출력물 제출

    7. [LAB] Loader 및 실행화일

    1. lmc를 부팅하면 Monitor로 진입하도록 하고 다음을 실행하시오.
      • cassette/BOOT의 내용을 "9710 0700" 으로 다시 바꾸고 ./lmc를 실행
      • 13 (LD,OORFMA) , 22 (ST,OORFMA)
    Monitor> edit 100 1300 0200 0000 2200 0120 9200 1300 0202 0000 2200 0120 9200 9710 0700
    Monitor> edit 200 0062 0063 0010 0000
    Monitor> run 100

    2. 다음을 실행해 보시오.
    Monitor> dasm 100 14
    . . . 
    Monitor> dump 200 4
    . . . 


    3. 이 프로그램을 "cassette/test.bl"이라는 BL type의 실행 화일로 만들어서 다음 명령으로 로딩하고 실행하시오.
    • 교재 Ch 5 p121 & Ch 7.6 p234,235
    • mainboard/CMOS의 내용
    # IO.Addr  Type            R/W     Opt.
    10             KEYBOARD              default-mode=D
    12             SCREEN                  default-mode=D
    30             TAPE                       deck=cassette cassette=BOOT
    40             TAPE                       deck=cassette cassette=test.bl
    • load and run
    Monitor> load bl 40     // IO 40번지 장치에서 BL type의 실행화일을 로드하라는 뜻
    Monitor> run 100
    . . . 

    • cassette/test.bl의 실제 내용
    0072 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0100 0000 0104 0000
    1300 0200 0000 2200 0120 9200 1300 0202 0000 2200 0120 9200 9710 0700
    0000 0000 0000 0000 ..... // 0000 이 86개
    0062 0063 0010 0000
    0069 0100 0000

     

    • cassette/test.bl의 내용 - 사람이 보기 좋은 형태
    H "0123456789" 0100 0000 0104 0000
    1300 0200 0000 2200 0120 9200 1300 0202 0000 2200 0120 9200 9710 0700
    0000 0000 0000 0000 ..... // 0000 이 86개
    0062 0063 0010 0000
    E 0100 0000

     

     

    4. 이 프로그램을 "cassette/test.rl"이라는 RL type의 실행 화일로 만들어서 다음 명령으로 로딩하고 실행하시오.
    • 교재 Ch 5 p123
    • H, T, E 레코드만 사용하고 M 레코드는 여기서는 사용하지 않는다.
    • mainboard/CMOS의 내용
    # IO.Addr  Type            R/W     Opt.
    10             KEYBOARD              default-mode=D
    12             SCREEN                  default-mode=D
    30             TAPE                       deck=cassette cassette=BOOT
    40             TAPE                       deck=cassette cassette=test.rl
    • load and run (M 레코드가 없으므로 반드시 실행화일의 start 주소와 같은 곳에 loading해야 한다.)
    Monitor> load rl 40 100   // IO 40번지 장치에서 RL type의 실행화일을 읽어 100번지부터 로드하라는 뜻
    Monitor> run 100
    . . . 
    • cassette/test.rl의 내용 - 사람이 보기 좋은 형태
    H "0123456789" 0100 0000 0104 0000
    T 0100 0000 0009 1300 0200 0000 2200 0120 9200 1300 0202 0000 T 0109 0000 0005 2200 0120 9200 9710 0700
    T 0200 0000 0004 0062 0063 0010 0000
    E 0100 0000

     

    5. 위 4번 실행화일에 M 레코드를 추가하여 어느 곳에 로딩하여도 문제없이 실행되도록 하시오.
    • load and run 
    Monitor> load rl 40 398   // IO 40번지 장치에서 RL type의 실행화일을 읽어 398번지부터 로드하라는 뜻
    Monitor> run 398
    . . . 
    • cassette/test.rl의 내용 - 사람이 보기 좋은 형태
    H "0123456789" 0100 0000 0104 0000
    T 0100 0000 0009 1300 0200 0000 2200 0120 9200 1300 0202 0000 T 0110 0000 0005 2200 0120 9200 9710 0700
    T 0200 0000 0004 0062 0063 0010 0000
    M 0101 0000 0002 // 0000:0101 번지부터 2박스를 바꾸라는 뜻
    . . .
    E 0100 0000
    • 상수를 코드 앞에 놓는다면 아래와 같을 것이다 - 주의 E record
    H "0123456789" 0100 0000 0018 0000
    T 0100 0000 0004 0062 0063 0010 0000
    T 0104 0000 0009 1300 0100 0000 2200 0120 9200 1300 0102 0000 T 0113 0000 0005 2200 0120 9200 9710 0700
    M 0105 0000 0002 // 0000:0105 번지부터 2박스를 바꾸라는 뜻
    . . .
    E 0104 0000
     
    6. 5번 프로그램을 메모리 어느 곳으로 relocation해도 상관 없도록 PC relative addressing mode로 모두 변경하시오
    • M 레코드가 필요없는 RL 타잎의 실행화일을 만들어 실행한다.
    Monitor> load rl 40 398   // IO 40번지 장치에서 RL type의 실행화일을 읽어 398번지부터 로드하라는 뜻
    Monitor> run 398
    . . . 

    7. 1번 프로그램을 아래와 같이 CMOS에서 SCREEN의 mode를 T(text)로 변경하여 실행하고 그 차이를 관찰하시오.
      • mainboard/CMOS의 내용
      # IO.Addr  Type            R/W     Opt.
      10             KEYBOARD              default-mode=D
      12             SCREEN                  default-mode=T
      30             TAPE                       deck=cassette cassette=BOOT
      40             TAPE                       deck=cassette cassette=test.bl
      • load and run
      Monitor> cat 40
      Monitor> load bl 40     // IO 40번지 장치에서 BL type의 실행화일을 로드하라는 뜻
      Monitor> run 100
      . . . 

      8. 40번지 장치의 카세트를 CC(Change Cassette) 명령어를 통해 test.rl로 교체한 후 실행하고 그 차이를 관찰하시오.
      • mainboard/CMOS의 내용
      # IO.Addr  Type            R/W     Opt.
      10             KEYBOARD              default-mode=D
      12             SCREEN                  default-mode=T
      30             TAPE                       deck=cassette cassette=BOOT
      40             TAPE                       deck=cassette cassette=test.bl
      • load and run
      Monitor> cc 40 test.rl
      Monitor> dump dev
      Monitor> cat 40
      Monitor> load rl 40 100   // IO 40번지 장치에서 RL type의 실행화일을 읽어 100번지부터 로드하라는 뜻
      Monitor> run 100
      . . . 

        9. 생각해보기
        • 마지막 6번 프로그램의 LMC 프로그램(ORG를 적절히 사용하고 주소는 숫자대신 symbolic label로 표현할 것)
        • 7번,8번에서 관찰한 SCREEN의 두가지 모드 D,T에 대해 설명하시오. 
          힌트: 교재 p235, ASCII 코드표 p409
        8. [LAB & Quiz] 디버거 활용

        1. Sum(1..n) 프로그램을 디버거 모드에서 실행 시키며 다음과 같이 관찰하시오.
        • 첫 명령에 중단점을 설정
        • 이후 반복문이 한번 지나갈 때 까지 NEXT로 한개 명령어 씩 실행하며 register 등 관찰
        • 반복 여부를 결정하는 조건문 및 모든 Jump 명령어에 중단점을 설정
        • CONTINUE 로 매 중단 지점 까지 실행하며 register 등을 관찰
        • 반복문이 한번 실행될 떄 마다 WATCH를 통해 sum 값을 관 찰
        2. 퀴즈(구두 테스트)로 확인함 - 11월 8일 예정

        9. [LAB] Program Block

        1. 아래 프로그램으로 다음 사항을 수행하시.
        • 어셈블러(교재 p360)로 번역해서 RL type의 실행 화일을 만들어 로드(교재 p359)하시오.
        • shell에서 어셈블러 사용할 때 (위 화일 이름이 tablesum.lmc라면)
            $./bin/asm --rl tablesum.lmc      
            // 에러가 발생하지 않으면 어셈블리 리스트가 모니터에 출력되고 tablesum.rl 이라는 실행화일이 생성된다.
        • 프로그램의 각 블록들이 제 위치에 들어갔는지 dasm 명령으로 확인하시오. (교재 pp107-111)
        • TABLE이 로드된 위치를 찾아 첫 10개의 값을 1부터 10으로 채우고(edit 명령) 프로그램을 실행(run 명령)해서 결과를 확인하시오.
        • 이 과정에서 에러가 있으면 알아서 고치면서 수행
        TOTAL START 0
        SCREEN_DEC EQU 12
        FIRST LD SP, #STK_BTM
        CALL NEAR MAIN
        COB
        USE CBLKS
        STACK RESDBOX 100
        STK_BTM EQU $
        USE
        MAIN CALL NEAR SUM_TABLE
        OUT SCREEN_DEC
        SHR A, 4
        OUT SCREEN_DEC
        RET
        USE CBLKS
        TABLE RESDBOX 100
        TBL_END EQU $
        LENGTH EQU (TBL_END-TABLE)/2
        USE CDATA
        TWO DBOX 2
        USE
        SUM_TABLE LD A, =0
        LD X, #LENGTH-1
        ADD X, X
        LD C, #LENGTH
        LABEL ADD A, @TABLE
        SUB X, TWO
        JLOOP NEAR LABEL
        RET
        USE CDATA
        LTORG
        END FIRST

        10. [HW4] 시스템 부팅
        1. 교재를 참고하여 부팅하면 간단한 Starter 프로그램이 실행되는 부팅 카세트를 제작하시오.
          • pp381~383, pp386~387
          • 부트스트랩 로더를 만들어야 함( BL type을 읽을 수 있는 Absolute Loader)
          • 필요하면 어셈블러를 사용하시오. (pp330,331)
          • // 아래 프로그램은 언제나 길이가 100BOX 보다 훨씬 큰 것으로 가정.함
            // 따라서 테잎의 부트 영역(0~99)에 담을 수 없으므로 ROM Loader에 의해 단순하게 처리될 수 없다.
            // 그래서 Bootstrap Loader를 만들어야 함
            STARTER      START  2000
            MOV A, NEAR ="Hello, Starter"
            PUSH A
            CALL PRINTLN // CALL 하려면 스택을 먼저 초기화해야 함
            // 위 스트링의 각 문자를 차례로 A에 넣고 OUT으로 출력해도 됨
            ADD SP, NEAR =2
            INT 10 // Trap to Monitor
            COB // Halt
            END
          • PRINTLN 함수는 교재 pp343-344 참조
          • mkboot: p356~358
        2. 리포트 내용
          • 부트스트랩 로더와 이를 통해 부팅되는 과정을 설명
          • 실행 화면 삽입
        3. 제출 방법
          • 사이버캠퍼스에 온라인으로 제출하고 마감일 강의 시작 전에 출력물 제출

        11. [LAB] Array and Pointer

        1. 다음 프로그램을  LMC 코드로 번역하여 실행하시오.
        • static int table[10] = {10,9,8,7,6,5,4,3,2,1};    // 이렇게 초기화가 된다고 가정!!

          static int a, b, result; static int *p;
          static int add_two(int x, int y) {

              int tmp;     tmp = x + y;     return tmp;        // 반환값을 A 레지스터가 아닌 스택을 통해서 전달 받는다.  // 함수 호출된 후 C,D,X 레지스터는 보존(PUSH)되었다가 복원(POP)되어야 함     }
          main() {
              result = add_two(2,3);     OUT(result,stdout);
              a = table[2];     b = table[3];     result = add_two(a,b);     OUT(result,stdout);
              result = add_two(table[4],table[5]);     OUT(result,stdout);
              p = table;     result = add_two(p[1], *(p+2));     OUT(result,stdout);
              p = &table[5];     result = add_two(p[1], *(p+2));     OUT(result,stdout);
          }

        2. 생각할 내용
        • 각 변수들의 배치 상황 설명
          - add_two 함수의 activation record 그림
          - 전역 변수들의 배치 상황 그림
          - Local Array의 배치 상황과 각 element의 addressing 방법
        • 위 프로그램 
          - 모니터의 어셈블러를 이용해서 나온 어셈블리 리스트(기계어주소라인넘버니모닉이  포함제출
        • 실행 예시
          - add_two가 호출될 때 마다 activation record가 형성되었다가 해체되는 과정 그림으로 설명

        12. [HW5] Local Array and Pointer

        1.  Array and Pointer 프로그램의 Global Array table[10]을 아래와 같이 main 함수 안의 Local Array로 바꾸고 이를  LMC 코드로 번역하여 실행하시오.
        • static int add_two(int x, int y) { int tmp; tmp = x + y; return tmp; // 반환값을 A 레지스터가 아닌 스택을 통해서 전달 받는다. } main() { int table[10]; int a, b, result; int *p; int i; for(i=9; i--; i>=0) table[i] = i+1; result = add_two(2,3); OUT(result,stdout); a = table[2]; b = table[3]; result = add_two(a,b); OUT(result,stdout); result = add_two(table[4],table[5]); OUT(result,stdout); p = table; result = add_two(p[1], *(p+2)); OUT(result,stdout); p = &table[5]; result = add_two(p[1], *(p+2)); OUT(result,stdout); }


        2리포트 내용
        • 각 변수들의 배치 상황 설명
          - add_two 함수의 activation record 그림
          - 전역 변수들의 배치 상황 그림
          - Local Array의 배치 상황과 각 element의 addressing 방법
        • 위 프로그램 
          - 모니터의 어셈블러를 이용해서 나온 어셈블리 리스트(기계어주소라인넘버니모닉이  포함제출
        • 실행 예시
          - add_two가 호출될 때 마다 activation record가 형성되었다가 해체되는 과정 그림으로 설명
        3. 제출 방법
        • 사이버캠퍼스에 온라인으로 제출하고 마감일 강의 시작 전에 출력물 제출

        Comments