ARM Assembly 명령어 정리

※ 용어 정의
     Rd: Destination Register   /   Rn: Operand1 Register   /   Rm: Operand2 Register
     <cond>: Execution Condition code
     <S>: S-Suffix – Status Update Suffix – SPSR의 값을 CPSR로 불러와서 Status를 Update
     <!> : ! – Suffix – Writeback Suffix – [,]내의 선처리 연산 수행 후 값을 갱신
     <Operand2>: Operand2가 가질 수 있는 형식
          ㄱ. #Immediate: 32bit  명령에서 Immediate값은 8-bit pattern의 짝수 shift 값 만을 허용
          ㄴ. Rm{, shift연산 #immediate}: Register(Rm)값에 #immediate 값으로 Shift 연산
               

                 § Shift 연산의 종류
               – asr(Arithmetic Shift Right): Immediate의 값 만큼 right shift, 앞에 bit는 Sign Extension
               – lsr(Logical Shift Right): Immediate의 값 만큼 right shift, 앞에 bit는 0으로 채움
               – lsl(Logical Shift Left): Immediate의 값 만큼 left shift, 뒤에 bit는 0으로 채움
               – ror(ROtate Right): Immediate의 값 만큼 rotate right, rotate후 bit 0값은 carry에 저장
               – rrx(Rotate Right eXtend): rrx는 1bit 씩 rotate right, bit 0값은 carry에 저장

1. 데이터 처리 명령(General Data Processing Instruction)



     1.1 산술 연산
Syntax: add<cond><S> Rd, Rn, <Operand2>

          add: Rd := Rn + <Operand2>
          sub: Rd := Rn – <Operand2>
          adc(ADd with Carry), sbc(SuBtract with Carry): Carry를 포함한 add, sub 연산
         
          rsb(Reverse SuBtract): Rd := <Operand2> – Rn
          rsc(Reverse Subract with Carry): Carry를 포함한 역 sub 연산

     1.2 논리 연산
Syntax: and<cond><S> Rd, Rn, <Operand2>

          and: Rd := Rn & <Operand2>
          orr:  Rd := Rn | <Operand2>
          eor: Rd := Rn ^ <Operand2>
          bic: Rd := Rn & !<Operand2>


     1.3 Register 값 저장

Syntax: mov<cond><S> Rd, <Operand2>

          mov: Rd := <Operand2>
          mvn: Rd := !<Operand2>

     1.4 비교
Syntax: cmp<cond><S> Rn, <Operand2>

          cmp: Rn값에서 Opeand2값을 빼서 그 결과를 Status flag에 반영, SUBS와 동일한 명령
          cmn: Rn값에서 Operand2값을 더해서 그 결과를 Status flag에 반영, ADDS와 동일한 명령

          tst: Rn과 Opearand2를 bit and 연산을 수행해서 그 결과를 Status flag에 반영, ANDS와 동일한 명령
          teq: Rn과 Operand2를 bit xor 연산을 수행해서 그 결과를 Status flag에 반영, EORS와 동일한 명령

2. 메모리 접근 명령(Memory Accesss Instruction)

          Syntax: ldr<cond><B> Rd, label
                       ldr<cond><B><T> Rd, [Rn]
                       ldr<cond><B> Rd, [Rn, FlexOffset]<!>         ;Pre-Indexed<Auto-Indexing>
                       ldr<cond><B><T> Rd, [Rn], FlexOffset        ;Post-Indexed

          <B>: B Suffix가 있을 경우 8-bit Unsigned byte 단위로 Access, 없을 경우 32-bit word로 Access
          <T>: T suffix가 있을 경우 Processor가 User mode에서 memory access 처리
          FlexOffset:
               ㄱ.#Immediate: -4095 부터 -4096사이의 상수 값
               ㄴ.{-}Rm{, shift연산}: Rm은 음의 부호를 가질 수 있으며, Rm의 Shift 연산도 가능함

     2.1 Load 또는 Store 명령 예제

          ldr r0, [r1]: r1에 저장된 주소를 이용해서 메모리로부터 r0로 값을 불러옴
          str r0, [r1], #4: r0의 값을 메모리의 r1의 주소에 저장하고 r1을 +4함.
          참고) 부호가 있는 Halfword, Byte로 읽을 때는 SH(Signed Halfword), SB(Signed Byte) <–(ldr only)
                  Unsigned Halfword로 읽거나 저장할 때는 H를 사용.
                  Doubleword의 경우 D 를 사용, 이 때의 Offset은 {-}Rm 만 허용함.

     2.2 Multiple Load 또는 Store 명령



