본문 바로가기

Computer Science/Micro Process

[마이크로프로세서] Ch.2 어셈블리 언어 프로그래밍(Assembly language programming) - 컴도리돌이

728x90
728x90

Outline

1.inside 8051

2.introduction to assembly programming

3.program counter and rom space

4.psw register and flag bits

5.register bank and stack


inside 8051

 

inside 8051 : block diagram

 

 

inside 8051 : black diagram

 

-8051 내부에 있는 ROM은 프로그램 코드가 저장되어 있다.

-8051 내부에 있는 RAM에는 임시적인 데이터가 저장되어 있다.

-8051 내부에 있는 CPU는 RAM에 저장되어 있는 임시적인 데이터(temporary data)를 가져와 ROM에 저장되어 있는 코드를 실행한다.

-8051 내부에 있는 입출력 포트(I/O PORTS)는 8bit로 4개의 포트가 존재한다.

-8051 내부에 있는 타이머는 16비트의 3개의 타이머/카운터가 존재한다.

-Clock 발진기 내장

 

inside 8051 : registers

 

 

8-bit 레지스터(registers) : A(accumulator), B, R0-R7, PSW(program status word)

 

 

 

 

16-bit 레지스터(registers) : DPTR(data pointer), PC(program counter)

 

*DPTR : 내부 프로그램 메모리는 16비트 길이의 DPTR(data pointer) 레지스터로 주소 지정하여 접근할 수 있다. 뿐만 아니라 외부에 확장 구성하는 외부 프로그램 메모리 및 외부 데이터 메모리 역시 16비트 주소 체계를 사용하므로, 확장 가능 한 외부 프로그램 메모리 및 데이터 메모리는 최대 64KB까지 가능하다.

 

*PC : 프로그램 카운터(program counter, PC)는 수행될 다음 명령이 메모리의 어디에 위치하는 지를 알려주는 두 바이트 크기의 주소를 값으로 가진다. 리셋하였 을 때 8051의 프로그램 카운터 값은 0000H으로 초기화되며, 명령이 수행될 때마다 그 값을 변경한다. 항상 프로그램 카운터는 다음에 실행할 명령의 주소를 그 값으로 가지는 16비트 길이의 레지스터이다.


Introduction to Assembly Programming

 

 

 

Assembly: MOV (move memory)

mov destination, source

 

source에 있는 데이터를 destination에 복사(copies)한다.

 

<example>

MOV A, #55H  //load 55H into reg.A
MOV R0, A    //copy contents of A into R0

 

*H는 16진수를 가리킨다.(hexadecimal number)

 

<cont'd> -> 중요!

MOV A, #0F3H 	 //If the number starts with a letter, put ‘0’ in front of it
MOV A, #7F2H 	// possible error
MOV A, #257 	//possible error

 

*MOV A, #7F2H에서 에러가 발생한다. ( 7F2H > 8bit(FFH))

*MOV A, #257에서 에러가 발생한다. (257 > 8bit(255))


Assembly: ADD

ADD A, source

 

ADD는 ACC(reg.A)의 값과 source의 값을 더하여, 결과를 ACC에 저장한다.

 

<example>

MOV A, #25H    //load 25H into A
MOV R2, #34H   //load 34H into R2
ADD A, R2      //A = A + R2
MOV R1, #0F5H  //load F5H into A (demo)
MOV A, #0      //load 0 into A

 

<cont'd>->중요!

->레지스터 A에는 하위 8비트만 저장됨

->오버플로가 발생할 경우 PSW(Program Status Word) 레지스터의 carry flag가 설정된다


Assembly: Strucutre

[label] [mnemonic] [operands] [;comments]

 

->어셈블리 언어 명령은 4개의 필드로 구성되어 있다.

 

 

structures of assembly language

 

 

레이블(label)

-> 프로그램 중에 기호 주소(symbolic address)를 지정할 필요가 있을 때 사용한다. 프로그램의 작성 과정에서 레이블(label)을 통하여 특정 위치를 지정할 수 있으며, 프로그램의 분기 또는 점프할 곳의 어드레스 대신에 사용되거나, 기억 장소의 어드레스 혹은 이름 또는 상수 값의 이름으로 사용된다

