[컴퓨터구조] Ch7-4. CA_Thumb Instruction Set

김규원·2024년 6월 8일

24-1: 컴퓨터구조(完)

목록 보기
11/15
post-thumbnail

Aims & Objectives

Aims

  • Thumb 명령어 집합

Learning Objectives

  • Thumb 명령어 집합의 기본 기능(basic features)
  • Thumb 일반적 특징
  • Thumb constraints 인식
  • Thumb 명령어의 general syntax

Arm vs Thumb

Thumb 명령어

  • 16bit 명령어 집합
  • c코드에서의 코드 밀도 최적화(ARM의 65%)
  • 좁은 메모리에서의 개선된 기능
  • ARM 명령어 집합의 일부 기능
    : 단일 ARM 명령어를 대체하기 위해 여러 Thumb 명령어가 필요한 경우 존재
  • 조건부 실행은 사용되지 않음
  • 대부분 데이터 처리 명령어에서 기본적으로 플래그가 설정
  • 소스 및 대상 레지스터는 동일
  • 저수준 레지스터만 사용(r0~r7)
  • 상수 크기가 제한
  • 인라인 barrel shifter가 사용되지 않음
    : 즉, barrel shifter 사용이 어렵기에 데이터 처리 명령어에서 쉬프트나 회전 연산을 수행하려면 미리 쉬프트된 값을 레지스터에 로드해야함.
  • 제약 조건이 일반적으로 일관되지 않음
    : Thumb 명령어의 특정 제약이 ARM 명령어를 사용할 때와 다를 수 있음
  • 컴파일러 생성을 대상으로 함.
    : Thumb 명령어 세트가 프로그래머가 직접 작성하는 대신 컴파일러가 코드를 생성하는 데 사용되도록 설계되었음.

요약

  • Thumb 명령어는 ARM 아키텍처의 일부로서, 주로 코드의 밀도를 높이고 실행 효율성을 향상시키기 위해 사용
  • 컴파일러는 C나 다른 고수준 언어로 작성된 소스 코드를 Thumb 명령어로 변환하여 메모리를 절약하고 실행 시간을 최적화

Arm and Thumb Performance

32bit

ARM > Thumb

  • Thumb 명령어가 더 작아서 하나의 ARM 명령어를 여러 개의 Thumb 명령어로 표현해야 하는 일이 발생하기에 ARM > Thumb

16bit

ARM < Thumb

  • 메모리 제한이 있는 시스템에서는 Thumb 모드가 유리함.
  • 즉, 작은 코드 크기는 효율성을 향상시키고 메모리 대역폭을 절약할 수 있음

16bit with 32 bit stack

ARM < Thumb

  • Thumb 모드에서는 stack을 32bit로 유지하면서 16bit 명령어 사용이 가능
  • 이러한 구성은 메모리 사용량을 최적화하면서도 stack 관리의 유연성 유지에 유리

Branches

Conditional Branches(조건부 분기)

  • 특정 조건이 충족될 때만 분기
  • B<cond> label
  • 8비트 오프셋을 사용
  • -128에서 +127 명령어 범위(+/- 256바이트)

Unconditional Branches(무조건 분기)

  • 조건 없이 항상 분기
  • B label
  • 11비트 오프셋 사용
  • -1024에서 +1023 명령어 범위(+/- 2킬로바이트)

Long Branches with Link(링크를 통한 장거리 분기)

  • BL subroutine
  • 두 개의 명령어로 구성
  • 호출된 서브루틴으로 분기
  • 22비트 오프셋을 사용
  • -2097152에서 +2097151 명령어 범위 (+/- 4메가바이트).

BX(브랜치 및 교환)

  • ARM 코드와의 상호 운용성을 위해 사용
BX LR
; LR 레지스터에 저장된 주소로 분기하여 실행 상태를 변경함
  • 현재 실행 중인 코드의 흐름을 변경하고, 동시에 실행 상태를 ARM 상태와 Thumb 상태 간에 전환
  • BX 명령어는 주로 Thumb 코드에서 ARM 코드로 분기하는 데 사용

예시 시나리오

CMP R0, #0      ; R0가 0인지 확인
BEQ Label       ; 만약 R0가 0이면 Label로 분기
BX LR           ; R0가 0이 아니면 LR에 저장된 주소로 분기하여 실행 상태 변경