Syntax: ldm<cond><addrmode> Rn<!>, {reglist}<^>

          <addrmode>: address mode에는 총 8가지가 있으며, 4가지는 address의 연상 방식에 따른
                                구분이며 4가지는 stack의 특성에 따른 구분이다.
              – IA(Increment Address after each transfer), – IB(Increment Address after each transfer)
              – DA(Decrement Address after each transfer), – DB(Decrement Address after each transfer)

              – FD(Full descending stack): stack의 주소에 data가 저장이 된 상태이고, 주소가 감소하면서 저장
              – ED(Emtpy descending stack): stack의 주소에 data가 없는 상태이고, 주소가 감소하면서 저장
              – FA(Full ascending stack): stack의 주소에 data가 저장이 된 상태이고, 주소가 증가하면서 저장
              – EA(Emtpy ascending stack): stack의 주소에 data가 없는 상태이고, 주소가 증가하면서 저장

          <!>: ! – Suffix가 있을 경우 마지막 주소(최종으로 이동한 주소)를 Rn에 저장함
          <^>: SPSR의 값을 CPSR에 넣어줌, S-Suffix와 동일한 기능을 수행함.

          ldm: Rn으로 부터 reglist에 지정한 register 수 만큼 값을 불러옴
          stm: reglist에 있는 register의 값들을 Rn에 저장함.

          [주의] Reglist에 지정한 Register의 순서와 상관없이 Register의 번호가 낮은 값이
                    메모리의 낮은 주소에 저장 또는 읽어진다. reglist는 ‘r1,r2,r3’ 또는 ‘r1-r3’으로 표현
          [자주 사용되는 형식] STMFD sp!, {r4-r7,lr} / LDMFD sp!, {r4-r7,pc}

3. 분기 명령(Branch Instruction)


Syntax
: b<cond> label

     b: label이 있는 주소로 branch(PC값에 label의 주소를 입력)
     bl: 다음 명령의 주소를 lr에 저장하고, b와 같이 label의 주소로 branch

4. 기타 명령어
     4.1 Software Interrupt

Syntax: swi<cond> Immediate_24bit

          swi: 지정한 번호를 갖는 Software Interrupt를 발생시킴, 해당 번호에 맞는 SWI vector로 branch
               (Software Interrupt가 걸리면 프로세서의 모드는 Supervisor로 변경됨)

     4.2 PSR Access

Syntax: mrs<cond> Rd, psr

                    psr에 지정한 값(cpsr 또는 spsr)로 부터 값을 불러와서 Rd에 저장 (Register <- PSR)


Syntax: msr<cond> psr_(field), #Immediate_8bit
msr<cond> psr_fields, Rm      

                    Register(Rm)의 값 또는 8bit Immediate값을 psr(cpsr 또는 spsr)에 저장 (Register -> PSR)
                    (field): f, s, x, c 값이 선택적으로 올 수 있음. 지정한 field 영역에만 값을 저장함.



          [주의] 프로세서가 User 또는 System mode일 때는 SPSR에 엑세스 하지 말아야 한다.
          [자주 사용되는 형식] msr CPSR_c,r0

