Что физически происходит внутри компьютера, когда часть кода компилируется и запускается - PullRequest
0 голосов
/ 29 октября 2019

Мне любопытно понять, как кусок кода превращается в то, что может понять компьютер. Во многих похожих вопросах распространенным ответом является утверждение о том, что цепочка от читаемого человеком кода до инструкций машинного уровня более или менее следует цепочке компиляции:

high-level code --> assembly code --> machine binary code

Несмотря на высокую частоту этого ответа, он все еще остаетсянемного загадки для меня, что на самом деле происходит в компьютере. Я в некоторой степени понимаю основную электронику, лежащую в основе компьютеров и процессоров, но этот конкретный случай все еще остается для меня загадкой.

Скажем, например, что я кодирую классическое "Привет, мир!"пример в

#include <iostream>
using namespace std;
int main() 
{
    cout << "Hello, world!";
    return 0;
}

, который затем преобразуется в код сборки, например,

section     .text
global      _start                              ;must be declared for linker (ld)

_start:                                         ;tell linker entry point

    mov     edx,len                             ;message length
    mov     ecx,msg                             ;message to write
    mov     ebx,1                               ;file descriptor (stdout)
    mov     eax,4                               ;system call number (sys_write)
    int     0x80                                ;call kernel

    mov     eax,1                               ;system call number (sys_exit)
    int     0x80                                ;call kernel

section     .data

msg     db  'Hello, world!',0xa                 ;our dear string
len     equ $ - msg                             ;length of our dear string

, который в конечном итоге преобразуется в двоичную последовательность

10100010101001111...................

, а затем"Привет, мир!"появляется на экране.

Таким образом, мой вопрос таков: что происходит на физическом уровне электрического сигнала на каждом этапе этого процесса внутри компьютера?

Я понимаю, что мойвопрос может быть слишком широким, чтобы ответить на него полностью, поэтому я был бы признателен, если бы вы указали на основные физические явления, которые происходят внутри компьютера (например, между жестким диском, процессором и оперативной памятью).

Также, пожалуйста, дайте мне знать, если мой вопрос не по теме, поскольку он не всегда на 100% однозначен, когда лежит граница между различными дисциплинами компьютерной инженерии. В этом случае, не могли бы вы предложить другой сайт SE, где этот вопрос может быть лучше подходит, спасибо.

Ответы [ 2 ]

1 голос
/ 29 октября 2019

Компьютер имеет ЦП, ОЗУ и устройства, которые можно подключить.

A компилятор переводит программный (исходный) код в машинный код , где программакод и данные кодируются в виде чисел - см. также Архитектура набора команд .

операционная система загружает (см. загрузчик ) машинный код впроцесс и запускает ЦП в его начале.

ЦП - это аппаратное обеспечение, которое интерпретирует числа как инструкции машинного кода, и они сообщают ему, что делать на каждом этапе программы машинного кода, и на каждом этапе, чтоследующая инструкция машинного кода должна быть.

Некоторые инструкции машинного кода говорят компьютеру загружать или хранить данные в памяти или связываться с устройством. Существует также механизм прерываний , который позволяет устройствам привлекать внимание ЦП.

Этот процесс очень мета, поскольку ЦП выполняет ту же самую интерпретацию машинного кода во время компиляции, связыванияи работает операционная система - существуют механизмы, такие как переключение контекста , которые позволяют ЦПУ переключать задания / программы и играть разные роли (операционная система, пользовательский процесс A, B и т. д.). За исключением простоя, ЦПУ всегда выполняет некоторую программу, то есть некоторую последовательность запрограммированных шагов в виде инструкций машинного кода.

Транзисторы реализуют ЦП и ОЗУ. Внутри ЦП имеются функциональные блоки, скажем, для сложения, вычитания, условного ветвления и т. Д. Эти функциональные блоки состоят из большого количества транзисторов. Процессор также имеет регистр памяти и кэш-памяти. Все они переключают значения на основе инструкций машинного кода, выполняемых в данный момент, так как единственная задача ЦПУ - выполнять инструкцию машинного кода после инструкции.

Например, скажем, программа машинного кодапоручает компьютеру добавить два числа, которые попали в регистры процессора, и записать ответ обратно в один из них. Аппаратное обеспечение сначала извлекает команду для выполнения, затем декодирует числа в ней, извлекает значения из именованных регистров, передает их на входы ALU , инструктирует ALU выполнить добавление, затем сохраняетВывод ALU обратно в регистр - готов к следующей инструкции машинного кода.

