본문 바로가기

AVR(ATmega128)로 장난하기

AVR(ATmega128) 시스템 개발 기초 지식_어셈블리 명령


1. 명령어 분류와 주소지정 방식


● 명령어 기본 형식 : 명령어는 명령코드(OP 코드:OPeration code)와 오퍼랜드(operand)로 구성되는데 명령코드는 명령 그 자체이고 오퍼랜드는 명령의 대상으로 레지스터, 메모리, 상수값이 사용될 수 있으며 명령에 따라 오퍼랜드 없이 명령코드에 포함되는 경우가 있다. 명령코드는 대부분 16비트의 길이이지만 LDS, STS, JMP, CALL 4개의 명령어는 32비트이다.

 실행시간에 따른 분류 : 실행하는데 1~4 기계사이클를 요구하여 ① 1기계사이클 명령어(예: ADD Rd, Rr)와 ② 2기계사이클 명령어(예:ADIW Rdl, K) ③3기계사이클 명령어(예:ELPM 혹은 LPM) ④4기계사이클 명령어 (예:RETI 혹은 RET)로 나뉠 수 있다.

 기능에 따른 분류 : 데이터전송, 산술과 논리 연산, 분기, 비트 조작, MCU 제어 명령으로 나눌 수 있다.

① 데이터전송 명령 : 내부램이나 외부램의 데이터 전송을 위한 명령으로 MOV, MOVW, LDI, LD, LDD, LDS, ST, STD, STS, LPM, ELPM, SPM, IN, OUT, PUSH, POP 등 16가지가 관계된다.

② 산술과 논리연산 명령 : 가감산, 증감, 곱하기 등 산술연산과 논리연산 명령어로 ADD, ADC, ADIW, SUB, SUBI, SBC, SBCI, SBIW, AND, ANDI, OR, ORI, EOR, COM, NEG, SBR, CBR, INC, DEC, TST, CLR, SER, MUL, MULS, MULSU, FMUL, FMULS, FMULSU 등 28가지가 관계된다.

③ 분기 명령 : 조건을 따져 분기하거나 프로그램의 실행순서를 바꾸는 명령으로 RJMP, IJMP, JMP, RCALL, ICALL, CALL, RET, RETI, CPSE, CP, CPC, CPI, SBRC, SBRS, SBIC, SBIS, BRBS, BRBC, BREQ, BRNE, BRCS, BRCC, BRSH, BRLO, BRMI, BRPL, BRGE, BRLT, BRHS, BRHC, BRTS, BRTC, BRVS, BRVC, BRIE, BRID 등이 관계된다.

④ 비트 조작 명령 : 1비트값에 대한 비트조작 불리안 연산 명령으로 SBI, CBI, LSL, LSR, ROL, ROR, ASR, SWAP, BSET, BCLR, BST, BLD, SEC, CLC, SEN, CLN, SEZ, CLZ, SEI, CLI, SES, CLS, SEV, CLV, SET, CLT, SEH, CLH등이 관계된다.

⑤ MCU 제어 명령 : NOP, SLEEP, WDR, BREAK 등 4개의 MCU 제어 관련 명령

 오퍼랜드의 주소지정방식

① 직접상수지정 방식 : 오퍼랜드로서 상수값을 사용하는 방식이다.

② I/O 직접주소지정 방식 : 오퍼랜드로서 64개의 I/O 레지스터의 주소값을 직접 지정한다.

③ 레지스터직접주소지정 방식 : R0~R31이 오퍼랜드로서 지정된다.

④ 데이터 직접주소지정 방식 : 오퍼랜드로서 데이터 메모리 영역의 16비트 주소값을 직접 지정한다.

⑤ 데이터 간접지정 방식 : 오퍼랜드의 주소를 저장하고 있는 X,Y,Z레지스터를 이용하여 간접적으로 지정한다.

⑥ 선증가 데이터 간접지정방식 : 데이터 간접지정방식과 비슷하나 X,Y,Z레지스터값을 먼저 1만큼 감소시킨다.

⑦ 후증가 데이터 간접지정방식 : 데이터 간접지정방식과 비슷하나 X,Y,Z레지스터값을 명령 실행 후에 1만큼 증가시킨다.

⑧ 변위 데이터 간접지정방식 : 데이터 간접지정과 비슷하나 Y,Z레지스터값에 변위값을 합하여 사용한다.

