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

asm-avr-c-asm-mixing-program

C 프로그램과 Assembly 언어 프로그램을 Mixing한 프로그램
  C 프로그램과 Assembly 언어 프로그램을 Mixing한 프로그램 개발 - ASM


  • C 프로그램과 Assembly 언어 프로그램을 Mixing한 프로그램 개발
    • Microchip(AVR) Studio 에서 사용 하는 Assembler
    • Microchip(AVR) Studio에서는 GCC Assembler와 AVR Assmbler를 사용 한다.

      GCC Assembler는 GCC에 포함되어 있는 Assembler 이기 때문에 GCC C와 Assembly 언어 프로그램을 Mixing한 프로그램 개발에는 GCC Assembler를 사용 한다.

      • GCC Assembler : GCC 사용 환경에서(WinAVR 등 을 사용 하는 경우) 사용 할 수 있다.
      • GCC Assembler는 GCC(GNU C Compiler)에 포함 되어 있는 Assembler 이기 때문에 GCC c와 Assembly Program을 Mixing 한 프로그램을 작성 하기에 적합하다.

      • AVR Assembler : Microchip(AVR) Studio에서 사용 할 수 있다.
      • AVR Assembler는 AVR microcontroller를 설계하고 Microchip Studio를 제공하는 Atmel(현 Microchip)에서 제공 하는 Assembler 이기 때문에 Microchip Studio의 기능을 잘 활용할 수 있는 장점이 있다.

      • GCC Assembler와 AVR Assembler의 차이
        • GCC Assembler 를 사용 하는 경우
          • Assembly Language Program은 .S Extension 을 갖는다.
          • C Language Program은 .c Extension 을 갖는다.
          • GCC Assembler는 GCC C/C++와 같은 Preprocessor을 사용 한다. #include, #define 등을 사용 할 수 있다.
          • AVR Studio4 에서 사용하는 GCC Assembler(WinAVR에 포함되어 있음)는 Data Segment 영역(Global variable)을 자동으로 초기화 하였으나, 현재 사용하는 Microchip Studio(AVR Studio7)에서는 자동으로 초기화를 하지않기 때문에 초기화가 필요한 경우에는 Code Segment 내에 초기화에 필요한 Data를 포함 시키고, 이 값을 Data Segment 영역으로 복사하여 주는 초기화 프로그램을 작성 하여 실행 하여야 한다.
        • Atmel AVR Assembler 를 사용 하는 경우
          • Assembly Language Program은 .asm Extension 을 갖는다.
          • Atmel AVR Assembler는 Data Segment 영역(Global variable)을 초기화 하지 않는다. 만약 초기화가 필요한 경우에는 Code Segment 내에 초기화에 필요한 Data를 포함 시키고, 이 값을 Data Segment 영역으로 복사하여 주는 초기화 프로그램을 작성 하여 실행 하여야 한다.
        • 기타 차이 예:
        • 참고자료: Microchip Studio(AVR Studio7) 환경에서 AVR Assembly Program 작성 하기

          참고자료: AVR Assembler

            GCC Assembler
            hi8
            lo8
            .asciz “hello”
            .section .data
            .section .text
            <avr/io.h>
            Atmel AVR Assembler
            high
            low
            .db “hello”,0
            .dseg
            .cseg
            “m128def.inc”

    • C 프로그램과 Assembly 언어 프로그램을 Mixing한 프로그램 개발을 위한 Project 만들기
      • Microchip Studio 를 실행한다.
      • File → New → Project를 실행하고 New Project 창에서 “C/C++ → GCC C Executable Project C/C++”을 선택한다.
      • New Project 창 예
      • Project name Box에 Project name 입력 한다.
      • Location Box에 Browse... 버튼을 사용하여 Project 폴더를 설정한다.
      • Create directory for solution Box를 Check 한다.
      • “OK”를 클릭한다.
      • Device Selection 창에서 Device를 선택(예: ATmega128, ATmega128A는 GCC Assembler에서 지원 하지 않는다.)하고 “OK”를 클릭하면 Project가 생성되고 main.c 파일이 열린다. Assembly Source File은 아직 하나도 만들어 지지 않은 상태 임.
      • main.c에 c 프로그램을 작성한다.
      • 새 c Source File 추가하기: Solution Explorer 창에 있는 project_name 위에서 마우스 우측 버튼을 클릭하고 Add → New Item… 을 클릭하면 Add New Item 창이 열린다. 이 창에서 C/C++ → C File을 선택한다. Name Box에 File name을 입력하고 Add 버튼을 클릭하면 새 C Flie이 Project 내에 추가된다. 추가된 파일을 편집하여 프로그램을 작성한다.
      • 새 Assembly Language Source File 추가하기: Solution Explorer 창에 있는 project_name 위에서 마우스 우측 버튼을 클릭하고 Add → New Item… 을 클릭하면 Add New Item 창이 열린다. 이 창에서 C/C++ → Assembly File을 선택한다. Name Box에 File name을 입력하고 Add 버튼을 클릭하면 새 Assembly Flie이 Project 내에 추가된다. 추가된 파일을 편집하여 프로그램을 작성한다.
      • 주: 이미 작성된 Source File(c or Assembly Language Source File)이 있는 경우에는 Solution Explorer 창에 있는 project_name 위에서 마우스 우측 버튼을 하고 Add → Existing Item… 을 클릭하면 추가할 파일을 팀색하기 위한 창이 열린다. 이 창에서 추가할 파일을 탐색하여 추가한다.

      • 새 c 또는 Assembly Language Source File을 추가하기 위한 "Add New Item" 창 예

    • C와 Assembly Language을 혼합 한 Program에서 Register의 사용
    • C Program에서 Assembly 언어로 작성된 Subroutine을 Call 하는 경우 호환성을 위하여 C Compiler에서 Rg를 사용 하는 규칙을 아는 것이 중요하다.

      • C Compiler에서 Register 사용
        • r0 : Temporary Register 로 사용 한다. Assembly 언어로 작성된 프로그램에서 C 함수를 호출하는 경우 이 Rg는 Assembly Code 내에서 Save 되고, Restore 되어야 한다. 그러나, Compiler에 의하여 생성된 Interrupt Routine은 r0 Rg를 Save 하고 Restore 한다.
        • r1 : Compiler는 이 Rg의 값이 zero라고 가정하기 때문에 프로그램 초기화 과정에서 이 Rg를 Zero로 Clear 하여야 한다.
        • r2 – r17, r28, r29 : 이 Rg 들은 Compiler에 의하여 생성된 Code에서 임시 저장 장소로 이용 되기 때문에 Assembly Code에서 이 Rg가 사용 되고, Compiler에 의하여 생성된 Code에서 Call 된다면 이 Rg들은 Assembly Code 내에서 Save 되고, Restore 되어야 한다. Y Index Register(r29:r28) 는 Function의 Stack Frame Pointer로 사용 된다.
        • r18 – r27, r30, r31 : 이 Rg 들도 Assembly Code에서 사용 되고, Assembly Code에서 Compiler에 의하여 생성된 Code를 Call 하여야 한다면 Assembly Code 내에서 Save 되고, Restore 되어야 한다.

    • Function을 Call 할 때 Argument Passing과 Return Values
      • Register를 이용한 Arguments Passing
        • 미리 약속된 Rg를 사용 하여 Function Arguments를 Passing 한다.
        • Function Arguments는 좌측에서 우측으로 배치 되어 있고, r25 로부터 r8 까지 할당 된다.
        • 모든 Arguments는 짝수 개의 Rg에 할당 된다. C Compiler 가 MOVW 명령을 사용 하여 Word 단위로 Data를 처리 하도록 하여 보다 효과적으로 데이터를 처리 할 수 있다.
        • 만약 보다 더 많은 Arguments를 Pass 하여야 하는 경우에는 나머지 Arguments는 Stack을 이용 하여 Pass 한다.
        • Rg를 이용 한 Arguments Passing 예
        • Void lcd_cursor_xy(uint8_t x, uint8_t y);

          lcd_cursor_xy(2,3);

          위 c 함수는 아래와 같이 Compile 된다.

      • Stack을 이용한 Arguments Passing
        • 일부 함수(Printf, scanf, etc)는 모든 Arguments를 Stack을 이용하여 Pass 한다.
        • 이 때 char parameters는 Integer(Word)로 확장 되어 Pass 된다.
        • Parameters는 오른 쪽에 있는 Arguments 부터 Stack에 Push 된다.
        • 8-bit 변수는 16-bit로 확장 되어 Pass 된다.
        • 이 때 상위 8-bit는 zero로 set 된다.
      • Return Values
        • 8-bit 값은 r24을 이용 하여 Return 된다.
        • 16-bit 값은 r25:r24을 이용 하여 Return 된다.
        • 32-bit 값은 r25:r24:r23:r22을 이용 하여 Return 된다.
        • 64-bit 값은 r25:r24:r23:r22:r21:r20:r19:r18을 이용 하여 Return 된다.

  • C 프로그램과 Assembly 언어 프로그램을 Mixing한 프로그램 예
    • GCC c 프로그램에서 Assembly Function을 이용 하는 예
    • GCC c 프로그램에서 3개의 정수를 더하는 Assembly Function을 call 하는 프로그램 예이다. 이해를 쉽게하기 위하여 asm_add 함수만 Assembly 언어로 작성하였다.

      • GCC c main() 프로그램 예
      • Assembly 언어로 작성된 asm_add 함수 프로그램 예

      • 실험을 위한 준비
        • 컴퓨터(USB --> UART(RS232) 변환 모듈)의 RXD와 Atmega128의 TXD0(PE1)를 연결한다.
        • 컴퓨터(USB --> UART(RS232) 변환 모듈)의 TXD와 Atmega128의 RXD0(PE0)를 연결한다.
        • 주: 컴퓨터에 Serial Port가 없는 경우 "USB --> UART(RS232) 변환 모듈"를 사용(USB Port를 Serial Port로 변환)하여 연결한다. 개발보드에 따라서는 "USB --> UART(RS232) 변환 모듈"을 내장하고 있는 경우가 많기 때문에 본인이 사용하는 개발보드에서 확인 하여야 한다.

          참고자료: USB - Serial 변환 모듈

        • 컴퓨터(USB --> UART(RS232)의 GND와 Atmega128의 GND를 연결한다. "USB --> UART(RS232) 변환 모듈"를 사용하는 경우 변환 모듈의 GND와 Atmega128의 GND를 연결한다.
      • 실험 방법
        • GCC_c_call_asm_func_3v_add_uart.zip 파일을 Download하여 압축을 해제한다.
        • Build → Build Solution 를 실행 하면 프로그램이 Build 되어 GCC_c_call_asm_func_3v_add_uart.hex 파일이 생성된다.
        • GCC_c_call_asm_func_3v_add_uart.hex 파일을 Target Board에 Upload 하고 프로그램을 실행한다.
        • 주: 모니터 프로그램(예: OC-Console, Tera Term)과 hex 파일을 Target Board에 Upload 하는 프로그램이 동일한 Port를 사용하기 때문에 모니터 프로그램을 중지하고 Upload를 실행하여야 한다.

        • 모니터 프로그램(예: OC-Console, Tera Term)을 설치(이미 설치되어 있는 경우에는 실행만 하면됨)하고 실행 한다.
        • 모니터 프로그램에서 필요한 설정(Serial Port와 Baudrate 등을 설정)을 한다.
        • 실험:
          • 개발 보드의 Reset SW를 누르면 모니터에 "Assembly Function Call Testing" 메세지가 출력되고,
          • 아래 줄에 "Sum = 39" 가 출력된다.
          • 이 프로그램은 프로그램을 간단히 하기 위하여 한번만 실행되고 종료되도록 하였다. Reset 버튼을 누르면 프로그램이 다시 한번 실행된다.

    • Assembly 프로그램에서 GCC c 함수를 이용 하는 예
    • Assembly 프로그램에서 3개의 정수를 더하는GCC c Function을 call 하는 프로그램 예이다. 이해를 쉽게하기 위하여 add 함수를 c 언어로 작성하였다.

      • Assembly main() 프로그램 예
      • GCC c 언어로 작성된 add 함수 프로그램 예

      • 실험을 위한 준비
      • 실험 방법
        • GCC_asm_call_c_func_3v_add.zip 파일을 Download하여 압축을 해제한다.
        • Build → Build Solution 를 실행 하면 프로그램이 Build 되어 GCC_asm_call_c_func_3v_add.hex 파일이 생성된다.
        • GCC_asm_call_c_func_3v_add.hex 파일을 Target Board에 Upload 하고 프로그램을 실행한다.
        • 실험:
          • 프로그램이 시작되면 연산 결과의 하위 Byte 값이 LED Array(8Bits)에 출력된다.
          • PD0 Push button switch를 누르면 결과의 상위 Byte 값이 LED Array(8Bits)에 출력된다.
          • 이 프로그램은 uart 출력과 2진수를 10진수로 변환하는 프로그램 등을 생략하기 위하여 LED Array(8Bits)에 출력하도록 하였다.

  • c Listing file에 대한 이해
    • Listing file은 C Source file을 Complie 하면 생성되는 File로 프로그램 Debugging에 자주 사용 되는 중요한 File 이다.

    • Listing file 이해를 위한 C Source file과 Compile 하여 생성된 Listing file 예
      • Listing file을 설명 하기 위한 C Source file 예
      • 위 C Source file을 Compile 하여 생성된 Listing file 예: sw_led_basic_lss.pdf
      • C 프로그램에서 함수를 Call 할 경우 Parameter passing과 함수에서 결과를 Return 하는 방법을 설명 하기 위한 C Source file: ex_AVR_c_c_parameter_pass_add_c.pdf
      • 위 C Source file을 Compile 하여 생성된 Listing file: ex_AVR_c_c_parameter_pass_add_lss-Os.pdf
      • 위 File의 Compile 결과 생성된 실행 File(Intel hex format): ex_c_c_parameter_pass_add_HEX.pdf


  • C 프로그램과 Assembly 언어 프로그램을 Mixing한 프로그램 개발 관련 페이지 보기