ARM 어셈블리어

RoughBoy·2023년 11월 10일
0

임베디드

목록 보기
2/4
post-custom-banner

ARM

  • 임베디드 기기에 주로 사용되는 RISC 프로세서
  • 저전력을 사용하도록 설계됨 → 모바일 기기 또는 IoT 디바이스에 사용됨

모드

  • Thumb 모드 레지스터 : R0 ~ R7 (8개) 기계어 코드 길이 : 16bit(2byte)
  • ARM 모드 레지스터 : R0 ~ R15 (16개) 기계어 코드 길이 : 32bit(4byte)

Thumb ↔ ARM 전환 : BLX/BX등 X로 끝나는 분기문 명령으로 모드를 전환한다.

레지스터

  • R0 ~ R12 : 범용 레지스터, 인자값 및 임시 계산 저장소 등
    • R0 : 함수 리턴값 저장
    • R0 ~ R3 : 함수 호출 인자 전달
    • R4 ~ R11 : 지역변수 저장
  • R13 ~ R15 : 특수 레지스터
    • R13(SP) : Stack Pointer 스택의 맨 위
    • R14(LR) : Link Register, 함수 호출 전 LR에 리턴 주소 저장
    • R15(PC) : 다음 실행할 코드의 주소 저장, x86의 EIP 레지스터와 동일한 역할
  • CPSR : 현재 프로그램 상태 레지스터
  • SPSR : CPSR값을 저장해두는 레지스터(CPSR 백업용)

ARM 아키텍처의 버전에 따라 레지스터의 개수는 다를 수 있다. ARMv8의 레지스터는 범용레지스터가 16개이고 총 레지스터 갯수는 30개가 넘는다.

함수 호출 규약

R0 ~ R3 : 인자 및 반환 값을 저장하기 위한 Register로 사용된다.

그러나 인자의 수가 4개 이상인 경우 stack을 통해 인자를 전달한다.

명령어

OP Code Rd, Rs, Rm

  • OP Code : push, add, sub, mov 등 어셈블리 명령어
  • Rd : Register Direction, 반드시 R0~R15인 Register만 가능하며 연산작업의 결과값을 저장하는 레지스터
  • Rs : Register Source, 연산을 위해 사용되는 첫 번째 레지스터, 반드시 R0~R15인 Register만 가능
  • Rm : Op2, 레지스터뿐만 아니라 상수(#), 주소([]), 쉬프트 연산식 등 다양한 값이 사용가능.

1-1) 산술연산

  • ADD(Addition)
    • ADD Rd Rs Rm → Rd = Rs + Rm
  • ADC(Addition with Carry)
    • ADC Rd Rs Rm → Rd = Rs + Rm + carry
  • SUB(Subtraction)
    • SUB Rd Rs Rm → Rd = Rs - Rm
  • SBC(Subtraction with Carry)
    • SBC Rd Rs Rm → Rd = Rs - Rm - !carry
  • RSB(Reverse Subtraction)
    • RSB Rd Rs Rm → Rd = Rs- Rs
  • RSC(Reverse Subtraction with Carry)
    • RSC Rd Rs Rm → Rd = Rm - Rs - !carry

1-2) 논리 연산

  • AND(Logical AND)
    • AND Rd Rs Rm → Rd = Rs AND Rm
  • ORR(Logical OR)
    • ORR Rd Rs Rm → Rd = Rs OR Rm
  • EOR(Logical XOR)
    • EOR Rd Rs Rm → Rd = Rs XOR Rm
  • BIC(Bit Clear)
    • BIC Rd Rs Rm → Rd = Rs AND (!Rm)

1-4) 시프트 연산

  • LSL(Logical Shift Left)
    • LSL #n : 최후에 밀려난 비트가 CPSR의 C-flag에 저장
      • LSL : signed/unsigned 곱하기 2
  • LSR(Logical Shift Right)
    • LSR #n : 최후에 밀려 비트가 CPSR의 C-flag에 저장
      • LSR : unsigned 나누기 2
  • ASR
    • ASR #n : MSB를 유지하고, 밀려난 비트가 CPSR의 C-flag에 저장
      • ASR은 signed int의 나누기 2 동작을 수행합니다.
    • 레지스터를 우측으로 지정한 비트 수 만큼 부호를 유지하며 Shift합니다.

1-4) Register 값 저장

  • MOV(Move)
    • MOV Rd Rs → Rd = Rs
  • MVN(Move Negative)
    • MVN Rd Rs → Rd = !Rs

1-5) 비교 연산

  • CMP(Compare)
    • CMP Rs Rm → status = Rs - Rm
      • "Rs - Rm"의 결과를 Status flag에 반영
  • CMN(Compare Negative)
    • CMN Rs Rm → status = Rs - ( -Rm) = Rs + Rm
      • "Rs + Rm"의 결과를 Status flag에 반영
  • TST(Test bits)
    • TST Rs Rm → Status = Rs AND Rm
      • "Rs AND Rm"의 결과를 Status flag에 반영
  • TEQ(Test Equivalence)
    • TEQ Rs Rm → Status = Rs XOR Rm
      • "Rs XOR Rm"의 결과를 Status flag에 반영

1-6) 분기 명령어

  • B(Branch)
    • B Rd
      • B add : Global Label
      • B 1f : Local Lable
      • B . : 무한루프(‘ . ’ = 제자리)
    • 뒤에 지정된 주소값으로 분기
  • BL(Branch with Link)
    • BL Rd
    • 뒤에 지정된 주소값으로 분기하면서 현재 R15(PC) + 0x2 번지의 주소값을 R14에 저장

B와 BL은 분기 주소로 레지스터를 사용할 수 없다.

  • BX(Branch indirect)
    • BX R
    • 뒤에 지정된 레지스터 값으로 분기
  • BLX(Branch indirect with Link)
    • BLX R
    • 뒤에 지정된 레지스터 값으로 분기하면서 현재 R15(PC) + 0x2 번지의 주소 값을 R14에 저장

1-7) 메모리 접근 명령어

  • LDR(Load) : 메모리 → 레지스터(Load to Register)
    • ldr Rd, [Rs] : Rs의 값을 주소로 참조하여 Rd에 저장
    • ldr Rd, [Rs], #4 : Rs의 값을 주소로 참조하여 Rd에 저장하고 Rs에 4를 더함
    • ldr Rs , =Value : Rs레지스터에 상수값(최대 4byte) 저장
  • STR(Store) : 레지스터 → 메모리(Store to Memory)
    • ex)
      • str Rd, [Rs] : Rd의 값을 Rs의 값을 주소로 참조하여 저장
      • str Rd, [Rs], #4 : Rd의 값을 Rs의 값을 주소로 참조하여 저장하고 Rs에 4를 더함

상태 플래그

  • N : 연산 결과가 음의 값을 가질 경우 → Set 1
  • Z : 연산 결과가 Zero인 경우 → Set 1
  • C : 연산 결과가 Carry를 가질 경우 → Set 1
  • V : 연산 결과 Overflow가 발생한 경우 → Set 1

링크

profile
The day⋯ is doomed⋯. Thanks to⋯ the Rowdyruff Boys⋯.
post-custom-banner

0개의 댓글