Skip to the content.

ISB 명령어 (Instruction Synchronization Barrier)

Summary

정의: 파이프라인에 남아있는 모든 이전 명령어의 실행 결과를 완전히 반영시키고, 그 이후의 명령어를 다시 페치(fetch) 하도록 강제하는 배리어(barrier) 명령어. 명령어 스트림 자체의 일관성을 보장하는 목적으로 사용됨.


문법

ISB
ISB SY          // SY(System) 옵션, 사실상 ISB와 동일 (기본값)

특징: 오퍼랜드가 없거나, 있어도 SY 하나만 실질적 의미를 가짐(다른 옵션은 정의되어 있지 않거나 무시됨).


왜 필요한가 — 파이프라인과 명령어 캐시의 문제

핵심 배경: 최신 CPU는 성능을 위해 명령어 파이프라이닝명령어 프리페치(prefetch), 명령어 캐시(I-cache) 를 적극 활용함. 즉, CPU는 실행 중인 명령어보다 앞서서 다음 명령어들을 미리 읽어들이고 디코딩해둠.

문제 상황: 만약 프로그램이 자기 자신의 코드(명령어 영역)를 수정하거나, 시스템 레지스터(MMU 설정, 캐시 설정, 예외 벡터 등)를 변경한 직후 그 효과에 의존하는 명령어를 실행하려 하면, CPU가 이미 파이프라인에 미리 읽어들인 낡은(stale) 명령어를 그대로 실행할 위험이 있음.

ISB의 역할: “지금까지의 변경사항을 확실히 반영한 뒤, 이후 명령어는 새로 페치해서 실행하라”고 CPU에 명시적으로 지시함.


대표적 사용 상황

1. 자체 수정 코드 (Self-Modifying Code)

// 메모리에 새 명령어를 써넣은 직후
str w0, [x1]      // 코드 영역에 새 명령어 바이트 기록
dc  cvau, x1        // 데이터 캐시를 명령어 캐시와 동기화 (관련 캐시 관리 명령)
dsb ish              // 캐시 정리 작업이 완료됨을 보장 (아래 DSB 설명 참조)
ic  ivau, x1         // 명령어 캐시 무효화
dsb ish
isb                    // 파이프라인에 남은 낡은 명령어를 비우고 새로 페치하도록 강제
// 이 시점부터 새로 작성한 명령어가 정상적으로 실행됨

실전 맥락: JIT(Just-In-Time) 컴파일러가 런타임에 기계어 코드를 생성한 직후 반드시 이 절차를 거쳐야 함. macOS/iOS의 JavaScriptCore(WebKit JS 엔진) 같은 JIT 엔진 내부에서 필수적으로 등장하는 패턴.


2. 시스템 레지스터 변경 직후 (MMU, 예외 레벨 설정 등)

msr sctlr_el1, x0     // 시스템 제어 레지스터(예: MMU 활성화) 변경
isb                      // 변경사항이 이후 명령어 실행에 확실히 반영되도록 강제
// 이 시점 이후의 명령어는 새 설정이 적용된 상태로 페치됨

필요성: MSR로 시스템 레지스터를 바꾸는 것과, 그 변경이 실제로 명령어 페치·실행 파이프라인에 영향을 미치는 시점 사이에는 지연(latency)이 있을 수 있음. ISB 없이 바로 다음 명령어를 실행하면, 여전히 이전 설정 기준으로 동작할 위험이 있음.

커널/부트로더 맥락: MMU 활성화, 캐시 활성화, 예외 벡터 테이블(VBAR_EL1) 설정 등 시스템 초기화 코드에서 거의 예외 없이 등장함.


DSB / DMB와의 관계 — 배리어 3형제

핵심 구분: ARM64에는 목적이 다른 세 가지 배리어 명령어가 존재하며, 자주 혼동됨.

