Як виконується програма на рівні процесора?


14

Я знаю, що це дуже поширене питання. Але я маю інший кут на увазі. Я просто спробую це сформулювати тут.

Як я знаю, кожна інструкція, яку виконує процесор, є машинною мовою, і все, що може зробити CPU, - це робити деякі арифметичні операції завдяки ALU та його транзисторам (якщо ми переходимо на апаратний рівень).

Однак це простіше набрати, ніж зрозуміти. Отже, якщо все процесор робить додавання, віднімання тощо, то як програма, скажімо, програма JAVA, що говорить надрукувати Hello World, виконана з цими арифметичними операціями?

Я маю на увазі, як ця програма перетворюється на щось, що є лише доповненням для процесора?

PS Якщо це питання не стосується цього веб-сайту, то я прошу вибачення.

----- Частина друга -----

Добре. Дякую всім, що відповіли на це швидко та з цим ентузіазмом. Я подумав, що краще трохи змінити моє запитання, ніж піти і коментувати всі відповіді і задавати їх ще раз.

Так ось воно.

По-перше, всі відповіли конкретно на прикладі wrt Hello World. Це моя вина. Я мав би зберегти це загальне. Приклад світу привіт викликає питання про вихідні пристрої та те, як його обробка не обмежується лише процесором, що справедливо підводиться у ваших відповідях.

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

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

    1. зберігати дані в реєстрі всередині процесора
    2. Тепер ALU виконує арифметичні операції, звичайно після розшифровки інструкції, або виконує стрибок, якщо це інструкція if if like
    3. А потім спілкування з іншими ресурсами, якщо потрібно, наприклад, із пристроєм виведення тощо. Процеси поза цим поки що тривіальні.

Тож у step3, де CPU розшифровує інструкцію і вирішує зробити арифметичну операцію (тут ми припускаємо, що немає жодної іншої операції, як зробити стрибок поточної інструкції. Тому що арифметичні операції в основному робляться .. тому ми будемо дотримуватися цього ) Тут закінчується моя візуалізація. Як інструкція з моєї програми - це просто арифметична операція для процесора. Він виконує цю арифметичну операцію і ця інструкція служить своєму призначенню.

Я сподіваюся, що цього разу я зрозумів себе.

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


Я розумію, що компілятор перетворює програму на машинну мову. Я просто не можу візуалізувати програму як арифметичну операцію. Хоча якщо програма сама по собі додає два числа, то це зрозуміло, але в іншому випадку це не так ... але !! :)
користувач2827893

1
Можливо, ви повинні почати переглядати фактичний набір процесорних процесорів, наприклад, дуже простих, таких як MC6502, Z80 ... потім побачити, що є інструкції доступу до пам’яті, інструкції з обробки даних, гілки ... Ви зможете здогадатися, як вони можуть бути комбіновані для реалізації будь-якого алгоритму.
TEMLIB

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

1
Ви (здається) все ще твердо відмовляєтесь бачити IF (приймає рішення) та MOVE (читання та зберігання даних), програмування - 99%, якщо ПІДБАЖИТИ. Арифметика незначна. Ваш перший приклад (Hello world) взагалі не має арифметики.
edc65

1
1. Я думаю, ви б більше шансів отримати хороші відповіді, якби ви задали нове запитання зі своєю новою плутаниною, а не редагували це питання, щоб змінити те, що ви запитуєте. Ви отримали хороші відповіді на своє первісне запитання, і на ваше оригінальне запитання здається, що він може стояти самостійно, то чому б не видалити правки і не задати нове запитання? 2. З цього приводу я не можу зрозуміти нову частину. Яке саме ваше питання щодо нової частини? Коли ви говорите «це де мої візуалізації закінчується», значить , ти дійсно розумієте крок 3, або ви не розумієте , крок 3? Якщо ви це зробите, чого ви не розумієте?
DW

Відповіді:


7

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