-> E.g : HERE: SMJP HERE

 

니모닉(mnemonic)과 피연산자(Operand)

->니모닉(mnemonic)은 명령어의 동작을 지시하는 부분이며, 필요에 따라 명령어 수행에 필요한 피연산자를 동반하기도 한다.

->피연산자(operand)는 명령어의 동작을 지시하는 OP코드의 연산 대상 또는 목적이 되는 부분으로 명령에 따라 1개, 2개 혹은 생략되는 경우가 있다. 문법적으로 OP 코드와 피연산자 사이는 하나 이상의 공백이 있어야 하며, 두 개의 피연산자 간에는 콤마(,)를 두어 각각의 피연산자를 구분한다. 피연산자로 사용되는 즉치(Immediate Mode)의 표기방법은 16진수의 경우는 H를, 10진수는 기호 없이 혹은 D를, 2진수의 경우는 B문자를 즉치(Immediate Mode)의 후미에 덧붙인다.


Assembly: Direcitves

의사 명령어는 실행단계에서는 무의미한, 즉 실행에는 어떠한 영향도 주지 않으면서 어셈블 과정에서 유용하게 활용되는 명령어다.

 

 

 

 

ORG : 명령의 시작 주소를 지정하는 의사 명령어.

DB : 레이블 또는 어드레스로 지정할 수 있는 1바이트의 메모리를 확보하며, 확보된 메모리(ROM)에는 임시의 데이터를 기억시킬 수 있다.

END : 프로그램의 끝을 나타내는 의사 명령어(END 이후에 나열된 명령어는 어셈블 과정에서 번역되지 않는다.)

EQU : 특정 레이블에 데이터나 어드레스의 상수를 지정하기 위해 사용되며, 레이블 자체가 지정된 값을 가지므로 메모리를 차지하지는 않는다. 

 

*pseudo-code(수두 코드)는 머신 코드로 변경하지 않는다. 단지 어셈블러에서 특정한 작업을 알려줄 때 사용된다.


program counter and rom space

 

 

ROM Space : PC( program Counter)

PC(prgram counter)

 

->ROM에 저장되어 있는 명령어의 실행 순서를 정해주는 16bit Register

->실행하고자 하는 명령이 들어있는 메모리의 번지를 가리킨다.

->PC는 Reset 된 후의 값은 0000H가 된다. (0000H ~ FFFFH)

->점프/ 콜 등의 명령으로 그 값이 변화될 수 있다. (이외에는 명령어의 수행 크기만큼 자동으로 증가한다.)

 

 

Program Counter

 

*2행에서 현재 opcode가 7D25로 2byte이기 때문에 PC는 2만큼 증가한다.

*5행에서 현재 opcode가 2D로 1byte이기 때문에 PC는 1만큼 증가한다.

 

ROM space

->ROM은 프로그램 저장 시 사용한다.(PC로 접근)
->PC에서 액세스 할 수 있는 최대 ROM 공간: 64KB
->대부분의 8051 칩은 64KB 미만의 ROM 크기를 가지고 있다.


psw register and flag bits

 

 

PSW(Program Status Word register)

 

PSW

 

PSW(8-bit 레지스터)는 명령이 수행된 후에 그 결과에 따라 그 상태를 반영하는 중요한 비트들을 저장하는데 이용된다. PSW는 캐리, 보조 캐리, 오버플로, 그리고 패리티 플래그를 포함한다. 또한 PSW는 현재 선택된 레지스터 뱅크가 무엇인지를 나타내는 데 이용되는 레지스터 뱅크 선택 플래그 비트를 가진다.

 

PSW conditional flags

 

CY(carry flag, PSW.7)

 

-> 비트 7(D7)에서 캐리가 발생하면 1로 변경된다. 즉, Reg.A(ACC)와 피연산자의 값을 더한 결과가 255를 초과하면 캐리 비트를 1로 된다. 그렇지 않으면 캐리 비트는 0이다.

 

->SETB C : 캐리 비트를 1로 설정

->CLR C : 캐리 비트를 0으로 설정

 

