[TIL/크래프톤 정글9기] 41일차 (CSAPP Chapter.8.1 예외적 제어 흐름)

blueprint·2025년 6월 21일

크래프톤정글9기

목록 보기
35/55

CSAPP Chapter 8.1 - 예외적 제어 흐름 (Exceptional Control Flow)

서론: 제어 흐름의 기본 개념

프로그램 카운터와 제어 흐름

프로세서에 전원이 공급되는 순간부터 전원이 차단될 때까지, 프로그램 카운터(PC)는 다음과 같은 주소 시퀀스를 가정합니다:

a₀, a₁, ..., aₙ₋₁

여기서:

  • 각 aₖ: 해당하는 명령어 Iₖ의 주소
  • 제어 전이(Control Transfer): aₖ에서 aₖ₊₁로의 각 전환
  • 제어 흐름(Control Flow): 이러한 제어 전이들의 시퀀스

일반적인 제어 흐름 패턴

1. 순차적(Smooth) 제어 흐름

  • 특징: 각 Iₖ와 Iₖ₊₁이 메모리에서 인접
  • 가장 단순한 형태: 연속적인 명령어 실행

2. 급작스러운 제어 흐름 변화

  • 발생 조건: Iₖ₊₁이 Iₖ에 인접하지 않음
  • 일반적인 원인:
    • 점프(Jump) 명령어
    • 호출(Call) 명령어
    • 반환(Return) 명령어
  • 목적: 프로그램 변수로 표현되는 내부 프로그램 상태 변화에 반응

시스템 상태 변화와 ECF의 필요성

내부 프로그램 변수로 캡처되지 않는 시스템 상태 변화들

  1. 하드웨어 타이머: 정기적으로 발생하는 타이머 인터럽트
  2. 네트워크 패킷: 네트워크 어댑터에 도착하여 메모리에 저장되어야 하는 패킷들
  3. 디스크 I/O: 프로그램이 디스크에서 데이터를 요청하고 데이터가 준비될 때까지 대기
  4. 프로세스 관리: 자식 프로세스를 생성한 부모 프로세스가 자식 프로세스 종료 알림을 받아야 함

예외적 제어 흐름 (Exceptional Control Flow, ECF)

정의: 이러한 상황들에 대응하기 위한 급작스러운 제어 흐름 변화

발생 레벨:

  • 하드웨어 레벨: 하드웨어가 감지한 이벤트가 예외 핸들러로의 급작스러운 제어 전이를 트리거
  • 운영체제 레벨: 커널이 컨텍스트 스위치를 통해 한 사용자 프로세스에서 다른 프로세스로 제어를 전이
  • 애플리케이션 레벨: 프로세스가 다른 프로세스에 시그널을 보내어 수신자의 시그널 핸들러로 급작스러운 제어 전이
  • 프로그램 레벨: 개별 프로그램이 오류에 반응하여 일반적인 스택 규칙을 우회하고 다른 함수의 임의 위치로 비지역 점프

ECF 이해의 중요성

1. 중요한 시스템 개념 이해

  • ECF는 운영체제가 I/O, 프로세스, 가상 메모리를 구현하는 기본 메커니즘
  • 이러한 중요한 아이디어들을 진정으로 이해하려면 먼저 ECF를 이해해야 함

2. 애플리케이션과 운영체제의 상호작용 이해

  • 시스템 콜(System Call): 애플리케이션이 ECF의 한 형태인 트랩을 사용하여 운영체제 서비스를 요청
  • 주요 서비스들:
    • 디스크에 데이터 쓰기
    • 네트워크에서 데이터 읽기
    • 새 프로세스 생성
    • 현재 프로세스 종료
  • 기본적인 시스템 콜 메커니즘 이해가 이러한 서비스들이 애플리케이션에 제공되는 방식을 이해하는 데 도움

