고급 언어로 작성된 소스 프로그램을 실행 가능한 프로그램으로 변환하려면 "컴파일과 링크"가 필요합니다. 고급 언어로 작성된 소스 프로그램은 머신에서 직접 실행할 수 없으며 컴파일하고 링크해야 합니다.
프로그램을 실행하려면 전처리, 컴파일, 어셈블리 및 연결의 네 단계를 거쳐야 합니다. 다음으로 몇 가지 간단한 예를 통해 이러한 프로세스를 자세히 설명하겠습니다.
위에 사용된 옵션에 대해서는 몇 가지 설명이 필요합니다.
옵션 없이 gcc 명령을 사용하면 기본적으로 전처리, 컴파일, 어셈블리, 링크의 전체 과정이 수행됩니다. 프로그램이 올바르면 실행 파일이 기본으로 제공됩니다.
-E 옵션 : 전처리를 수행한 후 컴파일러에 중지하라는 메시지를 표시하고 후속 컴파일, 어셈블리 및 링크는 실행되지 않습니다.
-S 옵션: 컴파일 후에 컴파일러가 중지하고 어셈블리 및 링크를 수행하지 않도록 프롬프트합니다.
-c 옵션: 어셈블리 실행 후 컴파일러에게 중지하라는 메시지를 표시합니다.
그래서 이 세 가지 옵션은 실행을 위해 특정 단계를 별도로 취하는 것이 아니라 컴파일러 실행 작업의 중지 시간을 제한하는 것과 같습니다.
위 프로그램의 실행과정은 모두가 숙지하고 있어야 시간낭비하지 않겠습니다.
1. 전처리:
-E 옵션을 사용하세요. 이는 사전 컴파일만 수행되고 이에 따라 .i 파일이 생성된다는 의미입니다.
전처리 과정에서 수행되는 작업:
간단한 프로그램을 사용하여 사실이 위와 같은지 검증한다.
간단한 프로그램을 작성한 후 -E 옵션을 사용하여 전처리 과정을 수행하고, 생성된 .i 파일을 열어 소스 파일과 비교하면, 결과가 한눈에 보입니다
코드를 작성할 때 줄 번호를 수동으로 추가하는 것은 위에서 사용하는 편집 도구에 의해 자동으로 추가되지 않습니다. , 그리고 이러한 줄 번호는 컴파일 시스템에서 볼 수 없습니다. 그러나 코드의 한 줄에 문제가 있으면 컴파일 중에 어떤 코드 줄에 문제가 있는지 묻는 메시지가 표시됩니다. 이것은 컴파일러가 자동으로 줄 번호를 추가한다는 것을 이미 증명했습니다.
2. 컴파일:
-S 옵션을 사용하여 실행 후 컴파일 작업이 종료됨을 나타냅니다. 그에 따라 .s 파일이 생성됩니다.
컴파일 프로세스는 전체 프로그램 구성의 핵심 부분입니다. 컴파일이 성공하면 소스 코드가 텍스트 형식에서 기계어로 변환됩니다. 컴파일 프로세스는 일련의 어휘 분석, 구문 분석, 의미 분석을 수행하는 것입니다. 전처리된 파일에 대한 분석 및 최적화를 통해 해당 어셈블리 코드 파일을 생성합니다.
어휘 분석은 lex라는 프로그램을 사용하여 어휘 스캐닝을 구현합니다. 이는 사용자가 이전에 설명한 어휘 규칙에 따라 입력 문자열을 토큰으로 분할합니다. 생성된 토큰은 일반적으로 키워드, 식별자, 리터럴(숫자, 문자열 등 포함) 및 특수 기호(연산자, 등호 등)로 구분되어 해당 테이블에 배치됩니다.
구문 분석은 표현의 문법 수준 분석을 완료하지만 해당 문장이 실제로 의미가 있는지는 파악하지 못합니다. 일부 명령문은 문법적으로는 유효하지만 실질적인 의미는 없습니다. 예를 들어 두 포인터가 곱해지는 경우 의미론적 분석이 필요합니다. 그러나 컴파일러가 분석할 수 있는 유일한 의미론은 정적 의미론입니다.
정적 의미 체계: 컴파일 타임에 결정될 수 있는 의미 체계입니다. 일반적으로 선언, 유형 일치 및 유형 변환이 포함됩니다. 예를 들어 부동 소수점 표현식이 정수 표현식에 할당되면 부동 소수점에서 정수로의 변환이 암시적으로 이루어지며 의미 분석은 이 변환을 완료해야 합니다. 또 다른 예는 부동 소수점 표현식을 정수 표현식으로 변환하는 것입니다. . 포인터에 표현식을 할당하는 것은 확실히 불가능합니다. 의미 분석 중에 두 유형이 일치하지 않는 것으로 확인되고 컴파일러는 오류를 보고합니다.
동적 의미 체계: 런타임에만 결정될 수 있는 의미 체계입니다. 예를 들어 두 개의 정수를 나누면 구문과 유형이 일치하는 데 문제가 없지만 제수가 0이면 문제가 발생하지 않습니다. 사전에 수행할 수 있으며 시간이 되어서야 그에게 문제가 있음을 알 수 있습니다. 이것이 동적 의미입니다.
우리 코드는 최적화될 수 있습니다. 컴파일 중에 결정될 수 있는 일부 값의 경우, 예를 들어 위 예에서 2+6이 컴파일 중에 결정될 수 있습니다. 그 값은 8이지만 구문을 직접 최적화하는 것이 더 어렵습니다. 이 경우 최적화 프로그램은 먼저 구문 트리를 중간 코드로 변환합니다. 중간 코드는 일반적으로 대상 시스템 및 운영 환경과 독립적입니다. (데이터 크기, 변수 주소, 레지스터 이름 등은 포함되지 않습니다.) 중간 코드는 컴파일러마다 다른 형식을 갖습니다. 가장 일반적인 코드는 3주소 코드와 P 코드입니다.
중간 코드를 사용하면 컴파일러를 프런트엔드와 백엔드로 나눌 수 있습니다. 컴파일러 프런트 엔드는 기계 독립적인 중간 코드를 생성하고, 컴파일러 백엔드는 중간 코드를 기계 코드로 변환합니다.
코드 생성기는 중간 코드를 기계어 코드로 변환합니다. 기계마다 단어 길이, 레지스터, 데이터 유형 등이 다르기 때문에 이 프로세스는 대상 기계에 따라 다릅니다.
마지막으로 대상 코드 최적화 프로그램은 적절한 주소 지정 방법 선택, 고유한 방법을 사용하여 곱셈과 나눗셈을 대체하고 중복 명령을 삭제하는 등 대상 코드를 최적화합니다.
3. 어셈블리
어셈블리 코드를 기계가 실행할 수 있는 명령어로 변환하는 데 사용되는 어셈블러 as를 호출하면 어셈블리 프로세스가 완료됩니다.
hello.s -o hello.o로 명령을 사용하거나 gcc -c hello.s -o hello.o를 사용하여 조립 프로세스가 끝날 때까지 실행하면 해당 생성된 파일은 .o 파일입니다.
4. 링크
링크의 주요 내용은 모듈 간에 서로 참조하는 부분을 올바르게 연결하는 것입니다. 그 임무는 다른 기호 주소에 대한 일부 명령어의 참조를 수정하는 것입니다. 연결 프로세스에는 주로 주소 및 공간 할당, 기호 확인 및 리디렉션이 포함됩니다.
기호 확인: 때로는 기호 바인딩, 이름 바인딩, 이름 확인 또는 주소 바인딩이라고도 하며 실제로 기호를 사용하여 주소를 식별하는 것을 의미합니다. A 예를 들어, int a = 6; 이러한 코드는 A를 사용하여 공간에서 4번째 바이트 크기 공간을 식별하고 공간에 저장된 내용은 4입니다.
Retreshing: 각 대상의 주소 재계산 프로세스가 호출됩니다. 재작성.
가장 기본적인 링크는 정적 링크라고 하는데, 각 모듈의 소스 코드 파일을 대상 파일(Linux: .o Windows: .obj)로 컴파일한 다음 대상 파일과 라이브러리를 함께 링크하여 최종 링크를 형성하는 것입니다. 실행 파일. 라이브러리는 실제로 대상 파일 세트의 패키지입니다. 가장 일반적으로 사용되는 코드 중 일부는 대상 파일로 변경된 다음 패키지되어 저장됩니다. 가장 일반적인 라이브러리는 프로그램 실행을 지원하는 기본 기능 모음인 런타임 라이브러리입니다.
더 많은 관련 지식을 보려면
PHP 중국어 웹사이트위 내용은 고급 언어로 작성된 소스 프로그램을 실행 가능한 프로그램으로 변환하려면 무엇이 필요합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!