Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- ARM 아키텍쳐: 메모리 모델과 배리어
- 실무PT후기
- 인프런
- 시스템 소프트웨어 개발을 위한 ARM 아키텍처의 구조와 원리
- 코멘토
- arm
- BSP
- Arm 아키텍처: 캐시
- 빌드 시스템
- ARM 아키텍처: 메모리모델과 배리어
- Kernel
- udemy
- Arm 아키텍처: 메모리 모델과 배리어
- yocto
- 코멘토실무PT
Archives
- Today
- Total
반도체 소프트웨어
요약 4. ARM 어셈블리 명령어 본문
- 개요
- 함수 시작과 끝에 주로 실행하는 어셈블리어 루틴
- stp: 레지스터 -> 스택 푸시 명령어
- ldp: 레지스터 -> 스택 팝 명령어
- ARM프로세서와 대화할 수 있는 언어 ex) ARM 프로세서에게 연산 시키기
- 어셈블리 명령어 실행한 결과는 레지스터에 저장
- 어셈블리 명령어 기본 형태 ex) "MOV <Xt>, #imm" == "<Xt> = #imm"
- 어셈블리 명령어 종류
- 어셈블리어는 유닛 단위, 루틴 단위로 공부하는 게 좋음
- 어셈블리어를 기계적으로 외우기보다는 해당 명령어가 ARM 프로세서 내부적으로 어떻게 동작하는지 원리를 파악하는 것이 중요
- 함수 시작과 끝에 주로 실행하는 어셈블리어 루틴
- 어셈블리 명령어의 실전 프로젝트 활용 사례
- 부트로더 개발
- 부트로더: 시스템 전원 인가 후 최초로 실행되는 소프트웨어
- 스타트업 코드: 부트로더에서 가장 먼저 실행되는 코드
- 스택 초기화
- MMU 설정
- 시스템 레지스터 설정
- 익셉션 벡터 베이스 주소 설정
- ARM 아키텍처의 기능을 활용한 드라이버 구현
- ARM 아키텍처의 기능을 활용해 모듈을 구현하려면 어셈블리 명령어 입력 필요
- 브링업 = 하드웨어 초기화
- 하이퍼바이저: 두 개 이상 OS를 사용하는 시스템 아키텍처
- 성능 최적화
- 디버깅
- 부트로더 개발
- 어셈블리 명령어 정리
- Move
- mov: 레지스터에 상수 설정 및 레지스터 데이터 옮길때, 대입할때 사용
- mvn: not 연산한 결과를 대입 <Rd> = ~#imm (2의보수, 음수 처리시에 주로 사용)
- 산술 명령어
- add: 단순 덧셈 연산뿐만아니라 구조체 멤버 접근시 주소 계산에도 사용함
- sub: 단순 뺄셈 연산뿐만 아니라 sp, 스택 공간 확보시에도 많이 사용 ex) sub r13, r13, #3c
- adc: add와 거의 유사하며 마지막에 캐리를 더함(add이후에 1을 더하는것)
- sbc: <Rd> = <Rn> - <Rm> - ~(Carry)
- rsb: 오퍼랜드에 대해 반대 순서로 뺄셈 연산을 수행하는 명령어
- rsc: <Rd> = <Rm> - <Rn> - ~(carry)
- 비트 시프트 명령어: 곱셈, 나눗셈으로 주로 사용
- LSL: <<
- 지정된 크기만큼 왼쪽으로 비트 시프트(엄청 많이 사용)
- 스타트업 코드에서 많이 사용, 성능이 좋은 명령어
- add 명령어와 함께 사용되기도 함 ex) ADD R1, R1, R0, LSL #4 : R0를 비트시프트해서 저장한뒤, 그 값을 R1과 더한 값을 R1에 저장
- LSR: >>
- ASR: >>>
- LSR 한 뒤에 MSB가 1이면, 오른쪽 비트 시프트시에 0으로 바뀌는 비트를 1로 변경(보통 맨 왼쪽이 1로 변경됨)
- ROR: X를 Y만큼 오른쪽으로 Rotate
- 오른쪽 비트 시프트되는 만큼을 MSB에 업데이트
- ROR RO, RO, #4: 4비트 만큼 로테이트
- LSL: <<
- 논리비트 명령어
- AND: 비트 AND
- ORR: 비트 OR
- ORN: 비트 OR NOT(X OR ~Y)
- EOR: 비트 Exclusive OR
- BIC: 비트 클리어 연산(X AND ~Y), 특정 비트(커널 비트 설정 등)를 클리어 할 때 주로 사용
- 메모리 연산 명령어
- H, SH, B 등 접미사는 다양하고 작은 비트단위로 데이터를 다룰때 사용
- 보통 메인메모리보다는 캐시메모리에 접근할 확률이 높음
- 메모리에 접근하는 명령어여서 주의깊게 다양한 관점에서 분석이 필요
- LDR: 메모리 -> 레지스터로 데이터 저장
- 해당 메모리 주소에 접근해서 데이터를 레지스터에 저장
- 포인터 타입으로 선언된 구조체 필드에 접근할 때 자주 사용
- 포인터 데이터형 접근시 많이 사용
- 사용하다가 데이터 어보트 발생하는 경우가 꽤 있음
- LDR 명령어 형태
- LDR <Rd>, <addr> ==> <Rd> = *<addr>
- LDR <Rd>, [Rn, #imm] ==> <Rd> = *(Rn + #imm)
- STR: 레지스터 -> 메모리로 데이터 저장
- 메모리 주소에 레지스터 데이터를 저장
- 구조체 필드에 저장할때도 많이 사용
- STR 명령어 형태(다른 명령어랑 조금다름): 왼쪽에서 오른쪽
- STR <Rd>, <addr> ==> *<addr> = <Rd>
- STR <Rd>, [Rn, #imm] ==> *(Rn + imm) = <Rd>
- 접근하는 메모리 주소가 올바르지 않은 경우
- ARMv7: data abort 익셉션 발생
- ARVv8: synchronous 익셉션 발생
- ARMv7(A32) 플래그 설정 명령어
- 일반적인 어셈블리어와 다르게 플래그 설정 명령어들은 cpsr 플래그 비트를 업데이트하는 동작을 실행!!
- 변수와 비트 연산을 수행한 결과에 따라 조건부로 분기하는 루틴에서 조건부 플래그를 많이 사용
- 즉 아래 명령어로 연산한 결과가 CPSR의 컨디션 플래그를 업데이트
- 종류
- CMP(COMPARE): Rn - op2 결과를 컨디션 플래그 해석에 맞게 비트를 업데이트 ex) CMP Rn, op2 에서 Rn - op2가 음수이면 CPSR.N 플래그를 1로 설정
- CMN(COMPARE NEGATIVE): Rn + op2 결과를 컨디션 플래그 해석에 맞게 업데이트
- TST(TEST): Rn & op2 (어떤 비트가 설정되었는지 확인할때 주로 사용)
- TEQ(test equivalence): Rn ^ op2
- 컨디션 플래그 종류(해석)
- N: 연산 결과 음수일때 1로 설정
- Z: 연산 결과가 0일때 1로 설정
- C: 캐리인경우 1로 설정
- V: 오버플로우인경우 1로 설정
- 보통 플래그 설정 다음에 조건부 분기 명령어가 쓰임
- ARM 아키텍처는 컨디션 플래그에 따라 수행 여부가 결정되는 조건부 실행 플래그를 지원
- 컨디션 비트값에 따라서 조건부 코드에서 다르게 분기
- 즉 조건문을 어셈블리어로 변환할 때 ARM 아키텍처의 플래그 설정값을 사용하여 표현
- 사례: BEQ 0x2000000 - cpsr 컨디션 플래그 비트 중 Z값이 1이면 0x2000000으로 분기
- ARM 아키텍처는 컨디션 플래그에 따라 수행 여부가 결정되는 조건부 실행 플래그를 지원
- 조건부 플래그와 접미사 (https://www.dongs.kr/post_arm.html -> 좋은 CV 블로그), (B.COND 타입의 명령어에서 COND으로 지정될 수 있다)
- 조건부 분기 명령어 (분기 명령어: 프로그램 흐름 바꾸는 명령어) (비트연산은 ARM 코어 내 ALU에서 처리되기에 실행 속도가 빠름!)
- B (offset): 지정된 주소로 분기 = 지정된 주소를 PC 레지스터에 저장하는 것(스타트업 코드에서 많이 보임)
- BL (offset): 지정된 주소로 분기하면서 링크 레지스터를 업데이트 (복귀할 주소), (c언어 함수 호출시에 주로 보임)
- BR <Rt>: 레지스터의 값으로 분기
- BLR <Rt>: 레지스터의 값으로 분기하면서 링크 레지스터를 업데이트(함수 포인터 사용시에 주로 보임)
- CBZ (ARMv8에서만 사용)
- CBZ Rt, <label>
- Rt 레지스터값이 0이면 지정된 주소나 레이블로 브랜치, 예시: cbz w26, 0xFFFFFFC010019E4C
- 수도코드: if (Rt == 0) b <label> else 다음 주소 명령어 실행
- CBNZ
- cbnz w26, 0xFFFFFFC010019E4C
- Rt 레지스터값이 0이 아니면 지정된 주소나 레이블로 브랜치
- 수도코드: if (Rt != 0) b <label> else 다음 주소 명령어 실행
- TBZ(test bit and branch if zero)
- test bit: 특정 비트가 0인지 1인지 여부를 확인하는 동작
- TBZ Rt, #imm, <label>
- Rt 레지스터 값의 #imm번째 비트가 클리어됐으면(0이면) 지정된 레이블로 분기
- if !(Rt & 0b#imm) b <label> else 다음 주소 명령어 실행
- tbz w26, #1, 0xFFFFFFC010019E4C == if !(w26 & 0b0010) else 다음 주소 명령어 실행(맨 오른쪽 비트가 0번째 비트)
- if (thread_flags & _TIF_NEED_RESCHED) {} 같은 코드가 tbz 사용 예시
- TBNZ
- Rt 레지스터값의 #imm번째 비트가 1로 셋팅됐으면 지정된 레이블로 분기
- if (Rt & 0b#imm) b <label> else 다음 주소 명령어 실행
- 트랩 명령어
- 단독으로 실행되는 명령어
- 다른 어셈블리어와 다르게 범용 레지스터를 입력으로 지정하지 않아도 실행됨
- 시스템 컨트롤 명령어
- 트랩 유발
- 익셉션 유발
- 명령어 실행시 소프트웨어적으로 익셉션 유발
- SVC
- 슈퍼바이저 콜(supervisor call)
- 유저 애플리케이션 -> 커널 공간으로 이동
- (ARMv7) user 모드 -> supervisor 모드로 스위칭
- Svc호출시 동작(ARMv7)
- 익셉션 발생
- pc에 익셉션 엔트리 주소 저장
- 시스템 콜 핸들러 호출
- Svc호출시 동작(ARMv8): el0 -> el1로 스위칭
- Svc호출시 동작(ARMv7)
- HVC
- 하이퍼바이저 콜
- 게스트 os에서 하이퍼바이저로 스위칭
- 커널에서 하이퍼바이저로 진입할때 실행
- 단일 os만 실행되는 시스템에서는 디버깅 정보를 저장하는 용도로 EL2를 활용
- 기타
- 하이퍼바이저 아키텍처: 여러 os를 동시에 운영하는 아키텍처(가상화 환경)
- 하이퍼바이저: 가상머신의 시스템 리소스 관리하는 역할
- 게스트 os = 가상머신
- vcpu를 통해 각 게스트 os가 사용할 cpu 설정 가능
- SMC
- 시큐어 모니터 콜
- 논 시큐어 <-> 시큐어 상태로 실행 흐름을 스위칭
- 트러스트존 아키텍처에서 주로 사용
- 프로세스 상태 제어 명령어
- ARMv7: xPSR(CPSR, SPSR)레지스터
- 직접 수정 가능
- MRS <Rt> xPSR: 값을 레지스터에 로드 (읽기)
- MSR xPSR_<field> <Rt>: 레지스터값을 xpsr필드에 쓰기 ex) MSR SPSR_s R0 / MSR SPSR_sf R0
- 접미사(특정비트 필드)(R0에서 접미사 범위에 해당하는 부분만 업데이트)
- c: [7:0] 비트필드
- x: [15:8] 비트필드
- s: [23:16] 비트필드
- f: [31:24] 비트필드
- ARMv8: PSTATE (인터페이스, 레지스터)
- 간접 수정 가능
- MSR DAIFSet, <Xt> : PSTATE.{D,A,I,F} 필드에 써주는 명령어
- 의사코드: PSTATE.DAIF |= <Xt>
- 보통 부팅이나 soc 검증시에 수동으로 설정할때 많이 사용
- 완벽하게 잘 사용해야함
- MSR DAIFClr, <Xt> : <Xt> 레지스터의 값을 PSTATE.{D,A,I,F}필드에 비트 클리어
- 의사코드: PSTATE.DAIF & = ~<Xt>
- 레지스터에 해당하는 값과 동일한 위치의 PSTATE필드만 비트 클리어
- ARMv7: xPSR(CPSR, SPSR)레지스터
- Move
출처: 인프런, "시스템 소프트웨어 개발을 위한 Arm 아키텍처의 구조와 원리", https://inf.run/FiFG
'CPU Architecture > ARM Architecture' 카테고리의 다른 글
요약 6. ARMv8 익셉션 레벨 (0) | 2023.12.31 |
---|---|
요약 5. ARMv7 동작모드 (0) | 2023.12.30 |
요약 3. ARM 레지스터 (0) | 2023.12.30 |
요약 2. ARM 공부 이유 (0) | 2023.12.30 |
요약 1. ARM 프로세서 역사 (0) | 2023.12.28 |