3. 흥미로운 새로운 애플리케이션 프로그램 작성

  • 운영체제가 제공하는 강력한 ECF 메커니즘들:
    • 새 프로세스 생성
    • 프로세스 종료 대기
    • 시스템의 예외적 이벤트를 다른 프로세스에 알림
    • 이러한 이벤트 감지 및 응답
  • 활용 예시: Unix 셸, 웹 서버 등

4. 동시성(Concurrency) 이해

  • ECF는 컴퓨터 시스템에서 동시성을 구현하는 기본 메커니즘
  • 동시성의 예시들:
    • 애플리케이션 프로그램 실행을 중단하는 예외 핸들러
    • 실행 시간이 겹치는 프로세스와 스레드
    • 애플리케이션 프로그램 실행을 중단하는 시그널 핸들러
  • ECF 이해는 동시성 이해의 첫 번째 단계 (Chapter 12에서 더 자세히 다룸)

5. 소프트웨어 예외 작동 방식 이해

  • 고급 언어 예외 메커니즘: C++, Java의 try, catch, throw 문
  • 소프트웨어 예외: 오류 조건에 응답하여 비지역 점프(일반적인 호출/반환 스택 규칙을 위반하는 점프) 허용
  • C 언어의 비지역 점프: setjmp, longjmp 함수를 통한 애플리케이션 레벨 ECF
  • 이러한 저수준 함수들의 이해가 고수준 소프트웨어 예외 구현 방식을 이해하는 데 도움

Chapter 8의 학습 목표

시스템 상호작용의 전환점

  • 이전까지: 애플리케이션이 하드웨어와 상호작용하는 방식 학습
  • 이번 장: 애플리케이션이 운영체제와 상호작용하는 방식 학습 시작
  • 핵심: 이러한 모든 상호작용이 ECF를 중심으로 이루어짐

학습 내용 구조

1. 예외 (Exceptions)

  • 위치: 하드웨어와 운영체제의 교차점
  • 구현: 하드웨어와 운영체체가 부분적으로 구현

2. 시스템 콜 (System Calls)

  • 정의: 애플리케이션에 운영체제로의 진입점을 제공하는 예외

3. 프로세스와 시그널 (Processes and Signals)

  • 위치: 애플리케이션과 운영체제의 교차점
  • 추상화 레벨: 한 단계 위의 추상화

4. 비지역 점프 (Nonlocal Jumps)

  • 정의: 애플리케이션 레벨의 ECF 형태

8.1 예외 (Exceptions)

예외의 정의와 특징

예외: 프로세서 상태의 어떤 변화에 응답하여 발생하는 급작스러운 제어 흐름 변화

구현 특징

  • 부분적 하드웨어 구현: 하드웨어에서 부분적으로 구현
  • 부분적 운영체제 구현: 운영체제에서 부분적으로 구현
  • 시스템별 차이: 하드웨어에서 부분적으로 구현되므로 시스템마다 세부사항이 다름
  • 공통 기본 아이디어: 모든 시스템에서 기본 아이디어는 동일

예외의 기본 구조

예외 발생 과정

  1. 현재 명령어 실행: 프로세서가 현재 명령어 Icurr 실행 중
  2. 상태 변화 감지: 프로세서 상태에 중요한 변화 발생
  3. 이벤트 인식: 상태 변화를 이벤트로 인식
  4. 예외 트리거: 이벤트에 응답하여 예외 발생
  5. 핸들러 호출: 예외 테이블을 통한 간접 프로시저 호출로 적절한 예외 핸들러 실행

이벤트의 종류

1. 현재 명령어 실행과 직접 관련된 이벤트
  • 가상 메모리 페이지 폴트: 참조된 페이지가 메모리에 없음
  • 산술 오버플로우: 계산 결과가 표현 범위를 초과
  • 0으로 나누기: 나눗셈에서 0으로 나누려는 시도
2. 현재 명령어 실행과 무관한 이벤트
  • 시스템 타이머: 시스템 타이머가 만료됨
  • I/O 요청 완료: I/O 작업이 완료됨

예외 처리 완료 후 가능한 동작