⑨ 프로그램 메모리 상수 지정방식 : Z레지스터를 사용하여 프로그램 메모리 영역의 상수값을 지정한다.

⑩ 후증가 프로그램 메모리 상수 지정방식 : 프로그램 메모리 상수 지정방식과 비슷하나 Z레지스터 값을 명령 실행 후에 1만큼 증가시킨다.


2. 명령어 요약


다음은 ATmega128의 명령을 요약한 것으로 항목에서 #clocks은 수행에 걸리는 기계사이클, Flags은 명령 수행으로 영향을 받는 CSEG의 비트를 의미한다. 그리고 다음의 정의들이 사용된다.


 Rd

 Destination register R0~R31

 Rr 

 Source register R0~R31

 b, s

 바이트 데이터의 비트번호값 0~7

 P

 I/O레지스터 주소값 (0-31/63)

 K

 8비트 상수값

 k, q

 상수

 Rd1

 R24, R26, R28, R30.

 X 

 Indirect address register R27:R26

 Y

 Indirect address register R29:R28

Z

 Indirect address register R31:R30

어셈블리 명령에 쓰인 약자의 의미


▶ 분기 명령


▶ MCU 제어 명령


▶ 데이터전송 명령 


▶ 산술과 논리 연산 명령


▶ 비트 조작 명령


(1) 어셈블리어의 일반형태


 어셈블리어의 일반형태는 아래와 같다.

[라벨 + : + 1개 이상의 공백 ] + 명령어(혹은 지시어) + [1개 이상의 공백 + ; + 주석]

(예: START: LDI AL, 0b10000000 ;AL에 이진수 10000000 값을 넣어라. )

 라벨 (Label)은 기호주소로 분기명령이나 참조에 사용되는 심볼(Symbol)로 ① 심볼과 바로 뒤에 공백없이 :(콜론)을 두고 콜론과 명령어는 1개 이상의 공백을 두어야 한다. ② 어셈블러(어셈블리어를 기계어로 바꾸어주는 프로그램)에 따라 다르지만 길이는 보통 1에서 수십개까지의 기호가 허용되고 AVR Studio4에서 심볼은 영문자

와 숫자와 특수문자(_)의 조합을 사용하고 처음은 반드시 숫자가 아닌 기호(영문자나 _)로 시작해야한다. ③R0-R31과 같은 어셈블러 특수 심볼 그리고 명령어와 지시어 등 예약어는 심볼로 사용될 수 없고 ④ 심볼은 보통 명령어, 지시어와 함께 대문자와 소문자의 구분이 없다(AVR Studio4에서 구분을 하게 옵션 설정 가능).

 주석은 반드시 앞에 ;(세미콜론)을 붙여야 하는데 어셈블러는 세미콜론과 같은 줄에 존재하며 세미콜론 뒤쪽에 존재하는 글은 주석으로 여기고 모두 무시한다.


(2) 지시어(의사 명령)


 지시어란 기계어로 번역되지 않고 어셈블러에게 어떤 정보만을 제공하는 것으로 의사명령이라고 불린다.

 CSEG : 프로그램 메모리에 해당하는 코드 세그먼트의 시작을 정의한다. 파라메터를 갖고 있지 않다.

 DSEG : SRAM 데이터 메모리 세그먼트의 시작을 정의한다. 파라메터를 갖고 있지 않다.

 ESEG : EEPROM 데이터 메모리 세그먼트의 시작을 정의한다. 파라메터를 갖고 있지 않다.

 EQU : .EQU +1개 이상의 공백 + 심볼 +1개 이상의 공백 +상수값의 형태로 어떤 심볼의 값을 정의하는데 용된다. EQU를 사용하면 숫자로 된 값대신에 기억하기 쉬운 심볼을 사용하여 프로그램을 쉽게 할 수 있다.

어셈블러에서는 기계어로 번역할 때 라벨을 상수값으로 대체하여 해석하게 된다. 한 번 할당된 값은 수정되거나 다시 정의될 수 없다.

