최규상 님의 KOCW 강의 "컴퓨터 구조"를 정리한 글입니다.
* David A. Patterson님과 John L. Hennessy 님의
"컴퓨터 구조 및 설계" 책을 교제로 한 강의입니다. (책의 내용은 포함되지 않았습니다)
1. MIPS Addressing for 32-Bit Immediates and Addresses
32-bit Constants
- I-Format 명령어에서 즉시 값은 16비트만 저장 가능 (MIPS의 레지스터 크기는 4byte)
- 따라서 32bit를 처리하려면 2개의 instruction이 필요
lui $s0, 61 # $s0의 상위 16비트에 61을 저장 (lui: Load Upper Immediate)
ori $s0, $s0, 2304 # $s0의 하위 16비트에 2304를 추가 (ori: bitwise OR)
Branch Addressing
op (6bit) | rs (5bit) | rt (5bit) | offset (16bit)
- 분기 명령어는 32bit
- PC 값을 기준으로 16비트 오프셋을 적용하여 이동하는 방식
- offset 값이 16비트이므로 32비트 전체 주소를 표현할 수 없음
- 이를 해결하기 위해 CPU에서 Target Address 값을 만들때 필요한 offset값만 전달하여 표현함
- Target Address = PC + offset * 4
Loop:
sll $t1, $s3, 2 # $t1 = $s3 * 4 (배열 인덱스 계산)
add $t1, $t1, $s6 # 배열 시작 주소($s6) + 인덱스($t1)
lw $t0, 0($t1) # 메모리에서 데이터 로드
bne $t0, $s5, Exit # 값이 다르면 Exit으로 분기
addi $s3, $s3, 1 # 인덱스 증가
j Loop # 다시 Loop로 점프
Exit:
Branching Far Away
- Target Address가 너무 멀어 offset 값으로 표현이 안되면 어셈블러는 Jump Address로 재작성하여 수행함
Jump Addressing
- 실행 흐름을 변경하기 위한 명령어
구조
op (6bit) | address (26bit)
- address (26 bits)
- Jump 명령어에서 분기할 타겟 주소를 나타냅니다
- Target Address
- PC & 0xF0000000 | (address * 4)
- PC & 0xF0000000: 같은 프로그램 내 명령어만 읽으므로 상위 4비트만 가져옴
- address * 4: 오프셋값을 26비트로 표현합니다. (4바이트로 메모리가 align되어 있기 때문)
2. Parallelism and Instructions: Synchronization
Synchronization Issue
- 여러개의 프로세스가 공유 메모리 영역을 접근할 경우, 데이터 레이스가 발생할 수 있음
- 데이터 레이스는 동기화가 이루어지지 않아 예측 불가능한 결과를 초래할 수 있음
하드웨어 지원
- 동기화를 보장하기 위해 하드웨어 수준에서 원자적 연산을 지원해야 함
- atomic read/write memory operation
- 하나의 연산이 인터럽트 없이 한번에 실행 및 완료되어야 함
- 실행 중 다른 프로세스가 해당 메모리 영역의 접근을 제한함
- 이를 활용해서 spin lock이 구현됨
spin lock
- 락을 획득하려는 스레드가 CPU를 사용해서 락이 풀릴 때까지 반복적으로 확인하는 방식
- 락이 해제되면, 해당 스레드는 즉시 락을 획득하고 임계 구역으로 진입할 수 있음
- 락을 획득하지 못한 스레드는 대기 상태가 되지 않고 계속해서 루프를 돌며 기다림
MIPS에서의 동기화 명령어
load linked
- ll rt, offset(rs)
store conditional
- sc rt, offset(rs)
3. Translating and Starting a Program
Translation
- Compile
- C Program -> (Compiler) -> Assembly language program (.s)
- Assemble
- 어셈블러가 어셈블리 코드를 기계어로 변환
- Assembly language program (.s) -> (Assembler) -> Object: Machine Language module (.o)
- Object: Library - Machine Language도 함께 변환됨
- Link
- 여러 오브젝트 파일과 라이브러리를 하나의 실행 가능한 바이너리 파일로 결합
- Object: Machine Language module (+ Library) -> (Linker) -> Executable: Machine Language
- Load
- 실행 파일을 메모리에 적재
- 운영체제가 실행을 시작할 준비를 함
Assembler Pseudoinstructions
- 어셈블러가 어셈블리언어(수도코드)를 기계어로 변환해줌
Object Module 구성
구성 요소 | 설명 |
Header |
메타데이터 (파일 크기, 세그먼트 정보, 심볼 테이블 위치)
|
Text Segment |
실행할 기계어 코드 저장
|
Static Data Segment |
초기화된 전역 변수 및 정적 변수 저장
|
Relocation Info |
주소가 확정되지 않은 심볼 정보
|
Symbol Table |
심볼 정보 (변수, 함수 등)
|
Debug Info |
디버깅 정보 (변수 이름, 소스 코드 라인 번호)
|
Linking Object Modules
1. 세그먼트 합치기
- 여러 오브젝트 파일에서 나온 Text Segment, Data Segment 등을 하나로 합침
- 같은 text, data, bss 영역을 병합하여 하나의 실행 파일로 만듦
2. 레이블 해결 (주소 결정)
- 함수 호출 및 변수 참조를 위해 실제 메모리 주소를 할당
3. external refs 해결
- 한 오브젝트 파일이 다른 오브젝트 파일의 심볼을 참조하는 경우
- 링커가 이를 찾아 연결함
4. location-dependent 해결
- 운영체제가 로더를 통해 실제 메모리에 적재할 때, 가상 주소를 실제 물리 주소로 다시 매핑
Loading a Program
- 실행 파일을 디스크에서 메모리로 올림
- 헤더로 세그먼트 사이즈 확인
- 가상 메모리 공간에 올림
- 직접 로드하지 않고 가상 주소를 설정
- 최소 필요한 부분만 물리 메모리에 적재하고 추가적으로 필요할 때 물리 메모리에 적재함
- 실행이 시작되면 MMU가 페이지 테이블을 조회하여 가상 주소를 물리 주소로 변환함
- 스택에 아규먼트 셋업
- 실행할 떄 전달된 명령줄 인자와 환경 변수를 스택에 저장
- 레지스터 초기화 (SP, PC 셋팅)
- 스타트업 루틴으로 점프
- C 런타임 초기화
- main() 함수 호출
출처