프로세서가 이벤트 발생을 감지하면, 예외 테이블을 통해 해당 이벤트를 처리하도록 특별히 설계된 운영체제 서브루틴(예외 핸들러)을 호출합니다.

예외 핸들러가 처리를 완료하면, 예외를 발생시킨 이벤트 유형에 따라 다음 세 가지 중 하나가 발생합니다:

1. 현재 명령어로 제어 반환

  • 반환 대상: Icurr (이벤트가 발생했을 때 실행 중이던 명령어)
  • 사용 경우: 복구 가능한 오류 상황

2. 다음 명령어로 제어 반환

  • 반환 대상: Inext (예외가 발생하지 않았다면 다음에 실행되었을 명령어)
  • 사용 경우: 정상적인 예외 처리 완료

3. 중단된 프로그램 종료

  • 동작: 프로그램 실행을 완전히 중단
  • 사용 경우: 복구 불가능한 심각한 오류

8.1.1 예외 처리 (Exception Handling)

하드웨어와 소프트웨어의 협력

예외 처리는 하드웨어와 소프트웨어 간의 긴밀한 협력을 포함하므로 이해하기 어려울 수 있습니다. 어떤 구성요소가 어떤 작업을 수행하는지에 대해 혼동이 생기기 쉽습니다.

예외 번호 할당

예외 번호의 특징

  • 고유성: 시스템의 각 가능한 예외 유형에는 고유한 음이 아닌 정수 예외 번호가 할당됨
  • 할당 주체 구분:
1. 프로세서 설계자가 할당하는 번호
  • 0으로 나누기
  • 페이지 폴트
  • 메모리 접근 위반
  • 브레이크포인트
  • 산술 오버플로우
2. 운영체제 커널 설계자가 할당하는 번호
  • 시스템 콜
  • 외부 I/O 장치로부터의 시그널

커널: 메모리에 상주하는 운영체제의 부분

예외 테이블 (Exception Table)

초기화 과정

시스템 부팅 시 (컴퓨터가 리셋되거나 전원이 켜질 때):

  • 운영체제가 예외 테이블이라는 점프 테이블을 할당하고 초기화
  • 엔트리 k: 예외 k에 대한 핸들러의 주소를 포함

예외 테이블 구조

런타임 예외 처리 과정

1. 이벤트 감지 및 예외 번호 결정

  • 시점: 시스템이 어떤 프로그램을 실행하는 런타임
  • 프로세서 동작:
    1. 이벤트 발생 감지
    2. 해당하는 예외 번호 k 결정

2. 예외 핸들러 주소 계산

예외 핸들러 주소 = 예외 테이블 베이스 레지스터 + (예외 번호 × 8)
  • 예외 테이블 베이스 레지스터: 예외 테이블의 시작 주소를 포함하는 특수 CPU 레지스터
  • 예외 번호: 예외 테이블의 인덱스 역할
  • 곱하기 8: 64비트 시스템에서 주소가 8바이트이므로

3. 간접 프로시저 호출

  • 방법: 예외 테이블의 엔트리 k를 통한 간접 프로시저 호출
  • 대상: 해당하는 핸들러로 제어 전이

예외와 프로시저 호출의 차이점

유사점

  • 스택 사용: 핸들러로 분기하기 전에 반환 주소를 스택에 푸시

주요 차이점

1. 반환 주소의 차이
  • 프로시저 호출: 항상 다음 명령어 주소
  • 예외: 예외 클래스에 따라 다름
    • 현재 명령어: 이벤트가 발생했을 때 실행 중이던 명령어
    • 다음 명령어: 이벤트가 발생하지 않았다면 실행되었을 명령어
2. 추가 프로세서 상태 저장
  • 목적: 중단된 프로그램을 핸들러 반환 시 재시작하는 데 필요
  • 예시 (x86-64): 현재 조건 코드를 포함하는 EFLAGS 레지스터 등을 스택에 푸시
3. 스택 위치의 차이
  • 사용자 프로그램 → 커널: 모든 항목들이 사용자 스택이 아닌 커널 스택에 푸시
  • 이유: 보안과 격리를 위함
