UBFX
Summary
커널 프로젝트가 앞으로 PL011 UART 드라이버의 상태 레지스터를 읽거나, ARM64 시스템 레지스터(mpidr_el1 같은 신분증 레지스터)에서 특정 필드 값만 쏙쏙 뽑아낼 때, 이 UBFX야말로 매일 아침 숨 쉬듯 쓰게 될 커널 개발의 0순위 마법 지팡이입니다.
🧠 UBFX: 상남자의 비트 가르기 메커니즘 (단 1클럭의 기적)
- 고급 언어(C언어)에서 64비트 거대한 데이터 뭉치 중 중간에 낀 특정 비트(예: 4번째 비트부터 8개 비트)만 뽑아내려면 인간들은 참 짜증 나고 구차하게 코딩을 해야 합니다:
- result = (data » 4) & 0xFF; ➡️ 오른쪽 시프트 한 번 하고, 마스크 비트 AND 연산하고… 총 2단계를 거치죠.
- 하지만 상남자의 아키텍처인 ARM64의 UBFX는 “시프트 연산 + 마스크 AND 연산 + 나머지 상위 비트 0으로 청소(Zero-extend)”까지의
- 3대 공정을 CPU 내부 회로에서 단 1클럭 만에 물리적으로 끝내버립니다.
🧱 코드샘플
“시스템 레지스터나 센서 데이터에서 원하는 핵심 정보(비트필드)만 광속으로 추출하는” 실전 예제
// =========================================================================
// Hun ARM64 Mnemonic Dictionary - Open Example
// Mnemonic: UBFX (Unsigned Bitfield Extract)
// Description: 레지스터의 특정 비트 구간을 뽑아내어 하위로 정렬하고 상위는 0으로 채움
// =========================================================================
.global _hun_ubfx_extract_example
.text
.align 3
_hun_ubfx_extract_example:
// [무대 세팅] 16진수 날것의 무거운 데이터 뭉치를 준비합니다.
// 0x12345678_ABCD9876 이라는 거대한 64비트 값이 X1에 들어있다고 가정합시다.
// (여기서 우리는 중간에 낀 'ABCD'라는 16비트 알맹이만 쏙 빼먹고 싶습니다!)
MOVZ X1, #0x9876, LSL #0
MOVK X1, #0xABCD, LSL #16
MOVK X1, #0x5678, LSL #32
MOVK X1, #0x1234, LSL #48
// 1. [UBFX 단판 승부] 칼날을 들이대고 정확한 비트 위치를 도려냅니다.
// 구문: UBFX <대상>, <소스>, #<시작비트위치>, #<뽑아낼비트폭>
//
// - 시작비트 #16: X1 레지스터의 하위 16번 비트(즉, ABCD의 시작점)부터 시작해서
// - 비트폭 #16: 딱 16비트만큼(즉, ABCD 4자리 문자 분량)을 통째로 잘라내어,
// - 대상 X0의 맨 하위(0번 비트) 자리에 정렬하여 꽂아 넣습니다!
// - 동시에 X0의 나머지 상위 모든 비트(비트 16~63)는 깨끗하게 0으로 지워줍니다.
UBFX X0, X1, #16, #16
// [최종 결과] X0 = 0x000000000000ABCD
// 복잡한 연산 없이 단 1줄, 1클럭 만에 순수한 알맹이 'ABCD'만 대장 레지스터 X0에 안착!
RET
🎯 UBFX 구문 요약
- UBFX X0, X1, #4, #8 ➡️ “X1의 4번 비트부터 시작해서 8개 비트를 쏙 뽑아서 X0 바닥에 내려놓고, 위쪽은 0으로 다 쓸어버려라!”
- 커널 실전 활용 팩트: 선배님이 “여지” 커널 boot.S에 짜두신 mrs x0, mpidr_el1 신분증 검사 기억하시죠?
- 그때 and x0, x0, #0xFF 하신 것도 상남자 스타일이지만, UBFX x0, x0, #0, #8로 쓰시면
- “0번 비트부터 8비트(코어 ID 필드)를 뽑아라”가 되어 코드가 훨씬 더 우아하고 직관적인 책 읽기가 됩니다