Как программа выполняется на уровне процессора?


14

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

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

Однако это легче напечатать, чем понять. Итак, если все, что ЦП делает, это сложение, вычитание и т. Д., То как программа, скажем, JAVA-программа с именем print Hello World, выполняется с этими арифметическими операциями?

Я имею в виду, как эта программа превращается в нечто, что является просто дополнением для процессора?

PS Если этот вопрос не относится к этому сайту, то я прошу прощения.

-----Часть вторая-----

Ладно. Спасибо всем, что ответили так быстро и с таким энтузиазмом. Я подумал, что лучше немного изменить свой вопрос, чем идти, комментировать все ответы и задавать их снова.

Так и здесь.

Во-первых, все ответили конкретно на примере Hello World. Это моя ошибка. Я должен был сохранить этот родовой. Пример Hello world ставит под вопрос устройства вывода и то, как его обработка не ограничивается только процессором, что справедливо отражено в ваших ответах.

Также многие из вас привлекли мое внимание, что процессор делает больше, чем просто дополнение. Я согласен с этим. Я просто не писал это и предполагал это полностью. Из того, что я понимаю, это процесс:

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

    1. хранить данные в регистре внутри процессора
    2. Теперь ALU выполняет арифметические операции, конечно, после декодирования инструкции, или выполняет переход, если это инструкция if like
    3. И затем общение с другими ресурсами, если необходимо, например, с устройством вывода и так далее. Процессы вне этого пока тривиальны.

Таким образом, на шаге 3, где ЦП декодирует инструкцию и решает выполнить арифметическую операцию (здесь мы предполагаем, что не нужно выполнять никакой другой операции, например, выполнить переход по текущей инструкции ... поскольку арифметические операции в основном выполняются ... поэтому мы будем придерживаться этого ) На этом моя визуализация заканчивается. Как инструкция из моей программы - просто арифметическая операция для процессора. Он выполняет эту арифметическую операцию, и эта инструкция служит своей цели.

Надеюсь, на этот раз я прояснил ситуацию.

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


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

1
Может быть, вы должны начать смотреть на фактический набор команд ЦП, например, на очень простые, такие как MC6502, Z80 ... затем увидеть, что есть инструкции по доступу к памяти, инструкции по обработке данных, ветви ... Тогда вы можете догадаться, как они могут быть в сочетании для реализации любого алгоритма.
TEMLIB

3
Процессор определенно может сделать больше, чем сложение. Важно отметить, что процессор может выполнять сравнения и переходы.
Теодорос Чатзигианнакис

1
Вы (кажется) по-прежнему твердо отказываетесь видеть IF (принятие решения) и MOVE (чтение и сохранение данных), программирование на 99% IF и MOVE. Арифметика ничтожна. Ваш первый пример (Hello world) вообще не имеет арифметики.
edc65

1
1. Я думаю, что у вас будет больше шансов получить хорошие ответы, если вы зададите новый вопрос с новым замешательством, чем редактировать этот вопрос, чтобы изменить то, что вы спрашиваете. Вы получили хорошие ответы на свой первоначальный вопрос, и ваш первоначальный вопрос, похоже, может стоять самостоятельно, так почему бы не удалить редактирование и задать новый вопрос? 2. Тем не менее, я не могу понять новую часть. Что именно ваш вопрос о новой части? Когда вы говорите: «На этом моя визуализация заканчивается», вы подразумеваете, что понимаете шаг 3 или не понимаете шаг 3? Если вы делаете, что вы не понимаете?
DW

Ответы:


7

Вы можете попробовать взять простую программу и скомпилировать ее в машинный код. (Java обычно компилируется в код JVM, но у Эндрю Тенненбаума есть книга, в которой он описывает, как спроектировать центральный процессор, который будет работать так, как обычно.) В GCC, например, вы даете компилятору -Sпереключатель.

Это скажет вам, что все хитрые вещи, такие как ввод / вывод, реализуются путем вызова операционной системы. В то время как вы можете загрузить исходный код в ядро ​​Linux и сделать то же самое с ним, то, что происходит под капотом: все манипулирует состоянием памяти компьютера, например, списком запущенных процессов, или же общается с оборудованием с помощью специальные адреса памяти, которые управляют этим, или используя специальные инструкции процессора, такие как inи outна x86. Как правило, однако, только специальные программы, называемые драйверами устройств, будут взаимодействовать с конкретным оборудованием, и ОС будет отправлять запросы на использование оборудования нужному драйверу.

В частности, если вы печатаете, "привет, мир!" ваш компилятор превратит это в набор инструкций, которые загружают строку в определенное место (например, загружает адрес строки в памяти в %rdiрегистр) и вызывают библиотечную функцию с callинструкцией. Эта библиотечная функция может найти длину строки с циклом, а затем вызвать системный вызовwrite()записать это количество байтов из строки в дескриптор файла номер 1, что является стандартным выводом. В этот момент ОС ищет файл 1 этого процесса и решает, что означает запись в него. Если записи на стандартный вывод будут напечатаны на вашем экране, будет некоторый процесс, например копирование байтов в буфер, который затем будет считан вашей терминальной программой, которая сообщает оконной системе, какие буквы помещать, где и каким шрифтом. Оконная система решает, как именно это должно выглядеть, и говорит драйверу устройства поместить пиксели на экран, что происходит путем изменения видеопамяти.


