ARM Assembly 기본

Sireal·2023년 11월 6일
0

펌웨어

목록 보기
8/8
post-thumbnail

ARM Assembly

겁먹지말자. 까보면 진짜 명령어 한줄 짜리들이라 C보다 훨씬 심플들하다.

  • 실제로 실무에서는 어셈을 읽을 줄만 알면 된다. 진짜 처음부터 짜보는 일은 (거의)없음.

명령어 구조로 되어있는 프로그래밍 언어.

  • 컴퓨터가 좋아하는 기계어와 우리가 좋아하는 고급언어(C, Python 등) 사이에 있는 친구
  • 명령어 구조
    • Opcode Operand ... : Opcode 가 명령어, Operand가 파라미터(하나일수도 다수일수도)

      OPcode<cond> Rd Rm Rn

      • OPcode<>: 명령어 <옵션>
      • Rd: 목적지 레지스터. 결과 값자리. R0~15만 올 수 있음.
      • Rm: R0~15만 올 수 있음.
      • Rn: 여러 값들을 올릴 수 있음
        예시) MOV R0,R1,R2

자주 사용하는 어셈블리 명령어 모음

덧붙임 명령어

  • [] : syntax. 포인터 비슷
    - [Rn] = *Rn
  • ! : Write back 연산자. 업데이트 명령어
    • 곧 바로하라! 라는 느낌.
  • S: 계산 후 CPSR에 SPSR을 넣어 복구

아래는 Instructions(명령어) 이다.

  • Branch: B, BL, BX, BLX
    • Rd로 점프
    • B _printf: Printf로 점프
    • BL _printf: LR(R14, 링크레지스터)에 주소 백업 후 점프
    • BX _printf: Mode(ARM <-> THUMB) 변경 후 점프
    • BLX _printf: L(주소백업)도하고 X(모드변경)도 한 후 점프
    • BNE _printf: PC와 값이 다르다면(if Not Equals) 점프
  • Data Processing
    • MOV Rd, Rm: Rm을 Rd로 옮겨라. 복사. (Rd = Rm)
    • MVN Rd, Rm: Rm의 Negative값을 Rd로 복사
    • ADD Rd, Rm, Rn: Rm + Rn = Rd
    • SUB Rd, Rm, Rn: Rm - Rn = Rd
    • RSB Rd, Rm, Rn: Reverse SUB. Rn - Rm = Rd
    • AND Rd, Rm, Rn: And 연산
    • BIC Rd, Rm, Rn: 비트클리어. Rd = Rm & ~Rn
    • CMP Rm Rn: Rm이 더큰가? (결과는 CPSR에 업데이트됨)
  • Load / Store
    • LDR Rd, Rm: Rm을 Rd에 로드(저장)
    • STR Rd, Rm: Rm를 Rn에 복사(저장)
    • 인덱싱 방식
      • LDR Rd, [Rm, offset]
        • Rd = *(Rm + offset). Rm은 그대로
      • LDR, Rd, [Rn, offset]!
        • Rd = *(offset ++ Rm).
      • LDR Rd, [Rm], offset
        • Rd = *(Rm) 그리고 + offset
        • Rd = *(Rm ++ offset)
    • 사이즈 별 변형이 될 수 있음
      • LDRB (byte), LDRH (Halfword), LDRSB (signed byte), LDRSH (signed halfword)
      • STRB (byte), STRH (Halfword), STRSB (signed byte), STRSH (signed halfword)
    • 다중 처리
      • LDM{addr_mode} Rn, Rs, STM{addr_mode} Rn, Rs
      • addr_mode: IA, IB, DA, DB
        • A: After, 처리 후
        • B: Before, 처리 전
        • I: Increment, Word 증가
        • D: Decrement, Word 감소
      • ARM Stack의 PUSH는 STMDA 동작구조와 동일하다
  • 의사 명령어: 편의에 맞게 줄여진 명령어
    • LDR Rd, Label: Rd = *(PC + offset)
    • ADR Rd, Label: Rd = Label주소
  • SWAP 명령어
    • SWP Rd Rm [Rn]
      • Rd = [Rn]
      • Rn = Rm
      • 스와핑 명령어. 명령어 하나로 섬세하게 레지스터값을 변경할 수 있다 (세마포어구현)
    • 주의: PC와 함께 사용 금지.
  • PSR 명령어: MRS, MSR
    • 상태 레지스터와 레지스터 복사 가능 명령어
    • MRS Rd CPSR
    • MSR CPSR Rm
  • SWI 명령어
    • SW Interrupt. IRQ 인터럽트를 발생 시키는 명령어
    • User Mode -> 다른 모드로 전환할 때 사용됨
    • SWI 0x11: SWI에서 0x11 case 호출
  • DCD 명령어
    • Data 를 위한 메모리 할당 명령어
    • DCB(Byte), DCW(Word, 2Byte) ...
    • data1   DCD     1,5,20      ; data1은 1,5,20을 이은 형태로 word형으로 3개의 메모리 새로 할당
       data2   DCD     mem06 + 4   ; data2 는 라벨 mem6에 4를 더한 형태로  1개의 word형으로 메모리 새로 할당

어셈블리 코드

어셈은 두가지로 나뉜다 (ADS, GNU)

  • ADS (ARM), GNU (GNU 재단). 이렇게 만들어짐.
  • 보통 툴체인을 GNU로 써서 GNU식으로 많이 봤었음.
  • Dircetives가 대문자면 ARM, .소문자 면 GNU

어셈에서 코드란?

  • Directives + Label + Instruction + Comment
  • 이 조합으로 코드 1개가 완성된다.

OhHellNo 코드 예시

CODE32
AREA OhHellNo CODE, READONLY

ENTRY
BEGIN	@ LABEL
	ADR r0, THUMB
    BX r0

THUMB	@ LABEL
	ADR r1,

LOOP	@ LABEL
	LDRB r0, [r1], #1
	CMP r0, #0
    BLNE print_ch
    BNE LOOP
    B EXIT

TEXT = "Oh Hell No..", 0	@ LABEL

END

Dircectives: 지시어

  • CODE 32/16: ARM/Thumb 모드

  • AREA: 코드묶음. 링커가 다루는 최소 단위 모음.

    • 예시: AREA OhHellNo CODE, READONLY

    • 오..HellNo라는 리드온리 코드 라는 표시
      • ALIGN : alignment. default 4byte
      • CODE : 코드입니다
      • DATA : contain data
      • COMDEF : common section def
      • COMMON : common data section
      • NOINIT : BSS입니다
      • READONLY
      • READWRITE
  • ENTRY: 코드 시작지점 (PC 시작점)

  • LABELS: 레이블. 사용자 지정 심볼. 그저 이름표.

  • END: 코드의 끝.

  • EXPORT, IMPORT 지시어

    • Export: Gloabl symbol
    • Import: Extern symbol

참고

profile
🚄계속 앞으로🚄

0개의 댓글