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
-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개의 필드로 구성되어 있다.
레이블(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)
->점프/ 콜 등의 명령으로 그 값이 변화될 수 있다. (이외에는 명령어의 수행 크기만큼 자동으로 증가한다.)
*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(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에 접근하는 것이다!)
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만큼 증가한다.
'Computer Science > Micro Process' 카테고리의 다른 글
[마이크로프로세서] Ch.8 Hardware Connection - 컴도리돌이 (0) | 2020.11.05 |
---|---|
[마이크로프로세서] Ch.3 Jump, Loop, and Call - 컴도리돌이 (0) | 2020.11.04 |
[마이크로프로세서] Ch.1 마이크로컨트롤러(Introduction to Microcontroller)- 컴도리돌이 (0) | 2020.11.02 |