Мы также знаем, что добавление может быть выполнено множеством хотя и очень простой логической логики, которую могут выполнять транзисторы, см. сумматор . Эта же идея объединения транзисторов в функциональные блоки, необходимые для интерпретации инструкций машинного кода процессором, реализована для всех функций процессора.

Большинство цифровых схем построены с использованием одного единственного типа шлюза, сегодня, NAND Ворота. Ворота могут быть организованы для реализации любой логической функции. Эти транзисторы объединены в две широкие цепи: комбинационные и последовательные . В то время как комбинационные схемы вычисляют выходные значения исключительно на основе предоставленных входов, последовательные схемы имеют контур обратной связи, который позволяет им запоминать вещи. Конструкторы чередуют комбинационные схемы и последовательные схемы для формирования функциональных блоков ЦП. Для упрощения регистры и память создаются с использованием последовательной логики, в то время как ALU будут использовать комбинационную логику.

Вы также можете проверить RAM и узнать, как это построено также из транзисторов.

Мы также можем заметить, что во время выполнения любого данного набора инструкций машинного кода некоторые схемы остаются неиспользованными, и, таким образом, нас не волнует, работают ли эти транзисторы или нет, если не пытаются сэкономить энергию;ожидается, что другие транзисторы будут просто сохранять свое состояние как есть, например, для регистров и ОЗУ, которые не участвуют в текущих инструкциях машинного кода.

0 голосов
/ 29 октября 2019

Вы сказали, что у вас есть базовое понимание того, что происходит, и затем спросите, что происходит. Итак, во-первых, это очень широкий / большой материал, чтобы действительно получить даже четырехлетний курс по электротехнике, он охватывает только набор инструментов, необходимых для начала, чтобы понять все. Ясно, что это не то, что подходит под любой SE-ответ (и я написал ответы, доказывающие, что для ответов существует ограничение по размеру / характеру).

Если вы хотите знать физическую электронику, тогда задача компиляциине имеет отношения к делу, не имеет отношения к этому вопросу.

Процессоры невероятно глупы, они представляют собой конечные автоматы, которые работают с входящими битами. Ваш компьютер имеет много уровней программного обеспечения, которые в некотором смысле скрывают физические элементы нижнего уровня, такие каквозможно, способы получить доступ к хранилищу, USB, PCI жестких дисков и так далее. Один USB, старая спецификация 1.1 была 300 печатных страниц. больше, чем здесь уместно, и это не распространяется на какие-либо подробности, касающиеся технологий флэш-памяти, ни USB, ни SATA, ни других.

процессор получает машинный код от запросов на своей шине, запросы на его шине декодируютсяконтроллером памяти или несколькими в зависимости от дизайна. Через несколько уровней обсуждения, которое могло бы уместиться в одном ответе, рассматриваются различные периферийные устройства, USB-контроллер, PCI-контроллер, DRAM-контроллер и т. д. Затем, обычно через контроллер PCIE, у вас есть жесткий диск или другие энергонезависимые носители в наши дни. поэтому очень большое количество инструкций обеспечивает уровень, который позволяет ядру получать доступ к конкретному жесткому диску, а также бесчисленное множество других файлов для создания файловой системы поверх хранения и извлечения битов с носителя.

Компилятор, ассемблер или компоновщик и т. Д. Станут еще одним уровнем программного обеспечения поверх уровней ядра / драйверов поверх уровней аппаратного обеспечения для доступа к байтам из файлов на носителе. в случае компилятора он считывает байты, считающиеся символами ascii, у него есть программное обеспечение, которое анализирует эти байты, декодирующие определенный язык, а затем, используя таблицы, обычно обрабатывает эту информацию, сокращая программу на более мелкие части.

x = y + 5;

у вас есть как минимум две переменные, которые требуют хранения (при условии отсутствия оптимизации, которая удаляет мертвый код, прежде чем вы сможете уменьшить мертвый код, вам все равно придется пройти через этопроцесс). таким образом, как минимум, должно быть чтение генерации переменной y для 5, этап сложения с некоторым промежуточным результатом и затем сохранение этого промежуточного результата в месте назначения. компилятор собирается перебирать такие строки кода, чтобы разбить его на эти типы операций.