AC(auxiliary carry flag, PSW.6)

 

->비트 3(D3)에서 캐리가 발생하면 1로 변경된다. 즉, ACC와 피연산자 값을 더한 결과가 15를 초과하면 AC는 1로 되고, 그렇지 않으면 AC는 0이다.

 

P(parity flag, PSW.0)

 

->Reg.A의 '1' 숫자가 홀수인 경우 P = 1
->Reg.A의 '1' 숫자가 짝수일 경우 P = 0

 

OV(overflow flag, PSW.2)

 

->비트 6(D6) 혹은 비트 7(D7)에서 자리올림이 발생하면 1로 변경된다. 그러나 두 비트 모두에서 자리올림이 발생하면 0이 된다. 즉, ACC와 피연산자 값을 더한 결과를 부호화 값으로 취급하였을 때 1바이트의 부호화 표현의 범위(-128~+127)를 벗어나면 OV 비트는 1로 되고, 그렇지 않은 경우 0이 된다.

 

RS1(PSW.4), RS0(PSW.3)

 

 

 

 

<example>

MOV A, #9CH
ADD A, #64H
Solution:  9C   10011100 
          +64   01100100 
          100   00000000 
			 
CY = 1  
AC = 0  
P  = 0 

 

<example>

MOV A, #38H
ADD A, #2FH
Solution: 38 00111000
         +2F 00101111
          67 01100111
          
CY = 0
AC = 1
P = 1

 

<example>

MOV A, #88H
ADD A, #93H
Solution : 88   10001000
          +93   10010011
          11B  100011011
          
CY = 1
AC = 0
P = 0

register bank and stack

 

RAM

->8051 내부에 있는 RAM은 전체 128 bytes로 존재한다.

->주소 범위 : 00H( ROM 주소 범위와 혼란되지 말자!, ROM은 PC에 접근하는 것이다!)

 

 

128 byte을 세 그룹으로 나누었다.

 

00H-1FH : 레지스터 뱅크, 스택 영역

20H-2FH : 비트 주소 지정 메모리

30H-7FH : "스크래치 패드", 데이터 및 파라미터 저장

 

Register Banks(레지스터 뱅크 영역) - 32 bytes

 

 

-> 최하위의 32바이트에는 8개 레지스터로 구성되는 레지스터 뱅크(register bank)가 4 뱅크(4 banks)가 존재한다. 각 레지스터 뱅크 내의 레지스터 각각은 R0, R1,..., R7으로 지칭된다. 이렇게 레지스터 이름을 사용하는 명령들은 해당 레지스터의 직접 주소를 사용하는 명령보다 짧기 때문에 명령 코드를 보다 효율적으로 사용할 수 있도록 한다. 이러한 레지스터 뱅크는 한순간에 하나의 레지스터 뱅크만이 의미를 가지며, PSW(program status word) SFR의 두 비트 RS1, RS0의 설정 값에 따라 레지스터 뱅크가 선택된다.

 

->리셋 후 레지스터 뱅크는 RB0가 기본적으로 설정되고, SP(stack pointer)는 07H로 설정된다. 이 경우 실질적인 스택 영역은 주소 08H부터 시작된다. 따라서 레지스터 뱅크를 제외한 나머지 영역은 프로그램 수행 중에 스택 영역으로 사용된 다. 이들 레지스터 뱅크는 한순간에 하나의 레지스터 뱅크만을 사용할 수 있으며, 다른 레지스터 뱅크를 선택하는 경우에는 SP도 적절히 재설정해 줄 필요가 있다.

 

<Example>

MOV R4, #32H //1
MOV R7, #3FH //2

//bank0을 사용할 경우 RAM location
//1 : RAM location 4H는 32H 값을 갖는다.
//2 : RAM location 7H는 3FH 값을 갖는다.

//bank2를 사용할 경우 RAM location
//1 : RAM location 14H는 32H 값을 갖는다.
//2 : RAM location 17H은 3FH 값을 갖는다.

 

SP(stack pointer) register

