본문 바로가기

Hacked Brain/embeddedland.net

196을 배워보자

2. 196을 배워보자

 

II. 196 Assember

II-II. 본격적인 196 어셈블리어

지난 시간에 언급한대로 196 어셈블리어의 명령을 기능에 따라 몇가지로 분류해보면 다음과 같다.

① 데이터 전송 명령 : 데이터의 이동에 관한 명령

② 산술 연산 명령 : 산술 연산(addition, subtraction, multiplication, division)에 관한 명령

③ 논리 연산 shift 명령 : 논리 연산과 shift 명령

④ branch 명령 : 일반 분기(jump) 및 비교(compare), 조건 분기에 관한 명령

⑤ Stack과 subroutine 및 system 제어 명령 : subroutine call, return, stack 제어, system 제어 명령

II-II-1. 데이터 전송 명령

데이터 전송 명령은 전송하는 데이터의 크기에 따라 byte, word, double word 전송 명령 등으로 분류될 있다. 또한 번지 지정 방식(addressing mode) 따라 register direct addressing mode, immediate addressing mode, indirect addressing mode, indirect addressing mode with auto increment 등으로 나눌 수 있는데, 이는 데이터 전송에서 뿐 아니라 뒤의 명령들에서도 사용되므로 정확히 알아두어야 한다.

어셈블리어의 한 문장의 형식은 이미 언급했지만, 다음과 같다.

<mnemonic> < 1 operand>, < 2 operand>, < 3 operand>

ex) LDB 0F0H, 30H

데이터 전송 명령에서는 1 operand와 제 2 operand만을 사용한다.

데이터 전송 명령은 모두 다음과 같다.

 

mnemonic

byte

state

기계어

flagS

76543210

2 operand

1 operand

LD

2+BEA

4+CEA

101000aa

waop

wreg

Z N C V VT ST

LDB

2+BEA

4+CEA

101100aa

boap

breg


ST

2+BEA

4+CEA

110000aa

waop

wreg


STB

2+BEA

4+CEA

110001aa

baop

breg


XCH

3

5+CEA

00000100

waop

wreg


XCHB

3

5+CEA

00010100

baop

breg


LDBSE

2+BEA

4+CEA

101111aa

waop

wreg


LDBZE

2+BEA

4+CEA

101011aa

baop

breg


BMOVI

3

7+8/word

11001101

waop

lreg


① aa 의미 operand 의미

 

aa

addressing mode

00

register direct

01

immediate

10

indirect

11

indexed

wreg

register file의 word register

waop

addressing mode에서 지정되는 word operand

breg

register file의 byte register

baop

addressing mode에서 지정되는 byte operand

lreg

register file의 long register

BEA

addressing mode에서 필요한 byte

CEA

addressing mode에서 필요한 state


* breg, wreg, lreg 사용하는 경우 boap 관계없지만, wreg 짝수, lreg 4의 배수의 address 되어야만 한다.

:

06H

05H

04H

03H

02H

01H

00H


위의 table에서 LD(Load Data) 제 2 operand 내용을 제 1 operand 의 내용으로 복사하는 명령이다. 뒤에 붙은 B는 byte를 의미한다. ST(STore) 반대 방향으로의 데이터 전송 명령이다. 나머지는 뒤에서 언급하기로 하고, 여기서 이 명령에 대해서 간단히 알아보고 번지 지정 방법(addressing mode) 대해서 알아보도록 하자.

II-II-1-1 data 전송 명령 형식

(1) Byte 전송 명령 형식 I

LDB < 1 operand>, < 2 operand>

① 제 1 operand byte register, 2 operand byte register 또는 번지 지정에 의해서 지정되는 memory이다.

② 결과가 저장되는 1 operand는 반드시 80196KC register file이어야 한다.

(2) Byte 전송 명령 형식 II

STB < 1 operand>, < 2 operand>

① 제 1 operand byte register, 2 operand byte register 혹은 번지 지정에 의해 지정되는 memory이다.

② STB역시 1 operand 반드시 register file이어야 한다.

(3) Word 전송 명령 형식 I

LD < 1 operand>, < 2 operand>

① 제 1 operand word register, 2 operand word register 혹은 번지 지정에 의해 지정되는 memory이다.

② 역시 1 operand register file이어야 한다.

(4) Word 전송 명령 형식 II

ST < 1 operand>, < 2 operand>