тогда может быть шаг оптимизации, например, компилятор может понять, что нигде программа не использует переменную xпосле этой строки кода, так что эта строка кода не дает значения, это мертвый код, поэтому все шаги, связанные с этой строкой кода, могут пройти, оптимизироваться. сегодня это обычно делается в оперативной памяти, но могут быть созданы промежуточные файлы для хранения информации, которая будет обработана.

снова поймите, что весь этот код - это машинный код и данные, которые передаются по шинам, через кеши, из больших запоминающих устройств, вероятно, основанных на драмах, каждый из которых состоит из одного-многих семестров классов для полного понимания, понимания высокого уровняне так много.

интерфейс компилятора преобразует ASCII в какой-то внутренний язык / таблицы, средняя часть компилятора может / делает это дальше, оптимизирует и т. Д. В этот момент компилятор может сохранить промежуточный файлили один популярный компилятор имеет формат файла и двоичный формат, который можно скомпилировать на этом этапе, чтобы позднее выполнить внутреннее преобразование в целевой набор команд.

Бэкенд компилятора затем преобразует последовательности операций в серию инструкций, которые поддерживает цель. вы можете иметь или не иметь оптимизатор глазка, который является целевой оптимизацией, например, целевой набор команд может предлагать команду регистр = регистр + немедленная, где 5 - это скорее немедленная, чем регистр = 5;зарегистрироваться = зарегистрироваться + зарегистрироваться. как только это будет сделано, тогда вывод, который для здравого смысла является ассемблером, но есть компиляторы, которые выводят машинные / объектные файлы.

запись файла ascii - это просто запись байтов в файл, поэтому у вас есть аппаратные слои, слои операционной системы плюс слои языковых библиотек, а затем ваше приложение, которое выдает эквивалент fprintf () для выводасимволы ascii, представляющие язык ассемблера, включая метки и директивы. если объект и машинный код, то он почти идентичен с физической точки зрения, только генерируются разные байты, которые представляют формат объектного файла и машинный код.

ассемблер такой же, только немного проще, он также читает черезвсе слои, байты, которые являются символами ascii, анализируют их и т. д., будучи другим языком, больше ориентированы на метки и тому подобное, а также на отдельные инструкции, которые сообщают ассемблеру биты, которые следует использовать в машинном коде для строк, которые являются инструкциями. ассемблер снова использует временные файлы или таблицы в памяти, чтобы отслеживать эту информацию. сжатие данных отличается от компилятора, но все еще достаточно много работы, набор инструкций имеет относительные смещения, и вещи, которые необходимо вычислять, поскольку каждая инструкция начинает принимать расстояние от одной инструкции до многих, могут занять многоитерации.

и через программные слои ассемблер затем записывает объектный файл.

тогда компоновщик берет объектные файлы и некоторый набор правил, которые определяют физическое адресное пространство, по крайней мере, из представления вна этом этапе, начиная с окончательного выполнения программы, это, скорее всего, виртуальный адрес, но это адресное пространство, сообщаемое компоновщику каким-то образом, часто каким-то другим файлом в формате, который должен быть проанализирован как программа в таблицах и т. д. использование слоев программного и аппаратного обеспечения для получения байтов с носителя, составляющего этот скрипт компоновщика. затем компоновщик, используя все слои, считывает байты с носителей, которые являются объектами. внешние функции, например, между двумя, скажем, файлами .C, должны быть разрешены на этом этапе, так как компоновщик помещает объекты в виртуальную копию целевого пространства памяти, где каждая из этих меток наконец получает свой адрес, затем объекты, которые ссылаются наэта метка может быть исправлена ​​компоновщиком, в зависимости от общей схемы набора инструментов, компоновщик иногда генерирует дополнительный код или создает / изменяет инструкции, оставленные ассемблером для облегчения этих соединений объектов.

И, как и все другие программы здесьон проходит через программный и аппаратный уровни, чтобы записать байты в файловую систему, которая в данном случае является конечным двоичным файлом, отмечая, что большую часть времени конечный двоичный файл представляет собой не просто образ памяти программы, которую нужно загрузить и запустить, он имеетфайловая структура, такая же, как файл документа или изображения, будет иметь некоторые накладные расходы, а также двоичные двоичные объекты, которые должны быть загружены в память для запуска создаваемой программы.

...