Data Processing instructions

  • ARM 데이터 처리 명령어의 하위 집합

Shift(이동) 명령어

  • 이동 명령어: LSL, ASR, LSR, ROR
  • ex
    LSL Rd, Rs, #Imm5 ; Rd = Rs <shift> #Imm5
    ASR Rd, Rs ; Rd = Rd <shift> Rs

data processing(데이터 처리) 명령어

  • 일반적으로 두 개의 피연산자만 사용
  • 저수준 레지스터에서 작동
    BIC Rd, Rs ; Rd := Rd AND NOT Rs
    : 레지스터 Rd에 저장된 값을 레지스터 Rs에 저장된 값의 NOT 연산(비트 반전)한 결과와 AND 연산하여 다시 레지스터 Rd에 저장
    ADD Rd, #Imm8 ; Rd := Rd + #Imm8
    : 레지스터 Rd에 저장된 값에 즉시 값(Immediate) #Imm8를 더하여 다시 레지스터 Rd에 저장
  • 덧셈, 뺄셈, 이동의 경우 세 개의 피연산자 형태도 존재
    ADD Rd, Rs, #Imm3 ; Rd = Rs + #Imm3
  • 저수준 레지스터 연산에서는 조건 코드가 항상 설정
  • MOV, ADD, CMP는 높은 레지스터에도 접근 가능
  • 조건 코드 플래그는 CMP 명령어만 설정
    : CMP 명령어는 두 개의 값을 비교하고 그 결과에 따라 조건 코드 플래그를 설정
    : 다른 데이터 처리 명령어는 조건 코드 플래그를 설정하지 않음.

Load or Store Register

사전 인덱스 주소 지정 모드(pre-indexed addressing modes)

  • Load/Store Register는 preindexed addressing modes(사전 인덱스 주소 지정 모드)에서만 사용됨.
    1. 베이스 레지스터(base register) + 오프셋 레지스터(offset register)
    1. 베이스 레지스터 + 상수 오프셋(constant offset)

을 결합하여 주소를 계산

Special forms(특별한 형태)

베이스 레지스터로 PC를 사용하는 로드 명령어

  • 1K바이트의 즉시 워드 정렬된 오프셋
  • 리터럴 풀(literal pool)에서 값을 로드하는 데 사용