예 : .EQU BUF= 0x20 ;기계어로 번역시 BUF는0x20으로 대체된다.

 SET : EQU와 유사하나 나중에 다시 정의되어 수정 가능하다.

 DEF : .DEF +1개 이상의 공백 + 심볼 +1개 이상의 공백 +레지스터이름의 형태로 기억하기 쉬운 심볼에 레지스터를 할당하여 프로그램을 쉽게 할 수 있다. 나중에 다시 정의되어 수정 가능하고 같은 레지스터에 여러가지 심볼을 할당할 수 있다.

예 : .DEF BUF= R0 ; BUF는 R0

 UNDEF : .UNDEF +1개 이상의 공백 + 심볼의 형태로 심볼에 레지스터를 할당한 것을 해제한다.

예 : .UNDEF BUF ; BUF를 해제

 ORG : .ORG +1개 이상의 공백 +주소의 형태로 바로 뒤에 오는 프로그램 명령어의 시작번지나 데이터의 시작번지 지정에 사용된다. 주소로는 숫자 뿐만 아니라 라벨도 사용될 수 있다. 다음과 같은 프로그램의 경우 명령어 LDI AL, 0b10000000와 그 이후의 명령은 프로그램 메모리의 20번지를 시작으로 차례로 저장된다.

예: .CSEG

.ORG 0x0020

START: LDI AL, 0b10000000 ;AL에 이진수 10000000 값을 넣어라.

.............

 BYTE : 심볼 +: +1개 이상의 공백 +.BYTE +1개 이상의 공백 +숫자의 형태로 SRAM 데이터 세그먼트에 숫자 만큼의 메모리를 바이트 단위로 예약해둔다.

예 : CNT: .BYTE 1 ;CNT을 위해 1바이트를 유보해 두라.

 DB (Define Byte) : 라벨 +: + 1개 이상의 공백 +.DB +1개 이상의 공백 +데이터의 형태로 1바이트(8비트)단위로 숫자나 문자 데이터들을 프로그램 메모리나 EEPROM 세그먼트에 저장할 때 사용한다.

예 : .ESEG

DATA: DB 1, 2, 'S' ; 라벨 DATA번지에 1을 DATA+1에 2를 DATA+2에 ‘S'를 저장.

 DW (Define Word) : 라벨 +: + 1개 이상의 공백 +.DW +1개 이상의 공백 +데이터의 형태로 1워드(2바이트,16비트) 단위로 숫자나 문자 데이터들을 프로그램 메모리나 EEPROM 세그먼트에 저장할 때 사용한다.

 DD (Define Doubleword) : 라벨 +: + 1개 이상의 공백 +.DD +1개 이상의 공백 +데이터의 형태로 2워드 (4바이트, 32비트)단위로 숫자나 문자 데이터들을 프로그램 메모리나 EEPROM 세그먼트에 저장할 때 사용한다.

 DQ (Define Quadword) : 라벨 +: + 1개 이상의 공백 +.DQ +1개 이상의 공백 +데이터의 형태로 4워드(8바이트, 64비트)단위로 숫자나 문자 데이터들을 프로그램 메모리나 EEPROM 세그먼트에 저장할 때 사용한다.

 INCLUDE : .INCLUDE + 1개 이상의 공백 +"+ 파일이름 +“의 형태로 외부의 파일을 include하여 어셈블할 때 사용한다.

 IF : .IF + 1개 이상의 공백 +조건식의 형태로 조건식을 만족하면 아래 부분를 어셈블한다.

 ELIF : .ELIF + 1개 이상의 공백 +조건식의 형태로 앞선 IF의 조건을 만족시키지 않는 다른 조건을 판단할 때 사용하며 주어진 조건식을 만족하면 아래 부분를 어셈블한다.

 IFDEF : .IFDEF + 1개 이상의 공백 +심볼의 형태로 심볼이 정의되어 있으면 아래 부분을 어셈블한다.

 IFNDEF : .IFNDEF + 1개 이상의 공백 +심볼의 형태로 심볼이 정의되지 않았으면 아래 부분을 어셈블한다.

 ELSE : IF, IFDEF, IFNDEF와 같은 조건문에서 이전 조건이 만족되지 않으면 아래 부분을 어셈블한다.

 ENDIF : .ENDEF의 형태로 조건 블록의 마지막을 표시한다.

 ENDM 혹은 ENDMACRO : .ENDM 혹은 .ENDMACRO의 형태로 마크로를 정의를 종료할 때 사용한다.

 MACRO : .MACRO + 1개 이상의 공백 +마크로이름의 형태로 마크로를 정의할 때 사용한다. 마크로는 @0~@9로 지정된 10개까지의 파라메터가 사용될 수 있고 마크로를 호출할 때는 아래의 예에서처럼 마크로 이름 다음에 공백을 두고 해당 파라메터를 차례로 ,를 사용해 나열하면 된다.

