대략적인 이해를 위해 먼저 사진을 보겠습니다.
우선, 시스템에서 제공하는 API를 애플리케이션이 직접 호출할 수 있는데, 이는 사용자 모드(Ring3)에서 가능합니다.
그러면 해당 API는 해당 시스템 호출 번호를 eax 레지스터에 저장한 다음(이 단계는 인라인 어셈블리를 통해 구현됨) int 0x80을 사용하여 인터럽트(인라인 어셈블리)를 트리거하고 인터럽트 처리 기능에 들어갑니다(이 기능은 완전히 어셈블리 코드로 작성됨), 이번에는 커널 상태(Ring0)로 들어갑니다.
인터럽트 처리 기능에서는 시스템 콜 번호에 해당하는 시스템 콜이 호출됩니다. 이 함수에서는 두 개의 레지스터 ds와 es가 커널 공간을 가리키도록 설정됩니다. 이러한 방식으로 사용자 모드에서 커널 모드로 데이터를 전송할 수 없습니다(예: open(const char * filename, int 플래그, ...)에서 파일 이름 포인터가 가리키는 문자열의 주소는 사용자 공간에 있습니다. 커널 공간의 해당 위치에서 검색하면 문자열이 전혀 존재하지 않습니다.) 어떻게 해야 합니까? 인터럽트 핸들러의 fs 레지스터가 사용자 공간을 가리키도록 설정되어 문제가 해결되었습니다.
시스템 호출에서는 파일 열기, 파일 쓰기 등 해당 작업이 수행됩니다.
처리가 끝나면 인터럽트 처리 기능으로 돌아가고 반환 값은 eax 레지스터에 저장됩니다.
인터럽트 처리 함수에서 API로 반환할 때 반환 값은 여전히 eax 레지스터에 저장됩니다. 이때 커널 모드에서 사용자 모드로 복원됩니다.
API의 eax에서 값을 가져와 해당 판단을 내리고 다른 값을 반환하여 작업 완료를 나타냅니다.
보호 모드에는 다양한 인터럽트가 있으며, 시스템 호출은 인터럽트 번호 0x80에 바인딩됩니다. 시스템 호출이 호출될 때 int 0x80이 트리거되고 인터럽트 처리 기능은 호출하려는 시스템 호출을 알기 위해 eax를 사용합니다. 그 이유는 시스템 콜이 너무 많아 인터럽트 개수가 부족해 중앙 관리용으로 한 개만 사용하기 때문이다.
운영 체제에는 다양한 시스템 호출 기능의 주소를 저장하는 데 사용되는 테이블이 있습니다. 이 테이블은 배열이므로 첨자를 통해 다양한 함수의 주소에 액세스할 수 있습니다. 따라서 하나의 인터럽트 번호 + 다양한 시스템 호출 번호를 사용하여 여러 시스템 호출을 관리할 수 있습니다.
위 내용은 Linux에서 시스템 호출 프로세스 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!