① 제 1 operand word register, 2 operand word register 혹은 번지 지정에 의해 지정되는 memory이다.

② 제 1 operand register file이어야 한다.

위에서 볼 있듯이 196은 다른 CPU와는 달리 데이터 전송에서 1 operand register file 내의 어떤 memory라도 상관없다. 보통의 CPU에서는 외부 memory를 access하기 위해서는 특정한 register를 사용하거나 accumulator사용해야 한다. 이는 196의 RALU 강점이라 할 수 있을 것이다. 이제 부터는 196 번지 지정 방법에 대해 알아보자.

II-II-1-2 번지 지정 방법(addressing mode)

(1) 레지스터 직접 번지 지정(register direct addressing mode)

register와 register 간의 data를 직접 access 사용된다.

ex) LDB 50H, 60H ; 60H byte register의 내용을 50H byte register 전송한다.

LDB 41H, 0E0H ; 0E0H byte register의 내용을 41H byte register로 전송한다.

STB 77H, 88H ; 77H byte register의 내용을 88H byte register로 전송한다.

LD 50H, 64H ; 64H word regiser의 내용을 50H word register 전송한다.

ST 0A0H,86H ; 0A0H word register의 내용을 86H word register 전송한다.

note

위에서 말했던 것처럼 word 전송의 경우, operand 반드시 word register address 되어야 한다. , 짝수 번지만이 사용될 수 있다. 다음과 같은 경우는 error 된다.

LD 51H, 60H

ST 6AH, 7FH

그러나 byte 전송의 경우에는 어떤 address라도 상관이 없다.

(2) immediate 번지 지정

명령어에 저장될 data가 직접 포함되어 있는 경우의 addressing 방법으로 register 원하는 data를 넣고 싶을 때에 사용할 수 있다. 여기에 사용되는 data의 앞에는 #을 사용해서 address(variable name)와 구분한다.

ex) LDB 81H, #50H ; byte register 81H에 data 50H 저장된다.

LD 4AH, #1024 ; word register 4AH에 십진수 1024가 저장된다.

LDB 0BBH, #'a' ; byte register 0BBH에 'a'의 ASCII code 값이 저장된다.

note 1

데이터가 word register 저장되는 순서는 하위, 상위의 순서로 저장된다. 예를 들어 다음 명령이 실행된 후의 memory(register file) 내용을 보면 아래와 같다.

              LD 50H, #1234H

              ( 명령 실행 )

52H

:


51H

??

상위 byte

50H

??

하위 byte

4FH

:


; word register 50H data 1234H 저장한다.

              ( 명령 실행 후  )

52H

:


51H

12H

상위 byte

50H

34H

하위 byte

4FH

:


note 2

immediate addressing mode에는 STB, ST 없다. 따라서 다음 명령의 경우는 error 된다.

STB #14, 50H

(3) 간접 번지 지정(indirect addressing mode)

간접 번지 지정의 경우에는 register를 pointer로서 사용한다. 즉, register의 값이 실제 사용될 memory의 address가 된다. 이 경우 [ ]를 이용하여 pointer 사용되고 있음을 나타낸다. [ ]안의 register 반드시 word register 되어야 한다(따라서 짝수 address register 되어야 한다.). 0000H~0FFFFH까지의 memory 영역을 access 하기 위한 주소로 사용되기 때문이다.

                         ex) LDB 53H, [60H]

                           ( 명령 실행 전 )

 

주소

:


61H

56H

상위 byte

60H

33H

하위 byte

:

:


:

:


53H

00H


52H

:


주소


:


5635H

33H

5634H

22H

5633H

11H

:


:


; word register 60H가 가리키는 memory 내용을 byte register 53H

; 에 저장한다.

                        ( 명령 실행 )

주소

:


61H

56H

상위 byte

60H

33H

하위 byte

:

:


:

:


53H

11H


52H

:


주소


:


5635H

33H

5634H

22H

5633H

11H

:


:


                           LD 60H, [70H]

                          ( 명령 실행 전 )

 

주소

:


71H

56H

high byte

70H

34H

low byte

:

:


:

:


61H

00H

high byte

60H

00H

low byte

5FH

:


주소


:


5636H

44H

5635H

33H

5634H

22H

5633H

11H

:




word register 70H가 가리키는 memory의 내용을 word register

; 60H에 저장한다.

                           ( 명령 실행 )

주소

:


61H

56H

