본문 바로가기

시스템/등드등

ARM Assembly 간단 정리

1. Thumb 모드, ARM 모드


 - Thumb 모드 

   레지스터 : R0 ~ R7 (8개)

   기계어코드 길이 : 16bit(2byte)

 

 - ARM 모드

   레지스터 : R0 ~ R15 (16개)

   기계어코드 길이 : 32bit(4byte)


 Thumb <-> ARM 전환 : BLX/BX 등 X로 끝나는 분기문 명령


2. 레지스터


 R0 ~ R12 : 범용 레지스터, 인자값 및 임시 계산 저장소 등

 R13(SP) : Stack Pointer, x86의 ESP와 비슷한 역할

 R14(LR) : Link Register, 함수 호출 전 LR에 리턴 주소 저장하고 점프 (함수 호출시 리턴주소 스택 활용X)

 R15(PC) : 다음 실행할 코드의 주소 저장, x86의 EIP 레지스터와 동일한 역할


3. 함수 호출 규약


 x86에서는 cdecl, fastcall, stdcall등 다양한 함수 호출규약이 존재했으나,

 

 - R0 ~ R12 : 범용 레지스터, 인자값 및 임시 계산 저장소 등

 - R13(SP) : Stack Pointer, x86의 ESP와 비슷한 역할 


4. 연산 순서(보통 <-)


ex. ADD R0, R1, #0x2 : R1에 0x2를 ADD한 결과값을 R0에 저장

      MOV R0, R1 : R0 레지스터에 R1 레지스터 값을 대입



5. 분기명령 - B, BL, BNE, BEQ, CMP


 - B there : there로 무조건 분기 (Branch)

 - BEQ there : 플래그가 0이면 there로 분기, 아니면 다음 명령어 수행 (Branch Equal)

 - BNE there : 플래그가 0이 아니면 there로 분기, 아니면 다음 명령어 수행 (Branch Not Equal)

 - BL sub+ROM : 계산된 위치의 서브루틴 호출 (Branch with Link - x86의 CALL과 유사) 

 - CMP R1, #4 : R1이 4면 플래그 0으로 set


6. 메모리 연산 - STR, LDR


 - STR : 메모리 주소에 레지스터 값을 저장 (연산방향 : ->)


   ex.  MOV R0, #0x100  : R0 레지스터에 0x100 저장

          MOV R1, #0xFF    : R1 레지스터에 0xFF 저장

          STR R1, [R0]          : 0x100번지에 0xFF 저장


     * [레지스터] : 해당 레지스터의 값에 있는 메모리 주소 (C언어의 포인터와 유사)   

     

   ex. STR R1, [R0, #4] : R0+4번지에 R1 레지스터 값을 저장 

                                         []안에서 콤마(,)와 숫자상수 #을 이용해 해당 R0에서 상대적인 offset 위치의 메모리 주소 access 가능

                                         offset 범위 -4095~4096

                             

   ex. STR R1, [R0], #4 : R0번지에 R1 레지스터 값을 저장하고, R0의 주소값을 +4

                                         []밖에서 콤마(,)와 숫자상수 #는 Post Index 기능

                                         즉 R1값을 R0에 저장하고 R0 주소값을 상수값으로 변화시키는 것


   ex. STR R1, [R0, #4]! : R0+4번지에 R1 레지스터 값을 저장하고, R0의 주소값 +4 

                                          ! 은 auto-update 옵션, offset이 +된 값이 해당 레지스터에 저장됨

                                          단순히 [R0,#4]는 R0+4번지만 가르키는 것으로 끝나지만, 

                                          [R0,#4]!은 R0+4번지를 가르키고, R0=R0+4까지 실행됨(+와 +=차이)

      

 - LDR : 해당 메모리 주소의 값을 레지스터에 저장 (연산방향 : <-)

    ex. LDR R1, [R1, #4] : R1에 4byte 더한 주소에 저장되어 있는 값을 R1에 저장


7.  ARM에선 스택을 위한 명령어가 따로 존재하지 않음 (ex. push, pop X)


 - 장점 : CALL을 연속적으로 사용하는 경우가 아닌, 한번만 CALL 했을 때,

             스택을 사용하지 않고, 레지스터를 사용함으로써 속도면에서 큰 이득


 - 단점 : CALL이 연속적인 즉, 어떤 서브 루틴에서 또 다른 서브 루틴을 콜 했을 때,

             lr에 복귀할 주소가 또 들어가게 되면서, lr값을 덮어쓰기 한게 된다. 

                 이럴 땐 수동으로 sp(r13)을 이용해 스택에 r14값을을 넣어줘야 한다.


보충할 게 있다면 추후에 드르륵-

'시스템 > 등드등' 카테고리의 다른 글

Wannacry 1차 정리본  (0) 2019.01.26
pwntools 간단 정리  (0) 2019.01.11
ELF 파일 구조  (3) 2018.11.20
간단한 정리  (0) 2018.11.19
Format String Bug  (0) 2018.11.10