5. 상태 플래그와 실행 조건 코드(Status Flags & Execution Condition Codes)
     N: 연산 결과가 음의 값을 가질 때 Set ‘1’
     Z: 연산 결과가 영일 때 Set ‘1’
     C: 연산 결과가 캐리(Carry)를 가질 때 Set ‘1’
     V: 연산 결과 오버플로우(Overflow)를 발생시킬 때 Se
사용자 삽입 이미지


<ARM Instructioin Set>


사용자 삽입 이미지
     ① opcode<cond><S> Rd, Rn, #Immediate
     ② opcode<cond><S> Rd, Rn, Rm OP #Imm
     ③ opcode<cond><S> Rd, Rn, Rm OP Rs
          – cmp, cmn 명령에서는 Rd는 무조건 ‘0’ 값을 넣어줘야 함.(SBZ(Should Be Zero))

     ④ opcode<cond> Rd, Rn, #Immediate
     ⑤ opcode<cond> Rd, Rn, Rm OP #Imm
     ⑥ opcode<cond> Rd, <address>
     ⑦ opcode<cond><addrmode> Rm, Register_List^
     ⑧ opcode<cond><addrmode> Rm<!>, Register_List
     ⑨ opcode<cond><addrmode> Rm<!>, Register_List^
          – P=’1′ Pre, P=’0′ Post / U=’1′ Increment, U=’0′ Decrement / B=’1′ Byte load, B=’0′ Word load /
            W=’1′ Write-back(Auto-Index) W=’0′ / L=’1′ opcode는 ldr, L= ‘0’ str /
            I=’1′ Addr_mode가 모두 Offset field I=’0′ 앞에 Addr_mode는 ‘0’ 뒤에 Addr_mode는 Rm /
            S=’1′ Signed, S=’0′ Unsigned / H=’1′ Half Word, H=’0′ Word or Byte

     ⑩ b<cond> #Target Address(24bit Offset) – L의 값이 ‘1’이면 bl 명령

     ⑪ SWI #SWI Number

     ⑫ mrs<cond><S> Rd, PSR
     ⑬ msr<cond><S> PSR_<Field_Mask>, Rm
     ⑭ msr<cond><S> PSR_f, #Immediate
          – S의 값이 ‘1’이면 SPSR에서, ‘0’이면 CPSR.
          – SBO(Should Be One) 영역은 ‘1’로, SBZ(Should Be Zero) 영역은 ‘0’의 값을 넣어줘야 함


<ARM Assembly 명령어 정리표>
5402276715.pdf<참고자료>
  – ARM Developer Suite 1.2 Assembler Guide(ARM DUI 0068B):
    http://infocenter.arm.com/help/topic/com.arm.doc.dui0068b/DUI0068.pdf
  – ARM Asssembly Language Programming: http://www.arm.com/miscPDFs/9658.pdf
  – kkamagui의 프로그래밍 작업실 ARM 어셈블리: http://kkamagui.springnote.com/pages/432792
  – ARM Instruction Quick Finder: http://www.heyrick.co.uk/assembler/qfinder.html
  – ARM Reference – rE Ejected: http://re-eject.gbadev.org/ =>ARM_Reference-rE.Ejected.pdf 자료 출처

You may also like...

3 Responses

  1. Xino 댓글:

    참고 잘 했습니다~
    Contidion 부분에 Always와 Never가 Opcode가 바뀐거 같아요.
    Never 니모닉은 NV가 아니라 NE인거 같구요..
    아무튼 너무 감사합니다.

  2. Xino 댓글:

    NV로도 쓰는군요.. 죄송합니다…;;
    홈피에 퍼갔는데 트랙백이 안 달려서 댓글로 남기고 갈께요~ ^^;;

    • downright 댓글:

      pdf 자료 내부에 있는 코드는 제가 작성한 내용이 아니라,
      원본을 갖고 있지 않습니다.
      그래서 웹 링크로 원본 출처를 밝혀놓았습니다.
      p.s.트랙백 기능은 테러를 당한 경우가 있어서 닫아 두었어요^^;

downright 에 응답 남기기 응답 취소