4. 실행 모드
  • 예외 핸들러: 커널 모드에서 실행 (Section 8.2.4 참조)
  • 권한: 모든 시스템 리소스에 완전한 접근 권한

소프트웨어에서의 예외 처리 완료

하드웨어의 역할 완료

하드웨어가 예외를 트리거하면, 나머지 작업은 예외 핸들러에 의해 소프트웨어에서 수행됩니다.

예외 핸들러의 작업 완료 후

  1. 이벤트 처리: 핸들러가 이벤트를 처리
  2. 선택적 반환: 특수한 "인터럽트로부터 반환" 명령어 실행
  3. 상태 복원:
    • 적절한 상태를 프로세서의 제어 및 데이터 레지스터로 다시 팝
    • 예외가 사용자 프로그램을 중단했다면 사용자 모드로 상태 복원 (Section 8.2.4 참조)
  4. 제어 반환: 중단된 프로그램으로 제어 반환

이러한 과정을 통해 예외 처리가 완료되고 시스템이 정상적인 실행을 재개할 수 있습니다.

CSAPP Chapter 8.1.2-8.1.3 - 예외 클래스와 Linux/x86-64 예외 정리

8.1.2 예외의 클래스 (Classes of Exceptions)

예외 분류 체계

예외는 네 가지 클래스로 분류됩니다: 인터럽트(Interrupts), 트랩(Traps), 폴트(Faults), 어보트(Aborts)

예외 클래스 요약표

클래스원인비동기/동기반환 동작
InterruptI/O 장치로부터의 시그널비동기항상 다음 명령어로 반환
Trap의도적인 예외동기항상 다음 명령어로 반환
Fault잠재적으로 복구 가능한 오류동기현재 명령어로 반환하거나 중단
Abort복구 불가능한 오류동기절대 반환하지 않음

비동기 예외: 프로세서 외부의 I/O 장치 이벤트 결과로 발생
동기 예외: 명령어 실행의 직접적인 결과로 발생

1. 인터럽트 (Interrupts)

인터럽트의 특징

  • 발생 방식: 프로세서 외부의 I/O 장치로부터의 시그널 결과로 비동기적으로 발생
  • 비동기성: 특정 명령어의 실행으로 인해 발생하지 않음
  • 핸들러 명칭: 하드웨어 인터럽트를 위한 예외 핸들러를 인터럽트 핸들러라고 부름

인터럽트 처리 과정

인터럽트 트리거 메커니즘

  1. I/O 장치의 시그널링:

    • 네트워크 어댑터, 디스크 컨트롤러, 타이머 칩 등이 인터럽트 트리거
    • 프로세서 칩의 핀에 시그널을 보냄
    • 시스템 버스에 인터럽트를 발생시킨 장치를 식별하는 예외 번호를 배치
  2. 프로세서의 응답:

    • 현재 명령어 실행 완료
    • 인터럽트 핀이 high가 된 것을 감지
    • 시스템 버스에서 예외 번호를 읽음
    • 적절한 인터럽트 핸들러 호출
  3. 핸들러 반환:

    • 핸들러가 반환할 때 다음 명령어로 제어 반환
    • 즉, 인터럽트가 발생하지 않았다면 제어 흐름에서 현재 명령어를 따랐을 명령어
    • 효과: 프로그램이 인터럽트가 전혀 발생하지 않은 것처럼 계속 실행

2. 트랩과 시스템 콜 (Traps and System Calls)

트랩의 특징

  • 발생 방식: 명령어 실행의 결과로 발생하는 의도적인 예외
  • 반환 동작: 인터럽트 핸들러와 마찬가지로 트랩 핸들러는 다음 명령어로 제어 반환
  • 가장 중요한 용도: 사용자 프로그램과 커널 간에 시스템 콜이라는 프로시저 유사 인터페이스 제공

시스템 콜의 필요성