LDR Rd, [PC, #imm]

  • PC(Program Counter)를 베이스 레지스터로 사용하여 리터럴 풀(literal pool)에서 값을 로드
  • imm은 1K바이트의 즉시 워드 정렬된 오프셋
  • 리터럴 풀에서 해당 위치에 있는 값을 Rd에 로드

베이스 레지스터로 SP를 사용하는 로드 및 저장 명령어

  • 1K 바이트의 즉시 워드 정렬된 오프셋
  • Stack(스택)의 로컬 변수에 접근하는 데 사용

LDR Rd, [SP, #imm]
STR Rd, [SP, #imm]

  • 스택(stack)의 로컬 변수에 접근하기 위해 스택 포인터(SP)를 베이스 레지스터로 사용
  • imm은 1K바이트의 즉시 워드 정렬된 오프셋
  • 해당 위치에서 값을 로드하거나 저장

Block Data Transfers

  • 메모리 복사와 같은 작업을 위해 사용
  • 전송 후 베이스 포인터를 증가시킴
  1. STMIA Rb!, {Low Reg list}:
  • 주어진 저수준 레지스터 목록을 메모리에 저장하고
  • 저장 후에 베이스 레지스터(Rb)를 자동으로 증가시킵니다.
  1. LDMIA Rb!, {Low Reg list}:
  • 메모리에서 주어진 저수준 레지스터 목록을 로드하고, 로드 후에 베이스 레지스터(Rb)를 자동으로 증가시킵니다.

또한, 스택의 전체적인 내림차순 작업도 수행 가능

  1. PUSH {Low Reg list}:
  • 주어진 저수준 레지스터 목록을 스택에 푸시(push)

PUSH {r0, r1, r2}

  • 레지스터 r0, r1, r2의 값을 스택에 푸시
  • 스택 포인터(SP)는 각 레지스터 값을 푸시할 때마다 감소
  1. PUSH {Low Reg list, LR}:
  • 주어진 저수준 레지스터 목록과 Link Register(LR)를 함께 스택에 푸시(push)
    • 이는 하위 레지스터 리스트와 함께 서브루틴 진입(subroutine entry)을 지원

PUSH {r4, r5, lr}

  • 레지스터 r4, r5와 링크 레지스터(LR)의 값을 스택에 푸시
  • 서브루틴 진입 시에 현재 함수의 상태를 저장하고, 돌아올 주소를 보존하기 위해 사용
  • 스택 포인터(SP)는 각 레지스터 값을 푸시할 때마다 감소
  1. POP {Low Reg list}:
  • 스택에서 주어진 저수준 레지스터 목록을 팝(pop)

POP {r0, r1, r2}

  • 스택에서 값을 팝하여 레지스터 r0, r1, r2에 저장
  • 스택 포인터(SP)는 각 레지스터 값을 팝할 때마다 증가
  • 이전 함수 호출에서 저장된 레지스터 값을 복원하는 데 유용
  1. POP {Low Reg list, PC}:
  • 스택에서 주어진 저수준 레지스터 목록과 프로그램 카운터(PC)를 함께 팝(pop)
  • 이는 하위 레지스터 리스트와 함께 서브루틴 종료(subroutine exit)를 지원

POP {r4, r5, pc}

  • 스택에서 값을 팝하여 레지스터 r4, r5와 프로그램 카운터(PC)에 저장
  • 프로그램 카운터(PC)가 갱신되면, CPU는 팝된 주소로 분기하여 실행을 재개
  • 서브루틴 종료 시에 저장된 레지스터 값과 복귀 주소를 복원하는 데 사용
; 함수 호출 시 현재 상태를 저장
PUSH {r4, r5, lr}

; 함수 본문
MOV r4, #10
MOV r5, #20
ADD r0, r4, r5

; 함수 종료 시 상태를 복원하고 호출자로 복귀
POP {r4, r5, pc}

Miscellaneous(여러가지잡다한)

Thumb SWI(Software Interrupt Manager) 명령어 형식

  • ARM과 동일하지만, SWI 번호는 0에서 255로 제한
    SWI <SWI number>

MRS 또는 MSR 명령어 없음

  • CPSR은 조건 코드 플래그를 설정하여만 접근 가능
  • SPSR에 접근 불가

coprocessor 명령어 공간 없음

Additions in Armv6

해석

  • ARMv6에서 일부 추가된 ARM 명령어는 Thumb에서도 사용할 수 있는 동등한 명령어 존재
  • REV
    바이트 순서 반전
    REV16 및 REVSH도 포함
  • SETEND
    시스템 엔디안을 설정 (무조건 명령어)
  • CPS
    프로세서 상태 변경
    ARM 버전과 달리 프로세서 운영 모드 변경 불가
    ARM 상태로 전환하지 않고도 인터럽트를 활성화/비활성화 가능
  • SEXT8
    8비트를 32비트로 부호 확장
    SEXT16, UEXT8, UEXT16도 포함

Appendix: Thumb-2

  • Thumb-2는 Thumb ISA에 대한 주요 확장
  • 거의 모든 ARM ISA 기능을 구현하기 위해 32비트 명령어를 추가
  • 완전한 16비트 Thumb 명령어 집합을 유지.
  • ARM1156T2-S와 Cortex 패밀리에서 지원
  • Cortex-M3는 Thumb-2만 지원
  • Cortex-M1은 Thumb-2의 일부를 지원
  • 설계 목표: Thumb 코드 밀도로 ARM 성능 달성
  • 명령어 집합 분할을 수동으로 선택할 필요가 없음
  • 코드 프로파일링 및 실행 패턴 이해 필요성을 줄임.
  • 컴파일러가 자동으로 16비트와 32비트 명령어를 선택 가능
  • ARM 상태 동작에 접근 가능
  • 예외를 직접 처리 가능.
  • 코프로세서에 접근 가능.
  • v5TE 및 v6의 고급 데이터 처리를 수행 가능
  • If-Then (IT) 명령어를 통한 조건부 실행

Appendix: Thumb-2 Size and Performance

for Time

  • Arm > Thumb-2 > Thumb

for Space

  • Arm > Thumb > Thumb-2
profile
행복한 하루 보내세요

0개의 댓글