high byte

60H

34H

low byte

:

:


:

:


61H

33H

high byte

60H

22H

low byte

5FH

:


주소


:


5636H

44H

5635H

33H

5634H

22H

5633H

11H

:


:

:

STB 53H, [80H] ; byte register 53H의 내용을 word register 80H가 가리키는 memory

; 에 저장한다.

                           ST 54H, [90H]

                           ( 명령 실행 )

주소

:


91H

00H

high byte

90H

20H

low byte

:

:


:

:


55H

81H

high byte

54H

17H

low byte

53H

:


주소


:


22H

00H

21H

00H

20H

00H

1FH

00H

:




 ; word register 54H의 내용을 word register 90H가 가리키는

; memory에 저장한다.

                         ( 명령 실행 )

주소

:


91H

00H

high byte

90H

20H

low byte

:

:


:

:


55H

81H

high byte

54H

17H

low byte

53H

:


주소


:


22H

00H

21H

81H

20H

17H

1FH

00H

:


:

:

note 1

앞서 설명했지만, [ ] 안의 register 반드시 word address register가 되어야 한다. 즉, 짝수 address가 되어야 한다. 다음과 같은 명령은 error.

LD 50H, [51H]

STB 59H, [5BH]

note 2

간접 번지 지정을 1 operand 사용할 수 없다. 1 operand 반드시 register file내의 address 사용될 수 있다. 다음과 같은 경우는 error이다.

LDB [50H], 70H

ST [4EH], 54H

(4) 자동 증가(auto increment)가 있는 간접 번지 지정

이 경우는 간접 번지 지정과 비슷하다. 그런데, 명령 실행 후 간접 번지 지정에 사용한 register값을 byte의 경우 +1, word의 경우 +2만큼 증가시킨다. 이는 간접 번지 지정과 increment 를 혼합해 놓은 것으로, 특정 연산을 때 편리하게 사용할 있다. (ex. search, block copy, block fill...) 간접 번지 지정에서 사용한 [ ]뒤에 +를 붙여서 [ ]+ 나타낸다.

                        ex) LD 72H, [62H]+

                           ( 명령 실행 )

주소

:


63H

96H

high byte

62H

24H

low byte

:

:


:

:


73H

81H

high byte

72H

17H

low byte

71H

:



주소



:

:


9627H

55H


9626H

44H


9625H

33H

>

9624H

22H


9623H

11H


:

:

; 62H 가리키는 memory의 내용을 72H 전송한 후(word) 62H의

; 값을 +2만큼 증가시킨다.

                             ( 명령 실행 후 )

주소

:


63H

96H

high byte

62H

26H

low byte

:

:


:

:


73H

33H

high byte

72H

22H

low byte

71H

:



주소



:

:


9627H

55H

>

9626H

44H


9625H

33H


9624H

22H


9623H

11H


:

:

LDB 77H, [62H]+ ; 62H가 가리키는 memory 내용을 77H로 전송한 (byte) 62H

; 값을 +1 만큼 증가시킨다.

ST 88H, [90H]+ ; 88H의 내용을(word) 90H 가리키는 memory로 전송한 90H의

; 값을 +2 만큼 증가시킨다.

                          STB 31H, [60H]+

                            ( 명령 실행 )

주소

:


61H

84H

high byte

60H

20H

low byte

:

:


:

:


32H

00H

high byte

31H

FFH

low byte

30H

:



주소



:

:


8423H

55H


8422H

44H


8421H

33H

>

8420H

22H


841FH

11H


:

:

; 31H의 내용을(byte) 60H 가리키는 memory로 전송한 60H의

; 값을 +1 만큼 증가시킨다.

                             ( 명령 실행 후 )

주소

:


61H

84H

high byte

60H

21H

low byte

:

:


:

:


32H

00H

high byte

31H

FFH

low byte

30H

:



주소



:

:


8423H

55H


8422H

44H

>

8421H

33H


8420H

FFH


841FH

11H


:

:

자동 증가를 사용하면 inc 명령을 쓰지 않아도 되므로 프로그램을 간단하게 작성할 수 있다. 예를 들어 메모리 8000H~9000H 번지를 11H 모두 채우고 싶다면 다음과 같이 간단히 프로그램하면 된다.

LD 60H, #8000H

LDB 50H, #11H

LOOP: STB 50H, [60H]+

CMP 60H, #9000H

JNE LOOP

END