사용자 프로그램이 자주 요청하는 커널 서비스들:

  • read: 파일 읽기
  • fork: 새 프로세스 생성
  • execve: 새 프로그램 로드
  • exit: 현재 프로세스 종료

시스템 콜 메커니즘

syscall 명령어
  • 제공: 프로세서가 특수한 syscall n 명령어 제공
  • 사용법: 사용자 프로그램이 서비스 n을 요청하고 싶을 때 실행
  • 동작: syscall 명령어 실행 시 인수를 디코딩하고 적절한 커널 루틴을 호출하는 예외 핸들러로의 트랩 발생
시스템 콜 처리 과정

시스템 콜과 일반 함수 호출의 차이

프로그래머 관점
  • 시스템 콜: 일반 함수 호출과 동일하게 보임
구현 관점의 차이

일반 함수:

  • 실행 모드: 사용자 모드에서 실행
  • 명령어 제한: 실행할 수 있는 명령어 유형에 제한
  • 스택 접근: 호출 함수와 동일한 스택에 접근

시스템 콜:

  • 실행 모드: 커널 모드에서 실행
  • 특권 명령어: 특권 명령어 실행 허용
  • 스택 접근: 커널에서 정의된 스택에 접근
  • 자세한 내용: Section 8.2.4에서 사용자 모드와 커널 모드에 대해 더 자세히 논의

3. 폴트 (Faults)

폴트의 특징

  • 발생 원인: 핸들러가 수정할 수 있을 가능성이 있는 오류 조건으로부터 발생
  • 처리 방식: 폴트 발생 시 프로세서가 폴트 핸들러로 제어 전이

폴트 처리 결과

1. 오류 수정 성공
  • 동작: 핸들러가 오류 조건을 수정할 수 있는 경우
  • 반환: 폴팅 명령어로 제어 반환하여 재실행
2. 오류 수정 실패
  • 동작: 핸들러가 오류를 수정할 수 없는 경우
  • 반환: 폴트를 발생시킨 애플리케이션 프로그램을 종료하는 커널의 어보트 루틴으로 반환

폴트 처리 과정

페이지 폴트 예제

페이지 폴트 예외: 폴트의 고전적인 예제

발생 조건
  • 명령어가 가상 주소를 참조
  • 해당하는 페이지가 메모리에 상주하지 않음
  • 따라서 디스크에서 검색해야 함
처리 과정
  1. 페이지 폴트 핸들러: 디스크에서 적절한 페이지를 로드
  2. 제어 반환: 폴트를 발생시킨 명령어로 제어 반환
  3. 명령어 재실행: 명령어가 다시 실행될 때 적절한 페이지가 메모리에 상주
  4. 성공적 완료: 명령어가 폴팅 없이 완료까지 실행 가능

페이지: 연속적인 가상 메모리 블록 (일반적으로 4KB)
자세한 내용: Chapter 9에서 확인

4. 어보트 (Aborts)

어보트의 특징

  • 발생 원인: 복구 불가능한 치명적 오류
  • 일반적 원인: DRAM이나 SRAM 비트가 손상될 때 발생하는 패리티 오류 등의 하드웨어 오류
  • 반환 특성: 어보트 핸들러는 절대로 애플리케이션 프로그램으로 제어를 반환하지 않음

어보트 처리 과정

어보트 결과

  • 핸들러 동작: 애플리케이션 프로그램을 종료하는 어보트 루틴으로 제어 반환
  • 최종 결과: 애플리케이션 프로그램 완전 종료

8.1.3 Linux/x86-64 시스템의 예외들

예외 번호 체계

전체 예외 유형

  • 총 개수: 최대 256개의 서로 다른 예외 유형

예외 번호 범위 분류

1. 범위 0-31: Intel 아키텍트 정의 예외
  • 정의자: Intel 아키텍트
  • 특징: 모든 x86-64 시스템에서 동일
  • 예시: 프로세서 레벨에서 정의된 기본 예외들
2. 범위 32-255: 운영체제 정의 예외
  • 정의자: 운영체제
  • 내용: 인터럽트와 트랩
  • 특징: 운영체제별로 다를 수 있음