명령어 정식 명칭 보장 대상 용도
DMB Data Memory Barrier 데이터 접근 순서 메모리 읽기/쓰기 순서 보장
DSB Data Synchronization Barrier 데이터 접근 완료 이전 메모리 연산이 완전히 끝날 때까지 대기
ISB Instruction Synchronization Barrier 명령어 페치/실행 파이프라인 플러시, 명령어 재페치 강제

차이를 직관적으로 정리하면:

세 개를 함께 쓰는 이유 — 자체 수정 코드 예제 재분석:

dc  cvau, x1     // 데이터 캐시로 새 명령어 write-back
dsb ish             // ① 이 write-back이 완전히 끝날 때까지 대기 (DATA 완료 보장)
ic  ivau, x1        // 명령어 캐시 무효화 요청
dsb ish             // ② 이 무효화가 완전히 끝날 때까지 대기 (DATA 완료 보장)
isb                   // ③ 파이프라인에 남은 낡은 명령어 페치 결과를 버리고 재페치 (INSTRUCTION 신선도 보장)

판단 기준: DSB까지는 “데이터(캐시 조작 등)가 실제로 메모리 계층에 반영되었는가”를 보장하고, ISB는 그 이후 “CPU가 실행할 명령어 자체를 새로 읽어오는가”를 보장함. 이 둘은 보장하는 대상이 다르므로 자체 수정 코드 시나리오에서는 반드시 DSB 다음에 ISB를 함께 써야 완전한 안전성이 확보됨.


이전 WFE 문서와의 연결 — 예외 처리 맥락

커널 예외 벡터 설정 예시:

msr vbar_el1, x0    // 예외 벡터 테이블 베이스 주소 설정
isb                     // 이 설정이 확실히 반영된 후 명령어 페치가 이루어지도록 보장
// 이 시점 이후 발생하는 예외는 새 벡터 테이블을 정상적으로 참조함

만약 ISB 없이 진행하면: 파이프라인에 이미 올라와 있던 명령어들이 이전 벡터 테이블 기준으로 동작할 수 있어, 예외 발생 시 예측 불가능한 동작(크래시, 잘못된 핸들러 진입)으로 이어질 위험이 있음.


일반 애플리케이션에서의 사용 빈도

결론: ISB는 이전에 다룬 AT, WFE와 유사하게 일반 사용자 애플리케이션 코드에서는 거의 등장하지 않음. 다만 AT(EL1 이상 특권 필요)와 달리 ISB 자체는 EL0에서도 실행 가능한 명령어임.

실전 등장 맥락 정리:

맥락 등장 빈도
일반 앱 로직(계산, 문자열, 네트워크 등) 거의 없음
JIT 컴파일러(JavaScriptCore, V8 등) 높음 (자체 수정 코드 필수 요소)
커널/부트로더 초기화 코드 매우 높음 (MMU, 예외 벡터 설정 직후)
하이퍼바이저, 가상화 관련 코드 높음
디버거/프로파일러 내부 구현 중간 (동적 브레이크포인트 삽입 등)

종합 정리

항목 내용
목적 파이프라인의 낡은 명령어를 비우고 재페치 강제
특권 레벨 EL0에서도 실행 가능
짝을 이루는 명령어 DSB(데이터 완료 보장), DC/IC(캐시 관리)
대표 사용 맥락 JIT 코드 생성 직후, 시스템 레지스터 변경 직후
일반 앱 코드 관찰 빈도 매우 낮음

최종 요약: ISB는 “데이터가 메모리에 잘 반영되었는가”가 아니라 “CPU가 그 다음에 읽어들일 명령어 자체가 최신 상태인가” 를 보장하는 특수 목적 배리어임. 코드를 실행 중에 생성하거나(JIT), CPU 동작 방식 자체를 바꾸는(MMU, 예외 벡터) 저수준 시스템 프로그래밍에서는 필수적이지만, 일반적인 애플리케이션 로직에서는 개발자가 직접 마주칠 일이 거의 없는 명령어임.