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

asm-debuger-instruction-processor

Debugger를 이용한 Instruction Set과 Microprocessor의 이해
  Debugger를 이용한 Instruction Set과 Microprocessor의 이해



  • Microchip Studio 환경에서 Debugger 사용하기
    • 작성한 프로그램에 오류가 있는 경우 이를 발견 하고, 정정 하기 위하여 AVR Simulator 를 이용한 Debugging 이 필요 하다.

      참고자료: "Atmel Studio USER GUIDE" 4. Debugging

    • "Assembly Language Programming Basic"를 참고하여 Debugging에 사용할 Program을 작성한다.
    • Simulator 설정: Project → (Project name) Properties... 를 실행하면 Property 창이 열린다. 이 창에서 Tool을 선택하고 “Selected debugger/programmer” Box 에서 Simulator 를 선택한다.
    • Debugging 하려는 .asm 파일(대부분의 경우 main.asm) 창을 선택하고 Debug → Start Debugging and Break을 실행 하면 Simulator 가 실행 되고, Debugging 에 필요한 창이 열린다.
      • Debugging에 자주 사용되는 창 예

        Source code 창

        Processor Status 창

        I/O 창


      • Source code 창: 프로그램 실행을 Trace 하기 위한 Source Code 를 보여 준다.
      • Processor Status 창: Debug → Windows → Processor Status 를 실행하면 Processor Status 창이 열린다. 이 창에는 Debugging 이 진행 되는 동안 Processor 의 상태(uP 내 모든 Rg의 상태)를 보여 준다.
      • I/O 창: Debug → Windows → I/O 를 실행하면 I/O 창이 열린다. 이 창에는 Processor 에 포함된 I/O 장치의 상태가 표시 된다.
      • Debug → Windows 에서 기타 Debugging 에 도움이 되는 Windows 를 열 수 있다.
        • Memory Window
        • Watch Window
        • Disassembly Window
        • Register Window 등
    • 자주 사용하는 Debugger 기능
      • Start Debugging and Break(Alt+F5): Debugger를 시작하고 프로그램의 첫 번째 명령문에서 부터 Debugging 할 수 있도록 첫 번째 명령문에서 중단한다.
      • Start Debugging(F5): 디버거를 시작하고 프로그램을 실행한다. 디버그 모드에서 중지된 경우에는 실행을 재개한다.
      • Stop Debugging(Ctrl+Shift+F5): Debug session을 중지 및 종료하고 프로그램 편집 모드로 돌아간다.
      • Restart: Debugger를 다시 시작하고 프로그램을 다시 로드한다.
      • Reset(Shift+F5): 프로그램의 시작 위치를 첫 번째 명령문으로 재 설정(Program counter 와 Cycle Counter를 0로 설정)한다.
      • Continue(F5): Break 위치에 도달할 때 까지 프로그램을 실행한다.
      • Step Into(F11): 하나의 명령을 실행한다. 디스어셈블리 수준에서 하나의 어셈블리 수준 명령어가 실행되고, 그렇지 않으면 하나의 소스 수준 명령어가 실행된다.
      • Step Over(F10): Step Into와 유사하게 Step Over는 하나의 명령을 실행한다. 그러나 명령어에 함수 호출/서브루틴 호출이 포함되어 있으면 함수/서브루틴도 함께 실행한다. Step Over 중에 사용자 Breakpoint(중단점)가 발생하면 실행이 중지된다.
      • Step Out(Shift+F11): 현재 함수가 완료될 때까지 실행을 계속한다. Step Over 중에 사용자 Breakpoint(중단점)를 만나면 실행이 중지된다. 프로그램이 최상위 수준에 있을 때 Step Out 명령이 실행되면 프로그램은 Breakpoint(중단점)에 도달하거나 사용자가 중지할 때까지 계속 실행된다.
      • Breakpoint(중단점)
        • Assembly Code 좌측 여백에 작은 적색 동그라미로 표시 된다
        • 설정된 Breakpoint에서 프로그램 실행이 중지된 경우에는 적색 동그라미 안에 작은 우측 화살표가 함께 표시된다.
        • Assembly Code 좌측 여백에서 마우스 좌측 버튼을 클릭하면 Breakpoint Enable과 Disable 상태가 Toggle(현재 Breakpoint 가 설정되지 않은 상태인 경우 Breakpoint 가 설정되고, Breakpoint 가 설정된 상태인 경우에는 Breakpoint 가 해제됨) 된다.

  • AVR128 Processor Instruction
    • 참고자료: "AVR ASM Instructions"

      참고자료: "AVR Instruction Set Manual" 4. Instruction Set Summary, 5.ADC – Add with Carry - 128.XCH – Exchange

      참고자료: "ATmega128_Instructions.pdf" ATmega128_Instructions.pdf

      여기서는 자주 사용하는 Instructions에 대하여만 설명한다.

    • Data Transfer Instructions
      • 두 Register 사이의 Data Transfer 명령 예
        • r16 Rg에 상수를 Load 하여 초기화 하고, Loop 내에서 r17에 r16을 복사하고 r16의 값을 1 만큼 증가 시킨 다음 다시 r17에 r16을 복사하는 프로그램 예
        • 실험을 위한 준비
          • Microchip Studio를 실행하고 실험에 사용할 Project를 생성한다.
          • Debugging에 사용할 Simulator를 설정한다.
          • 프로그램 편집 창(main.asm)에 위 Code를 복사하고 저장한다.
        • 실험 방법
          • Start Debugging and Break(Alt+F5) 명령을 실행하면 Debugger 가 실행되고 Microchip Studio가 Debugging 모드로 변환된다. Debugging 모드에서는 프로그램 편집 창(main.asm)은 Debugging 모드로 변환되고 설정 상태에 따라 Debugging에 필요한 Processor Status 창, I/O 창, Memory 창, Watch 창 등이 열린다.
          • 이 예에서는 "Processor Status 창"이 필요하기 때문에 만약 이 창이 자동으로 열리지 않은 경우에는 Debug → Windows → Processor Status 명령을 실행하여 Processor Status 창을 Open 한다.
          • Step Into(F11) 명령을 실행한다. Step Into(F11) 명령을 실행하면 아래 예와 같이 "Debugging source code 창"에는 다음 실행될 Code의 왼쪽에 노랑색 화살표가 표시되고 Code 가 노랑색으로 표시된다.
          • "Processor Status 창"의 현재 Program Counter 값과 Cycle Counter 값이 적색(이전 명령의 실행 결과 값이 변동된 경우 적색으로 표시됨)으로 표시된다. Program Counter 값과 Cycle Counter 값은 명령이 실행될 때 마다 변동하기 때문에 언제나 적색으로 표시된다.
          • "Processor Status 창"을 Scroll down 하여 R16, R17 Rg(아래 그림에서는 아래 부분이 절단되어 R01 Rg 까지만 보인다. "Processor Status 창" Scroll down 하면 R16, R17 Rg의 상태를 확인할 수 있다.)의 변동을 확인한다. Rg의 값도 이전 명령의 실행 결과 값이 변동된 경우 적색으로 표시된다.
          • Step Into(F11) 명령을 반복 실행하며 Program Counter 값과 R16, R17 Rg의 값이 바르게 변동하는지 확인한다.
          • 주: LDI와 같이 일부 명령에서는 Rd 또는 Rr를 R16 - R31 범위의 Rg 만 사용할 수 있기 때문에 프로그램 예에서 R16, R17 Rg를 사용하였다.

            주: 기타 LD, LDD, LDI, LDS, LPM, ST 명령을 사용하는 Code를 작성하여 실험하여보기 바람.

            Debugging source code 창 예

            Processor Status 창 예

      • Register와 Memory 사이의 Data Transfer 명령 예
        • Data Memory에 Global variable 저장 위치를 설정(DSEG)하고, Pointer Rg(Z,Y)를 이용하여 Data를 Read/Write 하는 프로그램 예
        • 실험을 위한 준비
          • Microchip Studio를 실행하고 실험에 사용할 Project를 생성한다.
          • Debugging에 사용할 Simulator를 설정한다.
          • 프로그램 편집 창(main.asm)에 위 Code를 복사하고 저장한다.
        • 실험 방법
          • Start Debugging and Break(Alt+F5) 명령을 실행하면 Debugger 가 실행되고 Microchip Studio가 Debugging 모드로 변환된다. Debugging 모드에서는 프로그램 편집 창(main.asm)은 Debugging 모드로 변환되고 설정 상태에 따라 Debugging에 필요한 Processor Status 창, I/O 창, Memory 창, Watch 창 등이 열린다.
          • 이 예에서는 "Processor Status 창"과 Memory 창이 필요하기 때문에 만약 이 창이 자동으로 열리지 않은 경우에는 Debug → Windows → Processor Status 명령과 Debug → Windows → Memory 명령을 실행하여 Processor Status 창과 Memory 창을 Open 한다.
          • Memory 창의 memory 선택 Box에서 dataIRAM을 선택하면 Address Box에 0x0100,data(DSEG의 100번지 부터 Memory 창에 표시됨) 가 표시된다.
          • Step Into(F11) 명령을 실행하며 "Processor Status 창"에서 Z Rg와 Y Rg에 data_x 번지(0x0100) 와 data_y번지(0x0101)가 바르게 설정되는지 확인한다. Z Rg와 Y Rg는 data_x 번지(0x0100) 와 data_y번지(0x0101)의 Pointer로 사용된다.
          • st Z, r16 명령이 실행되면 r16의 값이 data_x 번지(0x0100)에 Write 된다. 이 때 Memory 창의 0x0100의 값이 r16 값과 일치하는지 확인한다.
          • ls r16, Z 명령이 실행되면 data_x 번지(0x0100)의 값이 r16에 Load 된다. 이 때 r16 값이 Memory 창의 0x0100 값과 일치하는지 확인한다.
          • st Y, r16 명령이 실행되면 r16의 값이 data_y 번지(0x0101)에 Write 된다. 이 때 Memory 창의 0x0101의 값이 r16 값과 일치하는지 확인한다.
          • Step Into(F11) 명령을 계속 실행하며 data_x 번지(0x0100)의 값과 data_y 번지(0x0101)의 값이 바르게 변동하는지 확인한다.
          • Memory 상태을 확인할 수 있는 Memory 창 예


      • IN/OUT 명령 예
        • 참고자료: "ATmega128 I/O Port - ASM"

        • IN/OUT Port를 설정하고 Input port(PD0, PD1)의 상태를 읽어 Output port(PF0, PF1)에 Write 하는 프로그램 예
        • 실험을 위한 준비
          • Microchip Studio를 실행하고 실험에 사용할 Project를 생성한다.
          • Debugging에 사용할 Simulator를 설정한다.
          • 프로그램 편집 창(main.asm)에 위 Code를 복사하고 저장한다.
        • 실험 방법
          • Start Debugging and Break(Alt+F5) 명령을 실행하면 Debugger 가 실행되고 Microchip Studio가 Debugging 모드로 변환된다. Debugging 모드에서는 프로그램 편집 창(main.asm)은 Debugging 모드로 변환되고 설정 상태에 따라 Debugging에 필요한 Processor Status 창, I/O 창, Memory 창, Watch 창 등이 열린다.
          • 이 예에서는 "Processor Status 창"과 "I/O 창"이 필요하기 때문에 만약 이 창이 자동으로 열리지 않은 경우에는 Debug → Windows → Processor Status 명령과 Debug → Windows → I/O 명령을 실행하여 Processor Status 창과 I/O 창을 Open 한다.
          • Step Into(F11) 명령을 실행한다. Step Into(F11) 명령을 실행하면 위 "두 Register 사이의 Data Transfer 명령 예"와 같이 "Debugging source code 창"에는 다음 실행될 Code의 왼쪽에 노랑색 화살표가 표시되고 Code 가 노랑색으로 표시된다.
          • "Processor Status 창"의 현재 Program Counter 값과 Cycle Counter 값이 적색(이전 명령의 실행 결과 값이 변동된 경우 적색으로 표시됨)으로 표시된다. Program Counter 값과 Cycle Counter 값은 명령이 실행될 때 마다 변동하기 때문에 언제나 적색으로 표시된다.
          • "Processor Status 창"을 Scroll down 하여 R16 Rg의 값의 변동을 확인한다. Rg의 값도 이전 명령의 실행 결과 값이 변동된 경우 적색으로 표시된다.
          • I/O 명령(DDRD, PORTD, PIND, DDRF, PORTF에 영향을 주는 명령)이 실행된 다음에는 I/O 창에서 영향을 받은 PORT를 선택하여 PORT의 상태가 바르게 변동하는지 확인한다.
          • in r16, PIND 명령이 실행되기 전에 아래 "PIND의 입력 설정 상태를 보여주는 I/O 창 예"와 같이 PD0는 Set 하고 PD1은 Clear 한다.
          • Step Into(F11) 명령을 실행하며 Program Counter 값과 R16 Rg의 값이 바르게 변동하는지 확인한다.
          • sts PORTF, r16 명령이 실행된 다음 I/O 창에서 아래 "PORTF에 출력된 결과를 보여주는 I/O 창 예"와 같이 PF0는 Set 되고 PF1은 Clear 되었는지 확인한다.
          • Loop 내에서 in r16, PIND 명령이 실행되기 전에 PIND의 입력 설정(PD0, PD1)을 변경하며 실험을 반복한다.
          • 주: PORTF는 확장된 I/O Port이기 때문에 PORTF에 출력하는 경우 OUT 명령 대신 sts 명령을 사용하여야 한다.

            PIND의 입력 설정 상태를 보여주는 I/O 창 예

            PORTF에 출력된 결과를 보여주는 I/O 창 예


    • ALU Instructions
      • Arithmetic instructions
        • Global variable(data_x, data_y, data_z)을 설정하고, Program Memory에 저장된 상수를 읽어 변수(data_x, data_y)를 초기화하고, 두 변수의 값을 읽어 Add 한 다음 변수(data_z)에 Write 하는 프로그램 예
        • 실험을 위한 준비
          • 윗 Project 예를 참고하여 Project를 생성하고, 프로그램 편집 창(main.asm)에 위 Code를 복사하고 저장한다.
        • 실험 방법
          • Start Debugging and Break(Alt+F5) 명령을 실행하고, Debugger 가 실행되면 Debugging에 필요한 Processor Status 창과 Memory 창이 열려있는지 확인한다.
          • Memory 창의 memory 선택 Box에서 prog FLASH을 선택하면 Address Box에 Program memory address 0x000000,prog(CSEG의 0번지 부터 Memory 창에 표시됨) 가 표시된다.
          • Program memory 0x000000 번지 부터 16진법 숫자로 Code가 저장되어 있고 0x00001E 번지 부터 Data Memory의 초기화에 필요한 Data 03 과 04 가 저장되어 있는지 확인한다.
          • Memory 창의 memory 선택 Box에서 dataIRAM을 선택하면 Address Box에 0x0100,data(DSEG의 100번지 부터 Memory 창에 표시됨) 가 표시된다.
          • Step Into(F11) 명령을 실행하며 "Processor Status 창"과 Memory 창의 해당 Rg와 Memory 번지의 내용이 예상하는 프로그램 결과와 일치하는지 확인한다.
          • 주: Data memory(RAM)를 초기화 하기 위한 Data는 Program을 저장하는 Flash Memory에 저장하고, Data memory를 초기화 과정에서 Program memory에 저장된 Data를 읽어 Data memory를 초기화 한다. Program memory의 주소는 Word(16Bit) 단위 주소이기 때문에 Byte 단위 Data를 읽기 위하여는 Byte Address으로 변환하여 사용하여야 한다.

      • Logic instructions
        • AND, OR 연산을 실행하는 프로그램 예
        • 실험을 위한 준비
          • 윗 Project 예를 참고하여 Project를 생성하고, 프로그램 편집 창(main.asm)에 위 Code를 복사하고 저장한다.
        • 실험 방법
          • Start Debugging and Break(Alt+F5) 명령을 실행하고, Debugger 가 실행되면 Debugging에 필요한 Processor Status 창이 열려있는지 확인한다.
          • Step Into(F11) 명령을 실행하며 "Processor Status 창"의 내용이 예상하는 프로그램 결과와 일치하는지 확인한다.
    • Branch Instructions
      • Compare 명령: Compare 명령은 두 값을 비교하여 그 결과에 따라 Status Register의 해당 Bit를 Set 또는 Clear 한다.
        • Compare, Increment, Decrement을 실행하여 Status Register의 해당 Bit를 Set 또는 Clear 프로그램 예
        • 실험을 위한 준비
          • 윗 Project 예를 참고하여 Project를 생성하고, 프로그램 편집 창(main.asm)에 위 Code를 복사하고 저장한다.
        • 실험 방법
          • Start Debugging and Break(Alt+F5) 명령을 실행하고, Debugger 가 실행되면 Debugging에 필요한 Processor Status 창이 열려있는지 확인한다.
          • Step Into(F11) 명령을 실행하며 "Processor Status 창"의 내용(r16, r17, Status Register의 Zero flag)이 예상하는 프로그램 결과와 일치하는지 확인한다.
      • Branch Instructions
        • Branch Instruction을 이용하여 Loop를 제어하는 프로그램 예
        • r16을 3으로 초기화 하고, r16이 Zero 가 될 때 까지 r16를 1씩 감소 시키며 Loop1을 반복한다. r16이 Zero 가 되면 r16이 3이 될 때 까지 r16를 1씩 증가 시키며 Loop2을 반복한다.

        • 실험을 위한 준비
          • 윗 Project 예를 참고하여 Project를 생성하고, 프로그램 편집 창(main.asm)에 위 Code를 복사하고 저장한다.
        • 실험 방법
          • Start Debugging and Break(Alt+F5) 명령을 실행하고, Debugger 가 실행되면 Debugging에 필요한 Processor Status 창이 열려있는지 확인한다.
          • Step Into(F11) 명령을 실행하며 "Processor Status 창"의 내용(r16, Status Register의 Zero flag, Branch 명령 결과)이 예상하는 프로그램 결과와 일치하는지 확인한다.

  • Stack Operation과 Subroutine call
    • Stack Operation
        • Stack Operation(push, pop)을 이해를 위한 프로그램 예
        • Global variable data_x1 - data_x4를 1,2,3,4로 초기화 하고, Stack Operation(push, pop)을 이용하여 4,3,2,1 순서로 재 배열하는 프로그램 예

        • 실험을 위한 준비
          • 윗 Project 예를 참고하여 Project를 생성하고, 프로그램 편집 창(main.asm)에 위 Code를 복사하고 저장한다.
        • 실험 방법
          • Start Debugging and Break(Alt+F5) 명령을 실행하고, Debugger 가 실행되면 Debugging에 필요한 Processor Status 창과 Memory 창이 열려있는지 확인한다.
          • Step Into(F11) 명령을 실행하며 "Processor Status 창"의 내용(Stack Pointer, Z Register, r16, r17, Status Register의 Zero flag, Branch 명령 결과)과 Memory 창의 내용(data_xi(0x0100 - 0x0103 번지), Stack(0x0113 - 0x0110 번지))이 예상하는 프로그램 결과와 일치하는지 확인한다.
          • Memory 창의 memory 선택 Box에서 dataIRAM을 선택하면 Address Box에 0x0100,data(DSEG의 100번지 부터 Memory 창에 표시됨) 가 표시된다.
          • 주: Stack에 Data은 높은 번지로 부터 낮은 번지로 순차적으로 저장되기 때문에 일반적으로 Stack은 RAM Memory의 가장 높은 번지에 위치 시키는 것이 일반적이다. 그러나 이 프로그램 예에서는 Memory 창의 같은 위치에서 Data와 Stack에 저장되는 값을 비교할 수 있도록 0x0113 번지에 Stack을 위치하도록 하였다.

    • Subroutine call
      • Global variable(data_x, data_y, data_z)을 설정하고, 변수(data_x, data_y)를 초기화하고, Subroutine에서 두 변수의 값을 읽어 Add 한 다음, 변수(data_z)에 Write 하는 프로그램 예
      • 실험을 위한 준비
        • 윗 Project 예를 참고하여 Project를 생성하고, 프로그램 편집 창(main.asm)에 위 Code를 복사하고 저장한다.
      • 실험 방법
        • Start Debugging and Break(Alt+F5) 명령을 실행하고, Debugger 가 실행되면 Debugging에 필요한 Processor Status 창과 Memory 창이 열려있는지 확인한다.
        • Memory 창의 memory 선택 Box에서 dataIRAM을 선택하면 Address Box에 0x0100,data(DSEG의 100번지 부터 Memory 창에 표시됨) 가 표시된다.
        • Step Into(F11) 명령을 실행하며 "Processor Status 창"의 내용(Stack Pointer, Z Register, r16, r17, Status Register의 Zero flag, Call 명령과 ret 명령 결과)과 Memory 창의 내용(data_xi(0x0100 - 0x0103 번지), Stack(0x0113 - 0x0110 번지))이 예상하는 프로그램 결과와 일치하는지 확인한다.
        • 주: Call 명령이 실행될 떼 Program Counter 값의 변동과 Return 번지가 Stack에 바르게 저장되는지 확인한다. 또한 ret 명령에 따른 Program Counter 값과 Stack Pointer의 값이 예상한 결과와 일치하는지 확인한다.



  • Debugger를 이용한 Instruction Set과 Microprocessor의 이해 관련 페이지 보기