Це скаже вам, що все складне, як введення / виведення, реалізується за допомогою виклику операційної системи. Хоча ви можете завантажувати джерело до ядра Linux і робити те саме, що відбувається під кришкою: все маніпулює станом пам'яті комп'ютера, наприклад, перелік запущених процесів або інше спілкування з обладнанням за допомогою спеціальні адреси пам'яті, які ним керують, або за допомогою спеціальних інструкцій процесора, таких як inі outна x86. Однак, як правило, лише спеціальні програми, що називаються драйверами пристроїв, спілкуватимуться з конкретним обладнанням, і ОС надсилатиме запити на використання апаратного забезпечення потрібному драйверу.

Зокрема, якщо ви надрукуєте "привіт, світ!" ваш компілятор перетворить це в набір інструкцій, що завантажує рядок у певне місце (наприклад, завантаження адреси рядка в пам'ять до %rdiрегістра) і викликає функцію бібліотеки з callінструкцією. Ця функція бібліотеки може знайти довжину рядка з циклом, а потім зателефонувати в системний викликwrite()записати ту кількість байтів з рядка в дескриптор файлу №1, який є стандартним висновком. У цей момент ОС шукає, що таке файл № 1 цього процесу, і вирішує, що це означає для нього. Якщо запис на стандартний вихід буде надрукований на вашому екрані, відбудеться певний процес, як-от копіювання байтів у буфер, який потім зчитується термінальною програмою, яка повідомляє системі вікна, які букви ставити куди і яким шрифтом. Система вікон визначає, як саме це має виглядати, і повідомляє драйверу пристрою розміщувати пікселі на екрані, що це робить, змінюючи відеопам'ять.


Дякую @Lorehead Це пояснення добре виглядає на прикладі привіт світу.
користувач2827893

5

Ваш процесор сам по собі німий, як ви зрозуміли. Але навколо нього мікрокосм апаратних мікросхем. У вас є інструкція, яка дозволяє вам встановити одну лінію процесора на високому рівні, яка підключена до іншої мікросхеми. Цей апаратний чіп відстежує лінію і каже: "Ей, якщо ця лінія висока, то я щось роблю з деякими іншими рядками".

Щоб зробити це простішим, ці рядки групуються. Деякі використовуються для адреси пристроїв, деякі використовуються для передачі даних за цими адресами, а інші - просто рядки "Чувак, у моєму чіпі відбувається щось важливе".

Зрештою, ваш процесор просто повідомляє якусь іншу мікросхему, щоб досить змінити сигнал на монітор, щоб він виглядав як "Hello World".

Google накреслив 7-сегментний дисплей. У ньому є дроти, які підсвічуватимуть сегмент, якщо прикласти до нього напругу. Якщо зараз підключити один вихідний рядок вашого процесора з одним рядком 7-сегментного дисплея, дисплей загориться. Це не той процесор, який викликає світлодіод, він просто застосовує напругу до ліній, але деякі інші технічні речі можуть зробити витончені речі завдяки цьому.

Якщо ваш CPU тепер встановлює всі рядки для H високими, у 7-сегменті відображатиметься H, хоча H не є числом, з якого CPU додав би або відніме з нього.

Тепер, якщо всі шари згодні з тим, що потрібно зробити 7-сегментним відображенням H (встановити 5 конкретних рядків у висоту), компілятор Java може зробити код, щоб він відображався H. Це, звичайно, досить незручно - тому шари починаються до абстрактного. Найнижчий шар розпочнеться з: "Йо, наче 26 букв, давайте присвоїмо цифри кожній букві - як же ми дамо букві" Н "цифру" 72 "? Тоді ви можете просто сказати мені" Показати букву 72 ", замість "Встановити висоту 309, встановити лінію висоти 310, встановити лінію висотою 498, встановити лінію висотою 549, встановити лінію 3 високою". І тому кожен шар починає абстрагувати інформацію, як досягти певних результатів, тому вам не потрібно дбати про них.

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


3

У коледжі в рамках програми програми CS-ступеня я вивчив розширений приклад мови передачі реєстру, що визначає ЦП. Мене надихнуло по-іншому взяти на себе та написати тренажер, який приймає таке позначення як визначення, і опублікував це у програмуванні вбудованих систем (випуск від березня 1989 р.) Як спосіб відповісти на той же питання, який ви задали, дозволяючи людям будувати своє інтуїтивне розуміння таких речей.

У класі ми продовжували переганяти цю нотацію про перенесення реєстрів у фактичні логічні ворота на регістри! Він пише сам: подивіться на все, що має регістр "A", як місце призначення, і код A = (case1) або (case2) ..., і це стає вираженим у формі нормалізованої форми суми продуктів або продукту сум.

Лише наприкінці курсу я дізнався, що це справжній процесор: PDP-8, якщо я правильно згадую.

Сьогодні ви можете подати схему воріт у програмований чіп логічного масиву.

У цьому суть: встановлюється реєстр з результатами ворота AND і OR, що ведуть до інших регістрів. Одне із значень, яке слід включити, - це значення коду.

Тож уявіть собі: A: = (opcode == 17 & X + Y) | (opcode == 18 & X + Z) | ...

Сучасні процесори складніші з трубопроводами і автобусами, але окремі субодиниці, як-от одна АЛУ, працюють таким чином.


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 є синтаксисом. Він визначає, які біти вийдуть, коли ви вставляєте біти. Семантика його - це концепція здатності робити додавання. Ми з вами знаємо, що АЛУ може "робити доповнення", але щоб зрозуміти, що відбувається внизу, ви повинні пам'ятати, що АЛУ маніпулює лише бітами та байтами синтаксису.


0

Процесори працюють так:

  • отримати поточну інструкцію, збільшити покажчик "поточної інструкції".

  • розшифруйте його (наприклад, дізнайтеся, що ця інструкція говорить процесору)

  • виконайте його (зробіть те, що говорить інструкція) - поточний покажчик інструкції може бути змінений, якщо інструкція є чимось на зразок "стрибка".

  • Повторіть назавжди

Сучасні процесори складніші і намагаються сильно перекриватись і навіть передбачати частини цього процесу (наприклад, почати виконувати, поки 10 інших інструкцій декодують, тоді як процесор отримує набагато попереду вказівника "поточної інструкції", щоб "конвеєри" залишалися в повному обсязі), але істотний процес насправді той самий.

Існує багато типів інструкцій, приклад більшості з них:

  • "Перемістити" інструкції. Вони можуть скопіювати X на інший X, де X - пам'ять (RAM), реєстр або адреса в просторі вводу / виводу, якщо ЦП підтримує таке поняття.

  • Інструкції щодо маніпулювання стеком, включаючи спливаючу реєстрацію, push-регістр на стеку тощо. Це особливий випадок інструкцій "переміщення", які використовують та оновлюють реєстр "покажчик стека".

  • Інструкції, які виконують математичні операції, або між двома регістрами, або з пам'яттю, і з регістром. Ці інструкції автоматично впливають на регістр прапорів. Один такий прапор - це "нульовий" прапор, який встановлюється, якщо результат дорівнює нулю, інший - "негативний" прапор, який встановлюється, якщо встановлено найбільш значущий біт результату. Можуть бути й інші, залежно від процесора.

  • Окремим випадком математичних операцій є інструкції по порівнянню, що таке саме, як віднімання, але результат не зберігається. Прапори досі уражені.

  • Існують інструкції гілки, які переходять до адреси пам'яті, якщо встановлені специфічні прапори. Пам'ятаєте згаданий вище прапор "нуль"? Він також подвоюється як прапор "якщо рівний", тому ви бачите інструкції, як BEQна багатьох процесорах, які насправді розгалужуються, якщо встановлено прапор "нуль".

  • Інструкції, які виконують логічні операції (І, АБО, НЕ), переміщують біти та тестові біти. Вони можуть впливати на прапори, як математичні інструкції залежно від процесора.

  • Інструкції, які стрибають беззастережно.

  • Інструкції, що стрибають і зберігають зворотну адресу в стеку ("виклик"), та інші інструкції, що виводять адресу зі стека ("повернення").

  • Спеціальні інструкції, як-от такі, що зупиняють процесор, ідентифікують процесор або викликають оброблювачів переривань.

  • "Без операції" - майже всі процесори мають інструкцію "без відключення", яка просто споживає цикли та рухається далі.

Це справді лише приклад, є процесори з меншим типом інструкцій та процесори з більшою кількістю.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.