Я хотел знать глубокое значение и работу компилятора, компоновщика и загрузчика.
Ссылаясь на любой язык, желательно С++.
=====> COMPILATION PROCESS Input is Source file(.c) | V +=================+ | | | C Preprocessor | | | +=================+ | | —> Pure C file ( comd:cc -E ) | V +=================+ | | | Lexical Analyzer| | | +——————+ | | | Syntax Analyzer | | | +——————+ | | | Semantic Analyze| | | +——————+ | | | Pre Optimization| | | +——————+ | | | Code generation | | | +——————+ | | | Post Optimize | | | +=================+ | |—> Assembly code (comd: cc -S ) | V +=================+ | | | Assembler | | | +=================+ | |—> Object file (.obj) (comd: cc -c ) | V +=================+ | Linker | | and | | loader | +=================+ | |—> Executable (.Exe/a.out) (com:cc ) | V Executable file(a.out)
C препроцессор: –
Предварительная обработка C – первый шаг в компиляции. Он обрабатывает:
Компиляция. Как работает компилятор
- #define заявления.
- #include заявления.
- Условные высказывания.
- макрос
Цель этого блока – преобразовать исходный файл C в файл кода Pure C.
C компиляция:
В блоке есть шесть ступеней:
1) Лексический анализатор:
Он объединяет символы в исходном файле, чтобы сформировать “жетон”. Токен – это набор символов, который не имеет пробела, табуляции и новой строки. Поэтому эта единица компиляции также называется “TOKENIZER”. Он также удаляет комментарии, генерирует записи таблицы символов и таблицы перемещения.
2) Синтаксический анализатор:
Этот блок проверяет синтаксис в коде. Например:
Приведенный выше код сгенерирует ошибку разбора, поскольку уравнение не сбалансировано. Этот модуль проверяет это внутренне, генерируя дерево синтаксического анализатора следующим образом:
= / d — / + * / / a b c ?
Поэтому этот блок также называется PARSER.
3) Семантический анализатор:
Этот блок проверяет значение в утверждениях. Например:
Приведенный выше код генерирует ошибку “Присвоение несовместимого типа”.
4) Предварительная оптимизация:
Этот блок не зависит от процессора, т.е. Существует два типа оптимизации
- Преоптимизация (не зависит от процессора)
- Постоптимизация (зависит от процессора)
Этот модуль оптимизирует код в следующих формах:
- I) Устранение мертвого кода
- II) Устранение субкода
- III) Циклическая оптимизация
I) Устранение мертвого кода:
< int a = 10; if ( a >5 ) < /* . */ >else < /* . */ >>
Здесь компилятор знает значение ‘a’ во время компиляции, поэтому он также знает, что условие if всегда истинно. Следовательно, это исключает остальную часть кода.
II) Устранение субкода:
можно оптимизировать следующим образом:
III) Циклическая оптимизация:
В приведенном выше коде, если “а” является локальным и не используется в цикле, то его можно оптимизировать следующим образом:
Как работает язык программирования(Компилятор)? Основы программирования.
5) Генерация кода:
Здесь компилятор генерирует код сборки, чтобы наиболее часто используемые переменные сохранялись в регистрах.
6) Постоптимизация:
Здесь оптимизация зависит от процессора. Предположим, что если в коде более одного перехода, они преобразуются в один как:
—— jmp: jmp: —— ——
Управление переходит на прямое.
Затем последним этапом является Linking (который создает исполняемый файл или библиотеку). Когда исполняемый файл запущен, необходимые ему библиотеки загружаются.
- Компилятор читает, анализирует и переводит код в объектный файл или список сообщений об ошибках.
- Компилятор объединяет один или несколько объектных файлов и может использовать некоторый библиотечный код в любой исполняемый файл, какую-то библиотеку или список сообщений об ошибках.
- Загрузчик считывает исполняемый код в память, выполняет некоторые преобразования адресов и пытается запустить программу, в результате чего запущена программа или сообщение об ошибке (или оба).
[Source Code] —> Compiler —> [Object code] —* | [Source Code] —> Compiler —> [Object code] —*—> Linker —> [Executable] —> Loader | | [Source Code] —> Compiler —> [Object code] —* | | | [Library file]—* V [Running Executable in Memory]
Надеюсь, это поможет вам немного больше.
Сначала пройдите эту диаграмму:
(img source->internet)
Вы создаете фрагмент кода и сохраняете файл (исходный код), затем
Предварительная обработка: – Как следует из названия, это не часть компиляции. Они инструктируют компилятор выполнить необходимую предварительную обработку перед фактической компиляцией. Вы можете вызвать эту фазу “Замена текста” или интерпретировать специальные препроцессорные директивы, обозначенные символом “#”.
Компиляция: – Компиляция – это процесс, в котором программа, написанная на одном языке, переводится на другой целевой язык. Если есть некоторые ошибки, компилятор обнаружит их и сообщит об этом.
Соберите: – Сборка кода переводится в машинный код. Вы можете назвать ассемблер специальным типом complier.
Связывание: – Если для этого фрагмента кода нужен какой-либо другой исходный файл, связанный с ним, компоновщик свяжет их, чтобы сделать его исполняемым файлом.
После него происходит много процессов. Да, вы уже догадались, что здесь играет роль загрузчика:
Loader: – он загружает исполняемый код в память; создаются файлы программ и данных, регистр инициализируется.
Маленькая дополнительная информация: – http://www.geeksforgeeks.org/memory-layout-of-c-program/, вы можете увидеть макет памяти там.
Компилятор: это программа, которая переводит языковую программу высокого уровня в программу машинного языка. Компилятор более интеллектуальный, чем сборщик. Он проверяет все виды ограничений, диапазонов, ошибок и т.д. Но время выполнения программы больше и занимает большую часть памяти. Он имеет медленную скорость.
Поскольку компилятор просматривает всю программу, а затем переводит всю программу в машинные коды. Если компилятор работает на компьютере и создает машинные коды для одного и того же компьютера, то он известен как собственный компилятор или резидентный компилятор. С другой стороны, если компилятор работает на компьютере и создает машинные коды для другого компьютера, то он известен как кросс-компилятор.
Linker: на языках высокого уровня хранятся некоторые встроенные файлы заголовков или библиотеки. Эти библиотеки предопределены, и они содержат основные функции, которые необходимы для выполнения программы. Эти функции связаны с библиотеками с помощью программы Linker. Если компоновщик не находит библиотеку функции, он сообщает компилятору, а затем компилятор генерирует ошибку. Компилятор автоматически вызывает компоновщик в качестве последнего шага при компиляции программы.
Не встроенный в библиотеки, он также связывает определенные пользователем функции с определенными пользователем библиотеками. Обычно более длинная программа делится на более мелкие подпрограммы, называемые модулями. И эти модули должны быть объединены для выполнения программы. Процесс объединения модулей выполняется компоновщиком.
Loader: Loader – программа, которая загружает машинные коды программы в системную память. В Computing загрузчик является частью операционной системы, которая отвечает за загрузку программ. Это один из основных этапов процесса запуска программы. Потому что он помещает программы в память и готовит их к исполнению. Загрузка программы включает чтение содержимого исполняемого файла в память.
По завершении загрузки операционная система запускает программу, передавая управление загруженному программному коду. Все операционные системы, поддерживающие загрузку программы, имеют загрузчики. Во многих операционных системах загрузчик постоянно находится в памяти.
Википедия должна иметь хороший ответ, вот мои мысли:
- Компилятор: читает источник something.c, пишет объект something.o.
- Linker: объединяет несколько файлов *.o в исполняемую программу.
- Loader: код, который загружает исполняемый файл в память и запускает его.
Компилятор:
Он будет читать исходный файл, который может иметь тип .c или .cpp и т.д., и переводит его в файл .o, называемый объектным файлом.
Linker:
Он объединяет несколько файлов .o, которые могут быть сгенерированы для нескольких исходных файлов в исполняемый файл (формат ELF в GCC). Существует два типа ссылок:
- статическая привязка
- динамическое связывание
Погрузчик:
Программа, которая загружает исполняемый файл в основную память устройства.
Для подробного изучения этих трех этапов выполнения программы в Linux, пожалуйста, прочитать это.
объясняется в отношении систем на основе linux/unix, хотя это базовая концепция для всех других вычислительных систем.
Linkers and Loaders из LinuxJournal объясняет эту концепцию с ясностью. Это также объясняет, как появилось классическое имя a.out. (выход ассемблера)
c program —> [compiler] —> objectFile —> [linker] —> executable file (say, a.out)
1. Принципы работы компилятора.
не генерирует объектный код, а выдаёт результаты работы выполняемых операторов исходной программы.
2. Программные прерывания.
Для обработки событий, происходящих асинхронно по отношению к выполнению программы, лучше всего подходит механизм прерываний. Прерывание можно рассматривать как некоторое особое событие в системе, требующее моментальной реакции. Программные прерывания удобно использовать для организации доступа к отдельным, общим для всех программ модулям. Например, программные модули операционной системы доступны прикладным программам именно через прерывания, и нет необходимости при вызове этих модулей знать их текущий адрес в памяти.
Прикладные программы могут сами устанавливать свои обработчики прерываний для их последующего использования другими программами. Для этого встраиваемые обработчики прерываний должны быть резидентными в памяти. Программные прерывания вызываются следующими ситуациями:
особый случай, возникший при выполнении команды и препятствующий нормальному продолжению программы (переполнение, нарушение защиты памяти, отсутствие нужной страницы в оперативной памяти и т.п.);
наличие в программе специальной команды прерывания INT n, используемой обычно программистом при обращениях к специальным функциям операционной системы для ввода-вывода информации.
2. Временные прерывания.
2. Дисциплины обслуживания прерываний.
2. Общая структура системы прерывания.
Для того чтобы связать адрес обработчика прерывания с номером прерывания, используется таблица векторов прерываний, занимающая первый килобайт оперативной памяти — адреса от 0000:0000 до 0000:03FF. Таблица состоит из 256 элементов — FAR-адресов обработчиков прерываний. Эти элементы называются векторами прерываний. В первом слове элемента таблицы записано смещение, а во втором — адрес сегмента обработчика прерывания.
Прерыванию с номером 0 соответствует адрес 0000:0000, прерыванию с номером 1 — 0000:0004 и т.д.
Инициализация таблицы происходит частично BIOS после тестирования аппаратуры и перед началом загрузки операционной системой, частично при загрузке DOS. DOS может переключить на себя некоторые прерывания BIOS.
1. Функции операционной системы при управлении языковым процессора
2. Функционирование системы прерывания.
1. Программы и подпрограммы и их виды.
2. Архитектура ПК, управляемая событиями.
Источник: studfile.net
Компиляторы: история создания и развития
Компилятор — это системная программа, которая выполняет преобразование программных приложений, написанных на одном из алгоритмических языков, в программу на машинном языке или близком к нему.
Введение
В вычислительной технике компилятор является компьютерной программой, преобразующей исходный текст, который написан на одном из языков программирования высокого уровня, в машинные коды. Программы компиляции могут быть написаны как на автокоде, так и с применением языков высокого уровня.
Помимо этого, есть и специализированные языки формирования компиляторов, то есть условно говоря это компиляторы компиляторов. Компилятор компиляторов является системой, позволяющей выполнять генерацию компиляторов. На вход такой системы подаётся множество грамматик, после чего на выходе в идеале формируется готовая программа компиляции. В отдельных случаях под компилятором компиляторов понимается язык программирования, где исходной программой является описание компилятора конкретного языка, а сформированной (объектной) программой является сама программа компиляции, предназначенная для этого языка.
Иначе говоря, компилятор компиляторов является формализацией, которая необходима, чтобы сделать описание компилятора, включающее в явной или неявной форме отображение лексического и синтаксического анализатора, генератора кодов и иных компонентов формируемого компилятора. Чаще всего в компиляторе компиляторов применяется схема так называемого синтаксически управляемого перевода. И помимо этого, некоторые из них являются специальными языками высокого уровня, позволяющими в удобном формате выполнять описание алгоритмов, применяемых при реализации компиляторов.
История создания и развития компиляторов
Создание первых программ компиляции следует отнести к началу пятидесятых годов прошлого века. Главной задачей реализации первых компиляторов в то время было решение проблемы преобразования алгебраических выражений в машинные коды.
А фактическим годом рождения теории компиляции может считаться 1957-ой год, когда была реализована первая программа компиляции языка Фортран, сформированная Бэкусом и выдававшая довольно эффективные объектные (машинные) коды. Этот компилятор был предназначен для платформ IBM 704, IBM 360 и DEC PDP-11. В восьмидесятом году прошлого века вышел новый вариант компилятора, предназначенный для IBM 360 и IBM PC, который поддерживал стандарт FORTRAN 77. Годом позже образовалась компания Watcom, представившая в 1988-ом году программу компиляции Си. Она мгновенно стала чрезвычайно популярной среди специалистов по программированию, поскольку могла генерировать наиболее быстрые коды в сравнении с другими компиляторами тех времён.
«Компиляторы: история создания и развития»
Готовые курсовые работы и рефераты
Решение учебных вопросов в 2 клика
Помощь в написании учебной работы
Почти все компиляторы выполняют перевод программы с определённого языка высокого уровня программирования в машинные коды, которые могут быть исполнены центральным процессором. Обычно данные коды предназначены для исполнения в конкретной операционной системе, так как применяют предоставленные системой возможности, такие как, например, системные вызовы и библиотеки функций.
Замечание 1
Архитектурная организация, то есть совокупность программного и аппаратного обеспечения, для которой выполняется компиляция, именуется целевой машиной.
Отдельные программы компиляции, к примеру,Java, способны переводить программу не в машинные коды, а в программу на определённом специализированном языке низкого уровня. Данный язык, или по-другому байт-код, тоже может считаться языком машинных кодов, так как он должен интерпретироваться виртуальной машиной. К примеру, для языка Java языком виртуальной машины является JVM, или иначе байт-код Java.
Для всех целевых машин, к примеру, IBM, Apple и так далее, и всех операционных систем или их семейств, используемых на целевой машине, необходимо написать свою программу компиляции. Есть ещё так называемые программы кросс-компиляции, которые позволяют на одной машине и одной операционной системе формировать коды, предназначенные для исполнения на другой целевой машине или другой операционной системе.
Помимо этого, программы компиляции можно оптимизировать для разных типов процессоров из единого семейства. К примеру, коды, сформированные компилятором для процессоров семействаi686, могут применять специфические для данных процессоров инструкции MMX, SSE, SSE2. Имеются также программы, решающие обратную задачу, а именно, они переводят программы с языка низкого уровня на язык высокого уровня. Такая процедура именуется декомпиляцией, а выполняющие её программы называются декомпиляторами.
Компилятор структурно состоит из набора логических компонентов. Лексический анализ осуществляется специальным анализатором, который распознаёт лексемы языка и выполняет их замену необходимыми кодами. Лексемой является элементарная единица, которая входит в структуру предложений языка. Это может быть ключевое слово, константа, имя и тому подобное.
Синтаксический анализатор требуется для выяснения удовлетворяют ли предложения, входящие в состав исходной программы, грамматическим правилам данного языка. Процесс синтаксического анализа можно представить, как формирование дерева грамматического разбора для преобразуемых предложений.
Семантический анализ выполняет контроль типов и видов каждого идентификатора и всех операндов.
Процесс оптимизации предполагает выполнение преобразования исходной программы в некоторый промежуточный формат записи. Оптимизацией промежуточного кода является выделение общих подвыражений и определение подвыражений, являющихся константами. Оптимизационная фаза служит для удаления избыточных элементов программы, вызывающих задержки по времени выполнения и увеличивающих объём занимаемой памяти. Эта фаза работы с программой может быть исключена из общего цикла программной обработки, если применяются иные критерии проектирования транслятора.
Источник: spravochnick.ru