오늘 한 것
- CSAPP 3.1 ~ 3.3 정리
- 기계어, 어셈블리, 고급 언어의 관계 정리
- x86-64의 가상 주소 체계(정규 주소 형식) 학습
- ISA(Instruction Set Architecture)의 인코딩 규칙과 CPU 실행 과정 복습
- 실행 파일이 메모리에 적재되고 PC를 통해 실행되는 흐름 이해
오늘 배운 것
-
기계어를 배워야 하는 이유
- 고급 언어가 생산적이고 안정적이지만, 성능 최적화를 위해서는 어셈블리·기계어 수준에서 동작을 볼 줄 알아야 한다.
- 추상화 계층 뒤에 감춰진 런타임 동작을 이해하려면 ISA 레벨 분석이 필요하다.
-
x86-64 주소 공간
-
가상 주소는 64비트지만 **정규 주소 형식(canonical form)**을 따라야 한다.
-
실제 유효 주소는 하위 48비트. 상위 16비트는 47번 비트 값으로 sign extension된다.
-
범위:
- 사용자 공간 →
0x0000000000000000~0x00007FFFFFFFFFFF - 커널 공간 →
0xFFFF800000000000~0xFFFFFFFFFFFFFFFF
- 사용자 공간 →
-
-
명령어 인코딩 규칙
-
CPU는 “파일 전체에서 코드/데이터를 구분”하지 않고, PC가 가리키는 바이트를 명령어로 해석한다.
-
해석 기준은 오직 ISA 인코딩 규칙.
-
인코딩 형태:
- 고정 길이 ISA (예: RISC-V): 단순, PC는 일정 간격으로 증가
- 가변 길이 ISA (예: x86): 프리픽스~즉시값 순서로 읽으며 길이를 결정 → 디코더 복잡
-
-
실행 흐름
- 실행 파일 → OS 로더가 메모리 적재 → 시작 주소를 PC에 넣음
- CPU 파이프라인: Fetch → Decode → Execute → Memory → Writeback → PC 업데이트
-
추가 포인트
- 엔디안은 단순히 바이트 나열 방식일 뿐, 명령어 경계와 무관
- 일부 ISA는 정렬(Alignment) 제약을 강제
- CPU는 코드와 데이터를 구분 못 하므로 NX 같은 보호 기법이 필요
- 즉시값/분기 오프셋은 여러 비트를 이어붙이고 부호 확장 규칙을 적용
느낀 점
- 단순히 “C 코드가 컴파일돼 실행된다”가 아니라, ISA 규칙에 따라 PC가 해석하는 과정이라는 점을 명확히 이해했다.
- 특히 정규 주소 형식이 단순히 "상위 16비트=0"이 아니라, 47번 비트 sign extension 규칙이라는 걸 새롭게 알게 됐다.
- 추상화된 언어만 쓰다 보면, 내부에서 어떻게 “실제 명령어”가 실행되는지 감을 잃기 쉽다. 기계어를 공부하는 이유가 단순한 호기심이 아니라, 성능과 안정성을 확보하기 위한 기반이라는 사실을 체감했다.