주요 x86-64 예외 예시

예외 번호설명예외 클래스
0Divide errorFault
13General protection faultFault
14Page faultFault
18Machine checkAbort
32–255OS-defined exceptionsInterrupt/Trap

Linux/x86-64 폴트와 어보트

1. Divide Error (예외 0)

발생 조건

  • 애플리케이션이 0으로 나누기를 시도
  • 나눗셈 명령어의 결과가 목적지 피연산자에 비해 너무 큰 경우

처리 방식

  • Unix 정책: divide error로부터 복구를 시도하지 않음
  • 대신: 프로그램 중단을 선택
  • 셸 보고: Linux 셸은 일반적으로 divide error를 "Floating exceptions"로 보고

2. General Protection Fault (예외 13)

발생 원인 (다양한 이유)

  • 정의되지 않은 가상 메모리 영역 참조: 프로그램이 정의되지 않은 가상 메모리 영역을 참조
  • 읽기 전용 텍스트 세그먼트에 쓰기 시도: 프로그램이 읽기 전용 텍스트 세그먼트에 쓰기를 시도

처리 방식

  • Linux 정책: 이 폴트로부터 복구를 시도하지 않음
  • 셸 보고: Linux 셸은 일반적으로 general protection fault를 "Segmentation faults"로 보고

3. Page Fault (예외 14)

특징

  • 폴팅 명령어가 재시작되는 예외의 예시
  • 처리 방식: 핸들러가 디스크의 적절한 가상 메모리 페이지를 물리 메모리 페이지로 매핑한 다음 폴팅 명령어를 재시작

작동 원리

  • 자세한 내용: Chapter 9에서 페이지 폴트가 어떻게 작동하는지 상세히 확인

4. Machine Check (예외 18)

발생 원인

  • 치명적 하드웨어 오류: 폴팅 명령어 실행 중에 감지되는 치명적 하드웨어 오류의 결과로 발생

처리 방식

  • 복구 불가능: Machine check 핸들러는 절대로 애플리케이션 프로그램으로 제어를 반환하지 않음

Linux/x86-64 시스템 콜

시스템 콜 개요

제공 범위

  • Linux: 애플리케이션 프로그램이 커널로부터 서비스를 요청할 때 사용할 수 있는 수백 개의 시스템 콜 제공

주요 서비스

  • 파일 읽기
  • 파일 쓰기
  • 새 프로세스 생성
  • 기타 다양한 시스템 서비스

인기 있는 Linux 시스템 콜 예시

번호이름설명번호이름설명
0read파일 읽기33pause시그널 도착까지 프로세스 일시정지
1write파일 쓰기37alarm알람 시그널 전달 예약
2open파일 열기39getpid프로세스 ID 얻기
3close파일 닫기57fork프로세스 생성
4stat파일에 대한 정보 얻기59execve프로그램 실행
9mmap메모리 페이지를 파일에 매핑60_exit프로세스 종료
12brk힙의 상단 재설정61wait4프로세스 종료 대기
32dup2파일 디스크립터 복사62kill프로세스에 시그널 전송

시스템 콜 인터페이스

시스템 콜 점프 테이블

  • 각 시스템 콜: 커널의 점프 테이블에서 오프셋에 해당하는 고유한 정수 번호를 가짐
  • 주의: 이 점프 테이블은 예외 테이블과는 다름

C 프로그램에서의 시스템 콜 사용

1. 직접 호출 방법
// syscall 함수를 사용한 직접 호출
syscall(시스템콜번호, 인수1, 인수2, ...);
  • 실제 사용: 실제로는 거의 필요하지 않음
2. 래퍼 함수 사용 (일반적 방법)
  • C 표준 라이브러리: 대부분의 시스템 콜에 대해 편리한 래퍼 함수 집합 제공
  • 래퍼 함수의 역할:
    1. 인수들을 패키징
    2. 적절한 시스템 콜 명령어로 커널에 트랩
    3. 시스템 콜의 반환 상태를 호출 프로그램에 다시 전달