Спасибо @Lorehead. Это объяснение выглядит хорошо с примером Hello World.
user2827893 22.09.15

5

Ваш процессор сам по себе тупой, как вы поняли. Но вокруг него микрокосм аппаратных чипов. У вас есть инструкция, которая позволяет вам установить одну линию ЦП на высокий уровень, который подключен к другому чипу. Этот аппаратный чип контролирует линию и говорит: «Эй, если эта линия высока, то я делаю что-то с некоторыми другими линиями».

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

В конце концов, ваш процессор просто говорит какой-то другой микросхеме, пожалуйста, измените сигнал на мониторе, чтобы он выглядел как «Hello World».

Гугл чертеж 7-сегментного дисплея. У него есть провода, которые подсвечивают сегмент, если на него подавать напряжение. Если вы теперь подключите одну выходную линию вашего ЦП к одной строке 7-сегментного дисплея, дисплей загорится. Это не процессор, который заставляет светиться светодиод, он просто подает напряжение на линии, но некоторые другие аппаратные средства могут сделать из-за этого изящные вещи.

Если ваш ЦП теперь установит все строки для H на высокий уровень, 7-сегментный будет отображать H, хотя H не является числом, которое ЦП будет добавлять или вычитать из.

Теперь, если все слои согласуются с тем, что необходимо для отображения 7-сегментного дисплея H (задайте для 5 определенных строк высокое значение), компилятор Java может сделать код для отображения H. Это, конечно, довольно неудобно - поэтому слои запускаются абстрагироваться. Самый нижний слой начинается с: «Да, там 26 букв, давайте присваиваем цифры каждой букве - как насчет того, чтобы мы дали букве« H »число« 72 »? Тогда вы можете просто сказать мне« Показать букву 72 »», вместо «Установите высоту строки 309, установите высоту строки 310, установите высоту строки 498, установите высоту строки 549, установите высоту строки 3». Таким образом, каждый слой начинает абстрагировать информацию о том, как достичь определенных результатов, поэтому вам не нужно заботиться о них.

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


3

В колледже в рамках программы получения степени CS я изучил расширенный пример языка передачи регистров, определяющего ЦП. Я был вдохновлен, чтобы взять другой подход и написать симулятор, который принимает такие обозначения как определение, и опубликовал их в Embedded Systems Programming (выпуск за март 1989 года) как способ ответить на тот же вопрос, который вы задавали, позволяя людям построить свое интуитивное понимание таких вещей.

В классе мы продолжили использовать эту запись переноса резисторов в реальных логических элементах регистров! Он пишет сам: смотрите на все, что имеет регистр «A» в качестве места назначения, и код A = (case1) или (case2) ... и это выражается в виде суммы продуктов или суммы продуктов в нормированном виде.

Только в конце курса я узнал, что это был настоящий процессор: PDP-8, если я правильно помню.

Сегодня вы можете подать диаграмму гейта в чип программируемой логической матрицы.

В этом и заключается суть: регистр устанавливается с результатом логических элементов И и ИЛИ, ведущих к другим регистрам. Одним из значений для включения является значение кода операции.

Итак, представьте: A: = (код операции == 17 & X + Y) | (код операции == 18 & X + Z) | ...

Современные процессоры более сложны, с конвейерами и шинами, но отдельные подразделения, такие как один ALU, работают именно так.


2

Вы рассматриваете процессор здесь, но при запуске «Hello World» задействован еще один компонент: дисплей!

Для ЦП значение в памяти - это просто число, представленное в виде заданного количества битов (0 и 1).

Как это превращается в буквы на экране - другая история: на дисплее также есть память. Эта память (графическая память) отображается на пикселях на экране. Каждый пиксель кодируется со значением: если это очень простой монохромный дисплей, это просто интенсивность, для цветных дисплеев это комбинация красного, зеленого и синего (RGB), которая может кодироваться различными способами.

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

Таким образом, когда код скомпилирован, он включает в себя все виды вещей, которые поступают из библиотек ОС, в том числе набор шрифтов / символов и т. Д., Которые позволяют процессору знать, что писать в графической памяти. (Это довольно сложно, но это общая идея: компилятор включает в себя намного больше кода, чем то, что содержится только в вашем коде «привет мир», через импортированные библиотеки)

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


1

Вот формальный подход к вашему вопросу из области теоретической информатики.

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

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

Примечание: это слишком упрощено, но, на мой взгляд, дает хорошую интуицию.


1