->SP는 스택 영역을 지시하는 스택 포인터다. 리셋 후 SP은 07H로 초기화되며, 스택 영역은 08H부터 시작하여 내부 램의 주소 증가 방향으로 확장된다.->스택에 값을 저장하는 PUSH 명령의 경우, SP값을 하나 증가시키고 해당 위치에 값을 저장한다. POP 명령의 경우 우선 현재 SP값의 주소에 있는 값을 읽어내고, SP 값을 하나 감소한다.

 

<example>

MOV R0, #25H  
MOV R1, #12H  
MOV R2, #0F3H 
PUSH 0 // push R6 into stack
PUSH 1 // push R1 into stack
PUSH 2 // push R4 into stack
POP 3
POP 4
POP 5

 

<cont`d>

 

1) SP 레지스터의 값을 수동으로 변경할 수 있음(ex. MOV SP, 30H)


2) 레지스터 뱅크 1과 스택 간의 충돌

->레지스터 뱅크 1과 기본 스택이 동일한 주소를 사용한다.(08H-0FH)
->프로그램에서 레지스터 뱅크 1을 사용해야 하는 경우, 해당 스택을 재할당해야 한다.(ex. scratch pad, 30H)


3) 스택이 비어 있고 POP을 시도하면 어떻게 될까? (POP > PUSH)
->SP가 계속 감소한다.
->프로그램에서 PUSH와 POP의 수가 다르지 않도록 주의해야 한다.


4) 계속 PUSH 하면 어떻게 될까?
->메모리가 부족해질 때까지 SP가 계속 증가한다.(메모리 초과 주의)

 

5) Call instruction


->"CALL" 명령이 실행될 때마다 CPU는 스택을 사용하여 일시적으로 정보를 저장한다.
->SP 및 스택의 정보가 변경될 것이다.

↓시험공부

더보기

1. 명령어 오류 확인 & PC 증가 수

 

(1) MOV R1, #300   

(2) MOV R2, #70

(3) MOV A, #120H

(4) MOV A, #FFH

(5) MOV R17, #50H

 

-> (1), (3) , (4), (5)  오류  -> (2) : PC+2

 

2. DB directive가 상수 값으로 사용되었을 때 어느 메모리 공간을 사용하는가?

->DB는 확보된 메모리 공간을 임시적으로 데이터를 저장하는 데, ROM 메모리 공간에 사용된다.

 

3. 만약 프로그래머 레지스터 뱅크 1을 사용하고 부가적으로 스택(stack) 작업을 해야 한다면 어떻게 해야 하는가?

-> 뱅크 1과 스택 영역은 같은 공간을 유지하기 때문에 뱅크 1을 사용한다면 SP의 초기 값을 스크래치 패드 30H공간으로 재할당 시켜준다.

 

4. 만약 레지스터 뱅크 3을 사용하고 초기 값이 07H로 SP를 설정할 때, 초기 값 이후 PUSH 명령을 할 수 있는 최대 수는 얼마인가(뱅크 3과의 충돌 없이)?

-> 초기 값 07H를 갖는 스택의 공간은 뱅크 1과 공유하기 때문에 뱅크 1, 뱅크 2 공간은 자유롭게 PUSH, POP을 할 수 있다. 그러므로 뱅크 1, 뱅크 2 공간을 다 PUSH 할 경우 최대 PUSH 명령을 할 수 있는 수는 14번이다.

 

5. DB와 EQU directives가 상수 값으로 사용될 때 어느 것을 사용하는 게 좋은가? 

->DB는 데이터 상수를 사용할 때 임시 메모리 공간을 만들어서 데이터를 저장한다. 하지만 EQU는 상수를 선언할 때 메모리 공간을 사용하지 않는다. EQU는 메모리 공간을 사용하지 않기 때문에 매크로처럼 값을 지정하여 코드 내에서 사용할 수 있기 때문에 EQU direcitves를 사용하는 게 좋을 거 같다.(메모리 공간을 접근할 필요가 없기 때문에)

 

6. 명령어 실행될 때 PC 값을 얼마나 증가하는가?

-> opcode가 1byte일 때 PC값은 1만큼 증가하고, opcode가 2byte일 때 PC값은 2만큼 증가한다.


728x90
728x90