용어 정의

  • 시스템 레벨 함수: 이 텍스트에서는 시스템 콜과 관련 래퍼 함수를 상호 교환적으로 지칭

x86-64에서의 시스템 콜 구현

syscall 명령어

  • 제공: x86-64 시스템에서 syscall이라는 트래핑 명령어를 통해 시스템 콜 제공
  • 흥미로운 점: 프로그램이 이 명령어를 사용하여 Linux 시스템 콜을 직접 호출하는 방법 연구

인수 전달 방식

레지스터 사용 (스택 사용 안 함)
  • 모든 인수: 일반 목적 레지스터를 통해 전달
  • 레지스터 할당 규칙:
    • %rax: 시스템콜 번호 포함
    • 최대 6개 인수: %rdi, %rsi, %rdx, %r10, %r8, %r9에 순서대로 배치
    • 인수 순서: 첫 번째 인수는 %rdi, 두 번째는 %rsi, 이런 식으로 계속

반환 값 처리

  • 시스템 콜 반환 시:
    • %rcx와 %r11: 파괴됨 (destroyed)
    • %rax: 반환 값 포함
  • 오류 표시: -4,095와 -1 사이의 음수 반환 값은 음수 errno에 해당하는 오류를 나타냄

시스템 콜 사용 예제

Hello 프로그램 - printf 대신 write 사용

int main()
{
    write(1, "hello, world\n", 13);
    _exit(0);
}
인수 설명
  • 첫 번째 인수 (1): stdout으로 출력 전송
  • 두 번째 인수: 쓸 바이트 시퀀스
  • 세 번째 인수: 쓸 바이트 수

어셈블리 언어 버전

.section .data
string:
    .ascii "hello, world\n"
string_end:
    .equ len, string_end - string

.section .text
.globl main
main:
    # First, call write(1, "hello, world\n", 13)
    movq $1, %rax        # write는 시스템 콜 1
    movq $1, %rdi        # Arg1: stdout은 디스크립터 1을 가짐
    movq $string, %rsi   # Arg2: hello world 문자열
    movq $len, %rdx      # Arg3: 문자열 길이
    syscall              # 시스템 콜 수행

    # Next, call _exit(0)
    movq $60, %rax       # _exit는 시스템 콜 60
    movq $0, %rdi        # Arg1: 종료 상태는 0
    syscall              # 시스템 콜 수행
코드 분석

write 시스템 콜 (라인 9-13):
1. 라인 9: write 시스템 콜 번호를 %rax에 저장
2. 라인 10-12: 인수 리스트 설정
3. 라인 13: syscall 명령어로 시스템 콜 호출

_exit 시스템 콜 (라인 14-16):
1. 라인 14: _exit 시스템 콜 번호를 %rax에 저장
2. 라인 15: 종료 상태 인수 설정
3. 라인 16: syscall 명령어로 시스템 콜 호출

용어에 대한 참고사항

예외 클래스 용어의 시스템별 차이

프로세서 ISA 명세서:

  • 구분: 비동기 "인터럽트"와 동기 "예외"를 구분
  • 문제: 이러한 매우 유사한 개념들을 지칭하는 포괄적 용어가 없음

이 텍스트의 용어 사용:

  • "예외와 인터럽트" 및 "예외 또는 인터럽트"를 계속 언급하는 것을 피하기 위해
  • "예외"를 일반적인 용어로 사용
  • 비동기 예외(인터럽트)와 동기 예외(트랩, 폴트, 어보트)는 적절한 경우에만 구분

중요한 점:

  • 기본 아이디어: 모든 시스템에서 동일
  • 제조업체 매뉴얼: 일부 제조업체는 "예외"라는 단어를 동기 이벤트로 인한 제어 흐름 변화만을 지칭하는 데 사용

따라서 독자는 시스템별로 용어 사용에 차이가 있음을 인지해야 합니다.

0개의 댓글