예: .MACRO SUBL16 ; Start macro definition

subi @1,low(@0)  ; Subtract low byte

sbci @2,high(@0) ; Subtract high byte

.ENDM

.CSEG

SUBL16 0x3456, R0,R1

 ERROR : .WARNING + 1개 이상의 공백 +"주의문장“의 형태로 어셈블시 주의문장을 출력하고 어셈블을 중지한다.

예: .IFDEF EXPTEST

.ERROR "This is not proper" ; 만약 EXPTEST가 정의되었으면 This is ...을 출력하고 어셈블을 멈춘다.

.ENDIF

 WARNING : .WARNING + 1개 이상의 공백 +"주의문장“의 형태로 어셈블시 주의문장을 출력하나 ERROR처

럼 어셈블을 중지하지는 않는다.

예: .IFDEF EXPTEST

.WARNING "This is not properly tested, use at own riks" ; 만약 EXPTEST가 정의 되었으면 This is ...을 출력

.ENDIF


(3) 숫자, 문자, 연산자


 오퍼랜드로 상수값을 사용할 때는 반드시 진법 표현을 명확히 해야 한다. 2진수의 경우에는 0b를 앞에 붙여주고(예: 0b00000000), 16진수의 경우에는 0x 혹은 $를 붙여주고, 8진수의 경우 O를 붙여주고, 10진수의 경우에는 아무런 표시도 하지 않는다.

 문자상수값은 반드시 앞뒤에 반드시 따옴표(’)를 붙여준다. 문자열의 경우에는 큰 따옴표를 사용한다.

 오퍼랜드에 사용되는 수식의 연산자에는 산술연산자, 논리 연산자, 비교 연산자, 조건연산자가 있다.

 산술연산자로 +(더하기), -(빼기), /(나누기), *(곱하기), %(나머지가 정수가 되도록 나눈 나누기 연산의 나머지 값을 결과로 내놓는 mode연산), <<(오른쪽으로 이동), >>(왼쪽으로 이동)이 있다.

 논리 연산자로 !(NOT), &&(논리곱), ||(논리합), ~(비트단위 NOT), &(비트단위 AND), |(비트단위 OR), ^(비트단위 exclusive OR)이 쓰인다.

 비교 연산자로 == (동치), != (Not Equal), < (Less Than), <= (Less than or Equal to), > (Greater Than), >= (Greater than or Equal to)가 있다.

 조건 연산자로 아래와 같은 형식으로 사용하며 삼항 연산자로 보통 불린다. 조건식이 참이거나 0이 아니면 식1을 처리하고 거짓이거나 0이면 식2를 처리하라는 의미이다.

변수 = (조건) ? 식1 : 식2;


(4) 함수


 LOW(x) : x의 하위 바이트값을 돌려준다.

 HIGH(x) : x의 2번째 바이트값을 돌려준다.

 BYTE2(x) : x의 2번째 바이트값을 돌려준다.

 BYTE3(x) : x의 3번째 바이트값을 돌려준다.

 BYTE4(x) : x의 4번째 바이트값을 돌려준다.

 LWRD(x) : x의 비트 15~0 값을 돌려준다.

 HWRD(x) : x의 4번째 바이트값을 돌려준다.

 PAGE(x) : x의 비트 16~21값을 돌려준다.

 EXP2(x) : 2^x값을 돌려준다.

 LOG2(x) : log2X값의 정수부를 돌려준다.

 INT(x) : x의 정수부분을 돌려준다.

 FRAC(x) : x의 소수부분을 돌려준다.

 Q7(x) : x를 FMUL/FMULS.FMULSU 명령에 적절한 형태의 부호있는 1바이트 수로 변환한다.

 Q15(x) : x를 FMUL/FMULS.FMULSU 명령에 적절한 형태의 부호있는 1바이트 수로 변환한다.

 ABS(x) : x의 절대값을 돌려준다.

 DEFINED(x) : x라는 심볼이 정의된 경우 1을 돌려준다.