Что может помочь, так это отвлечь ваше мышление от «арифметики». Если вы действительно пытаетесь понять, что делают компьютеры под капотом, чтобы напечатать «Hello World», лучше подумать на один уровень ниже. «Состояние» компьютера можно описать как набор битов, сохраняемых транзисторными переключателями, которые либо включены, либо выключены (или конденсаторами, которые заряжены или не заряжены). Компьютер управляет этими битами в соответствии с правилами. Способы, которыми компьютеру разрешено манипулировать этими битами, записываются в ЦП в виде транзисторов, которые выполняют работу по изменению битов с 0 на 1 или с 1 на 0.

Когда ALU «выполняет арифметику», это действительно означает, что он изменил состояние компьютера таким образом, чтобы это соответствовало нашим правилам арифметики. Все, что он сделал, это изменил некоторые биты. Это значение программного обеспечения объясняет, почему мы должны думать о нем как о сложении или вычитании. Процессор не «знает», что он делает. Он просто меняется от штата к штату, и это все (по крайней мере, пока Skynet не вступит во владение).

Когда вы думаете об этом таким образом, более сложные инструкции, такие как инструкция «прыжка», ничем не отличаются. Все, что он делает, это изменяет некоторые биты. В этом случае случается изменение битов, которые, как мы знаем, означают местоположение следующей инструкции для выполнения. Процессор не «знает» об этом, но мы знаем. Поэтому мы используем инструкцию, которая изменяет эти биты, чтобы «перескакивать» с места на место в нашем коде.

IO на самом деле тоже не отличается, просто меняются биты. Единственное небольшое отличие состоит в том, что эти биты связаны с транзисторами, что в конечном итоге приводит к освещению символов на вашем экране. Если я могу вернуться на несколько десятилетий назад к тому, когда «Hello World» был на самом деле простым, было пространство памяти, где, если вы записали в него биты, соответствующие символам ASCII для «Hello World», эти символы были бы отображены непосредственно в экран. В наши дни все немного сложнее, потому что у нас есть видеокарты и операционные системы, которые мешают, но основная идея та же. У вас есть набор транзисторов, которые включены или выключены, которые связаны со схемой для отображения пикселя на экране. Мы установили правильные, и похоже, что «Hello World» появляется на экране.

Путаница - это просто вопрос синтаксиса против семантики. Поведение «добавлено наполовину» или «полностью добавлено» в ALU является синтаксисом. Он определяет, какие биты получатся, когда вы вставите биты. Его семантика - это концепция возможности делать сложение. Мы с вами знаем, что ALU может «делать сложение», но чтобы действительно понять, что происходит под ним, вы должны помнить, что ALU манипулирует только битами и байтами синтаксиса.


0

Процессоры работают так:

  • получить текущую инструкцию, увеличить указатель текущей инструкции.

  • расшифруйте его (например, выясните, что эта инструкция говорит процессору)

  • выполнить его (сделать то, что говорит инструкция) - текущий указатель инструкции может быть изменен, если инструкция является чем-то вроде «прыжка».

  • Повторить навсегда

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

Существует много типов инструкций, пример большинства из них:

  • «Переместить» инструкции. Они могут копировать X в другой X, где X - это память (RAM), регистр или адрес в пространстве ввода-вывода, если CPU поддерживает такое понятие.

  • Инструкции по манипулированию стеком, в том числе вставка в регистр, принудительный регистр в стеке и т. Д. Это особый случай инструкций «перемещения», которые используют и обновляют регистр «указателя стека».

  • Инструкции, выполняющие математические операции между двумя регистрами или памятью и регистром. Эти инструкции автоматически влияют на регистр флагов. Одним из таких флагов является флаг «нуля», который устанавливается, если результат равен нулю, а другим - «отрицательный» флаг, который устанавливается, если установлен старший значащий бит результата. Там могут быть другие в зависимости от процессора.

  • Частным случаем математических операций являются инструкции сравнения, которые аналогичны вычитанию, но результат не сохраняется. Флаги все еще затронуты.

  • Существуют инструкции перехода, которые переходят к адресу памяти, если установлены определенные флаги. Помните «нулевой» флаг, упомянутый выше? Он также удваивается как флаг «если равен», так что вы видите инструкции, как BEQна многих процессорах, которые фактически разветвляются, если установлен флаг «ноль».

  • Инструкции, которые выполняют логические операции (И, ИЛИ, НЕ), биты сдвига и тестовые биты. Они могут влиять на флаги, такие как математические инструкции, в зависимости от процессора.

  • Инструкции, которые прыгают безоговорочно.

  • Инструкции, которые переходят и сохраняют адрес возврата в стеке («вызов»), и другие инструкции, которые выталкивают адрес из стека («возврат»).

  • Специальные инструкции, подобные тем, которые останавливают процессор, идентифицируют процессор или вызывают обработчики прерываний.

  • «No Operation» - почти все процессоры имеют команду «no-op», которая просто потребляет циклы и движется дальше.

Это на самом деле просто пример, есть ЦПУ с меньшим количеством типов команд и ЦП с большим.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.