이 블로그는 임베디드 컴퓨터를 이용한 장치(시스템) 개발과 원격제어에 필요한 지식을 공유 하기 위한 블로그 입니다.
실제 개발과 프로그램 예를 위하여 Microchip 사의 ATmega128를 사용한 보드와 Arduino Mega 보드(ATmega2560), Raspberry Pi, Raspberry Pi Pico, WiFi 모듈을 사용 합니다.

avr-asm-addressing-mode

AVR Addressing Mode
  AVR Addressing Mode



  • Microprocessor의 Addressing Mode
    • 일반적인 uP의 Addressing Mode
      • Inherent Addressing Mode
        • Operand Field 를 갖지 않는다.
      • Immediate Addressing Mode
        • Operand Field 에 상수 값이 직접 주어진다.
      • Direct Addressing Mode
        • Operand Field에 실제 Address 가 온다.
      • Indirect Addressing Mode
        • Operand Field에 실제 Address가 저장된 Rg(Index Rg) 또는 Memory의 주소(Pointer)가 온다.
      • Relative Addressing Mode
        • PC 또는 Index Rg 를 기준으로한 상대번지가 온다.
    • AVR uP의 Addressing Mode
      • AVR uP의 Addressing Mode 구분
        • 일반적으로 AVR uP의 Addressing Mode는 다음과 같이 구분한다.

        • Register Direct Addressing Mode
          • 1 Register Direct mode: Operand Field에 하나의 Rregister만 포함되어 있다.
          • 2 Register Direct mode: Operand Field에 두개의 Rregister를 포함하고 있다.
        • I/O Direct Addressing Mode: I/O instructions에 직접 I/O Port의 주소가 포함되어 있다.
        • Data Direct Addressing Mode: Instructions에 직접 Data의 위치(주소)가 포함되어 있다.
        • Data Indirect Addressing Mode: Instructions에 Data의 위치(주소)가 간접적(Pointer를 사용)으로 포함되어 있다.
          • Pre-decrement Indirect mode: Instructions을 실행하기 전에 Pointer 값를 감소(-1) 시킨다.
          • Post-increment Indirect mode: Instructions을 실행한 후에 Pointer 값를 증가(+1) 시킨다.
        • Code Memory Addressing: Code(Instructions) Memory 영역을 Addressing 한다.
      • Register Direct Addressing Mode
        • Register Direct - Single Register, Rd: 하나의 Rregister(Rd)를 Operand로 갖는 Addressing Mode
          • 하나의 Rregister를 Operand로 갖는 Addressing Mode의 예
          • 아래 예는 하나의 Rregister를 Operand로 갖는 Instructions 예 이다.
            • inc R16: 이 명령은 R16 Rg의 값을 1만큼 증가 시키는 명령(R16 ← R16 + 1)으로 Operand 가 R16 Rg(Rd) 하나만 존재한다.
            • clr R22: 명령은 R22 Rg의 값을 0로 Clear 시키는 명령(R22 ← 0)으로 Operand 가 R22 Rg(Rd) 하나 이다.

        • Register Direct - Two Registers, Rd and Rr: 두개의 Rregister(Rd and Rr)를 Operand로 갖는 Addressing Mode
          • 두개의 Rregister를 Operand로 갖는 Addressing Mode의 예
          • 아래 예는 하나의 두개의 Rregister(Rd and Rr) Rregister를 Operand로 갖는 Instructions 예 이다.
            • add R16,R17: 이 명령은 R16 + R17 연산 결과를 R16 Rg에 저장하는 명령(R16 ← R16 + R17)으로 Operand 가 R16, R17 Rg(Rd, Rr) 두개 이다.
            • cp R22,R5: 이 명령은 R22와 R5 Rg의 값을 비교(두 Rg의 값이 동일한 경우 R22 - R5 연산 결과가 0로 됨)하는 명령(Status Register(Z,C,N,V,S,H) ← R22 - R5)이다. Status Register의 Z,C,N,V,S,H Flag 가 (R22 - R5) 연산 결과에 영향을 받는다. 이 명령이 실행된 다음에도 R22 Rg의 값은 변동하지 않는다.
            • mov R0,R1: 이 명령은 R0에 R1 Rg의 값을 복사하는 명령(R0 ← R1)으로 Operand 가 R0, R1 Rg(Rd, Rr) 두개 이다.

      • I/O Direct Addressing Mode
        • I/O Direct Addressing 예
        • 이 Addressing Mode는 위 예와 같이 I/O Port의 주소가 직접 Instruction에 포함되어 있다. I/O Port의 Addressing을 위해 6 Bits 가 활당되어 있기 때문에 I/O Direct Addressing은 최대 64개의 I/O Port Addressing이 가능하다.
          • in R16,PIND: 이 명령은 PIND(PORTD의 Input pin)의 상태를 R16 Rg에 읽어오는 명령(R16 ← PIND)이다.
          • out PORTC,R16: 이 명령은 R16의 값을 PORTC에 출력하는 명령(PORTC ← R16)이다.

          주: 일부 확장된 AVR Microcontrollers는 I/O addressing을 위해 op code에 준비된 64개 주소 내에서 지원할 수 있는 것보다 더 많은 주변 장치가 있다. 이 경우 64 - 255 번지에 확장된 I/O Port는 I/O addressing이 아닌 Data addressing을 사용하여야 한다.


      • Data Direct Addressing Mode
        • Data memory의 주소(16 Bits)가 직접 Instruction의 LSBs에 포함되어 있다. Rd는 Destination Register 이고 Rr는 Source Register 이다.
        • Direct Data Addressing 예
        • 아래 예는 Data memory의 주소(16 Bits)가 직접 Instruction 포함되어 있다.
          • sts 0x1000,R16: 이 명령은 R16 Rg의 값을 Memory 주소 0x1000 번지에 Write 하는 명령(0x1000 ← R16)이다.

      • Data Indirect Addressing Mode
        • Data Indirect Mode
          • Instruction에는 실제 Memory 주소를 직접 포함하지 않고 Memory 주소를 저장하고 있는 Index Rg를 사용하여 간접적으로 Memory 주소를 지정한다. Rd/Rr는 Destination 또는 Source register 이다.
          • Data Indirect Addressing Mode의 예
          • 아래 에는 Data memory의 주소(16 Bits)를 Index Rg를 사용하여 간접적으로 지정하는 예 이다.
            • ld R16, Y: 이 명령은 Y Index Rg에 저장되어 있는 Memory 주소에서 R16 Rg에 Data를 Load하는 명령(R16 ← (Y))이다.
            • st Z, R16: 이 명령은 R16 Rg의 값을 Y Index Rg에 저장되어 있는 Memory 주소에 저장하는 명령((Y) ← R16)이다.
          • Index Rg를 이용한 Indirect addressing의 장점:
            • 1 Word(16 Bits) Instruction으로 64K Data Space를 Addressing 할 수 있다. AVR은 대부분의 Instruction을 1 Word(일부 2 Word Instruction도 사용하지만 2 Word은 실행시 2번 Fetch 하여야함)로 설계한다.
            • Post-Increment 또는 Pre-Decrement를 이용하여 연속적으로 배열된(Array) Data를 효과적으로 Access 할 수 있다. Post-Increment, Pre-Decrement 동작은 Up/Down counter를 사용하여 Hardware로 구현되기 때문에 빠르고 효과적으로 실행된다.

        • Data Indirect with Displacement
          • Instruction에 Memory 주소를 저장하고 있는 Index Rg와 Displacement를 포함하고 있다. Index Rg 값과 Displacement를 더한 값이 실제 주소가 된다.
          • Data Indirect with Displacement Mode 예
          • 아래 예는 Instruction에 Memory 주소를 저장하고 있는 Index Rg와 Displacement를 포함한는 예 이다.
            • ldd R16, Y+0x10: 이 명령은 Memory (Y + 0x10) 번지에 저장되어 있는 Data를 R16 Rg에 Load하는 명령(R16 ← (Y+0x10))이다. 이 명령을 실행한 후 Y Rg의 값은 변동되지 않는다.
            • std Z+0x20, R16: 이 명령은 R16 Rg의 값을 Memory의 (Z+0x20) 번지에 저장하는 명령((Z+0x20) ← R16)이다. 이 명령을 실행한 후 Z Rg의 값은 변동되지 않는다.

        • Pre-Decrement Addressing Mode
          • Index Rg의 값을 1 만큼 감소한 값을 Index 주소로 사용한다.
          • Pre-Decrement Addressing Mode의 예
          • 아래 예는 Index Rg의 값을 1 만큼 감소한 값을 Index 주소로 사용하는 Instruction 예 이다.
            • ld R16, -Z: 이 명령은 Memory (Z - 1) 번지에 저장되어 있는 Data를 R16 Rg에 Load하는 명령(R16 ← (Z-1), Z ← (Z-1))이다. 이 명령을 실행한 후 Z Rg의 값은 Z ← (Z-1) 이 된다.
            • st -Z, R16: 이 명령은 R16 Rg의 값을 Memory의 (Z - 1) 번지에 저장하는 명령((Z-1) ← R16, Z ← (Z-1))이다. 이 명령을 실행한 후 Z Rg의 값은 Z ← (Z-1) 이 된다.

        • Post-Increment Addressing Mode
          • 이 명령이 실행한 다음 Index Rg의 값을 1 만큼 증가 시킨다.
          • Post-Increment Addressing Mode의 예
          • 아래 예는 명령이 실행한 다음 Index Rg의 값을 1 만큼 증가 시키는 Instruction 예 이다.
            • ld R16, Z+: 이 명령은 Z Rg를 Index로 사용하여 Memory에 저장되어 있는 Data를 R16 Rg에 Load하고 Z Rg의 값을 1만큼 증가 시키는 명령(R16 ← (Z), Z ← (Z+1))이다. 이 명령을 실행한 후 Z Rg의 값은 Z ← (Z+1) 이 된다.
            • st Z+, R16: st -Z, R16: 이 명령은 R16 Rg의 값을 Z Rg를 Index로 사용하여 Memory에 저장하는 명령((Z) ← R16, Z ← (Z+1))이다. 이 명령을 실행한 후 Z Rg의 값은 Z ← (Z+1) 이 된다.


      • Program Memory Addressing Mode
        • Program Memory Constant Addressing
          • Z Rg를 Program Memory 영역의 Data를 Load 하기 위한 Index Rg(Constant byte addressing)로 사용한다. LPM 명령인 경우 Z Rg의 상위 15 Bits는 Program Memory Word address를 선택한다. Z Rg의 LSB(Bit 0)는 LSB = 0 인 경우 하위 Byte를 선택하고 LSB = 1 인 경우 상위 Byte를 선택한다. SPM 명령인 경우 LSB를 0로 Clear 하여야 한다. ELPM 명령을 사용하는 경우 RAMPZ Rg를 사용하여 Z Rg를 확장한다.
          • 주: 이 Addressing Mode의 LPM 명령은 Z Rg를 Index Rg로 사용하여 Program Memory 영역의 Data를 Load 하는 경우에 사용한다. Flash Memory에 프로그램을 저장하는 Embedded computer인 경우 SRAM의 Global 변수를 초기화 하기 위한 Data 값을 Program Memory 영역에 저장한다. Global 변수를 초기화 하는 경우 이 Data를 Program Memory 영역으로 부터 SRAM의 Global 변수 영역에 복사한다.

          • Program Memory Constant Addressing의 예
          • 아래 예는 LPM 명령을 이용하여 Program Memory 영역의 Data를 R16 Rg에 Load 하는 Instruction 예 이다.
            • lpm R16, Z: 이 명령은 Z Rg를 Index로 사용하여 Program Memory 영역에 저장되어 있는 Data를 R16 Rg에 Load 하는 명령(R16 ← (Z))이다.

            주: AVR 인 경우 Data Memory는 Byte Addressing 이고 Program Memory 는 Word Addressing 때문에 Program Memory의 주소를 사용하기 전에 Byte Addressing으로 변환하여 Z Rg를 초기화 하여야 한다.


        • Program Memory Addressing with Post-increment
          • Z Rg를 Index Rg를 Program Memory 영역의 Data를 Load 하고 Z Rg의 값을 1 만큼 증가 시킨다. LPM 명령인 경우 Z Rg의 상위 15 Bits는 Program Memory Word address를 선택한다. Z Rg의 LSB(Bit 0)는 LSB = 0 인 경우 하위 Byte를 선택하고 LSB = 1 인 경우 상위 Byte를 선택한다.
          • Program Memory Addressing with Post-increment의 예
          • 아래 예는 LPM 명령을 이용하여 Program Memory 영역의 Data를 R16 Rg에 Load 하고 Z Rg의 값을 1 만큼 증가 시키는 Instruction 예 이다.
            • lpm R16, Z+: 이 명령은 Z Rg를 Index로 사용하여 Program Memory 영역에 저장되어 있는 Data를 R16 Rg에 Load 하고 Z Rg의 값을 1만큼 증가 시키는 명령(R16 ← (Z), Z ← (Z+1))이다.

            주: AVR 인 경우 Data Memory는 Byte Addressing 이고 Program Memory 는 Word Addressing 때문에 Program Memory의 주소를 사용하기 전에 Byte Addressing으로 변환하여 Z Rg를 초기화 하여야 한다.


        • Direct Program Addressing, JMP and CALL
          • JMP 또는 CALL 명령에 포힘된 주소로 직접 JMP 또는 CALL 명령을 실행한다.
          • Direct Program Addressing의 예
          • 아래 예는 직접 Instruction에 포함된 번지로 Program이 JMP 또는 CALL 명령을 실행하는 Instruction 예 이다.
            • jmp 0x1000: 이 명령은 직접 0x1000 번지로 JMP 하는 명령(PC ← 0x1000)이다.
            • call 0x1000: 이 명령은 직접 0x1000 번지를 CALL 하는 명령(PC ← 0x1000, (SP) ← (PC+1))이다.

        • Indirect Program Addressing, IJMP and ICALL
          • Z Rg에 저장된 번지로 JMP 또는 CALL 명령을 실행한다.
          • Indirect Program Addressing의 예
          • 이 Addressing Mode는 위 예와 갖이 Jmp 또는 Call 번지를 Z Rg에 저장하고 이 값을 Program counter에 복사하여 Jmp 또는 Call 명령을 실행한다.
            • ijmp: 이 명령은 Z Rg에 저장된 번지로 Jmp 하는 명령이다.
            • icall: 이 명령은 Z Rg에 저장된 번지를 Call 하는 명령이다.

        • Relative Program Addressing, RJMP and RCALL
          • 이 Addressing Mode는 현재 Program counter 값을 기준으로 상대 번지를 지정한다. Jmp 또는 Call 하는 번지가 현재 Program counter에 가까이 있는 경우(-2048 to 2047) 사용할 수 있다.
          • 주: Relative Program Addressing은 프로그램의 시작 번지가 바뀌어도 프로그램의 상대 번지는 변동하지 않기 때문에 프로그램의 재 배치에 유리하다.

          • Relative Program Addressing의 예
          • 이 Addressing Mode는 위 예와 갖이 (PC + k + 1) 번지로 Jmp 또는 Call 명령을 실행한다.
            • rjmp: 이 명령은 현재 Program counter에 k+1 값(-2048 to 2047)을 더한 상대 번지(PC ← PC+k+1)로 Jmp 한다.
            • rcall: 이 명령은 현재 Program counter에 k+1 값(-2048 to 2047)을 더한 상대 번지(PC ← PC+k+1)로 Call 하는 명령이다.

    • AVR Addressing Mode 관련 페이지 보기