Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Регистрируясь, я даю согласие на обработку данных и условия почтовых рассылок.
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр Рисковый и азартный три в ряд - играйте онлайн!

Камни в ряд онлайн!

Казуальные, Три в ряд, Мультиплеер

Играть

Топ прошлой недели

  • solenakrivetka solenakrivetka 7 постов
  • Animalrescueed Animalrescueed 53 поста
  • ia.panorama ia.panorama 12 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

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

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Маркет Промокоды Пятерочка Промокоды Aroma Butik Промокоды Яндекс Путешествия Промокоды Яндекс Еда Постила Футбол сегодня
0 просмотренных постов скрыто
19
georgiyozhegov
georgiyozhegov
Лига программистов
Серия Программирование

Путь от Кода до Бинарного Файла⁠⁠

9 месяцев назад

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

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

Этапы

1. Lexing

На этом этапе исходный код в виде строки разделяется на отдельные части, то есть токены. Этот этап – самый простой во всём процессе компиляции.

Вход

let a = 10 + 2

if a > 8 then

debug "A больше 8"

else

debug "А либо меньше, либо равно 8"

end

Выход

[

Let, Identifier("a"), Equal, Integer(10), Plus, Integer(2),

If, Identifier("a"), Greater, Integer(8), Then,

Debug, String("A больше 8"),

Else,

Debug, String("А либо меньше, либо равно 8"),

End,

]

2. Parsing

Здесь поток токенов объединяется в AST или абстрактное синтаксическое дерево. В этом дереве содержится вся информация об исходном коде в структурированном виде, удобным для обработки и анализа. Например, с его помощью можно проверять корректность типов переменных.

[

Let {

identifier: "a",

value: Binary(Add, Integer(10), Integer(2)),

},

If {

condition: Binary(Greater, Identifier("a"), Integer(8)),

then: [Debug(String("A больше 8"))],

else_: [Debug(String("А либо меньше, либо равно 8"))],

},

]

3. Промежуточное представление (IR)

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

В компиляторах Rust и Clang в качестве промежуточного представления используется LLVM IR, так как его экосистема берёт на себя многие оптимизации, и компилирование в ассемблерный код для разных платформ как X86, ARM и так далее.

Граф потока управления (CFG)

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

Блоки, не содержащие условий

{

0: [

Let {

identifier: "a",

value: Binary(Add, Integer(10), Integer(2)),

},

],

1: [Debug(String("A больше 8"))],

2: [Debug(String("А либо меньше, либо равно 8"))],

3: Empty,

}

Блок Empty – это пустой блок, который не содержит в себе инструкций, и служит только для удобства построения CFG.

И условные переходы между блоками

{

0: Branch { # переход с условием

condition: Binary(Greater, Identifier("a"), Integer(8)),

true_: 1,

false_: 2,

},

1: Direct(3), # прямой переход без условия

2: Direct(3),

}

Трёхадресный код (3AC)

Состоит из низкоуровневых инструкций максимально приближенных к нативному ассембли-коду.

Первый блок

[

Label(0),

LoadInteger { to: 0, value: 10 },

LoadInteger { to: 1, value: 2 },

Add { to: 2, left: 0, right: 1 },

Set { identifier: "a", from: 2 },

Get { to: 3, from: "a" },

LoadInteger { to: 4, value: 8 },

Greater { to: 5, left: 3, right: 4 },

JumpIf { condition: 5, label: 1 },

Jump(2),

Второй

Label(1),

LoadString { to: 6, value: "A больше 8" },

Debug { value: 6 },

Get { to: 7, from: "a" },

LoadInteger { to: 8, value: 8 },

Greater { to: 9, left: 7, right: 8 },

JumpIf { condition: 9, label: 3 },

Jump(2),

Третий

Label(2),

LoadString { to: 10, value: "А либо меньше, либо равно 8" },

Debug { value: 10 },

И последний, пустой блок

Label(3),

]

Или в виде псевдо-кода

@0:

#0 = 10

#1 = 2

#2 = add #0 #1

$a = #2

#3 = $a

#4 = 8

#5 = gt #3 #4

jump @1 if #5

jump @2

@1:

#6 = "A больше 8"

debug #6

#7 = $a

#8 = 8

#9 = gt #7 #8

jump @3 if #9

jump @2

@2:

#10 = "А либо меньше, либо равно 8"

debug #10

@3:

4. Ассембли

Далее, каждая 3AC инструкция конвертируется в одну или несколько ассемблерных инструкций, которые уже напрямую выполняются на процессоре без какой-либо прослойки.

section .data

str_0: db "A больше 8", 0

str_1: db "А либо меньше, либо равно 8", 0

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

section .bss

a: resq 1

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

section .text

global _start

_start:

Делаем _start глобально видимым для того, чтобы линкер смог собрать бинарный файл.

L0:

mov rax, 10

mov rbx, 2

mov rcx, rax

add rcx, rbx

mov [a], rcx

a = rcx = rax + rbx = 10 + 2 = 12.

mov rax, [a]

mov rbx, 8

cmp rax, rbx

mov rcx, 0

setg cl

rcx = rax > rbx = a > 8 = 1 то есть true.

cmp rcx, 1

je L1

jmp L2

Если rcx = 1, то есть true, то переходим в L1, иначе – в L2.

L1:

mov rax, str_0

call debug

debug – это какая-то функция, которая печатает строки в консоль. В целях соблюдения компактности, я не стал её включать в код. Регистр rax – первый аргумент.

mov rax, [a]

mov rbx, 8

cmp rax, rbx

setg rcx

cmp rcx, 1

je L3

jmp L2

L2:

mov rax, str_1

call debug

L2 – начало блока else.

L3:

mov rax, 60

mov rdi, 0

syscall

Выходим из программы, производя системный вызов (syscall). В rax находится номер вызова – 60, то есть выход (SYS_exit). А в rdi лежит статус завершения программы, в данном случае 0, то есть успешное завершение.

Полезное

  • Мой блог про программирование и не только

  • Классика –Crafting Interpreters

  • Исходники компилятора Rust

  • BabyGo – маленький компилятор для Go

  • Серия видео по разработке Porth с нуля

Заключение

Надеюсь вам понравилась эта статья! Она написана на основе моего хобби-компилятора, поэтому если у вас есть желание внести свою лепту в проект – отправляйте пул-реквест в репозиторий!

Показать полностью
[моё] Программа Обучение Гайд Assembler Asm Компиляция Компилятор Программирование Текст Длиннопост
9
Quizly
Quizly
Лига Геймеров

Ярчайшие Моменты из Эфиров Twitch // [QEHC-2]⁠⁠

9 месяцев назад

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

Как вам ? Я всегда жажду улучшений и будет интересно, что вам понравилось, а что нет.

Обложку решил сделать минималистичную, но яркую

Обложку решил сделать минималистичную, но яркую

Также я создал тизер для этого видео :)

В нём, как в безумной непонятной нарезке - попытался передать дух видео и анонсировать дату премьеры :)

Обложка Тизера. Как бы - загорается название видео)

Обложка Тизера. Как бы - загорается название видео)

Показать полностью 2 1
[моё] Стримеры YouTube Стрим Игры Юмор Реакция Игровой юмор Подборка Компиляция Видеоблог Видеомонтаж Геймеры Видео
0
23
kenny9600
kenny9600

National Geographic. Польская версия⁠⁠

10 месяцев назад
Перейти к видео
Видео Вертикальное видео Польша Поляки Польский язык The National Geographic Компиляция Без перевода Мат Бобр курва Курва
4
0
Quizly
Quizly
Stream game

TWITCH HIGHLIGHTS / Хайлайты Твича — Quizly: Crazy Clip Compilation⁠⁠

11 месяцев назад

Создал компиляция самых смешных клипов за последнее время из эфиров Twitch
QCCC > https://youtu.be/bO5e0gXEQ3M

[моё] YouTube Веселье Twitchtv Стрим Стримеры Юмор Подборка Компиляция Видео
0
1
Random.Idea
Random.Idea

Смешная нарезка с животными⁠⁠

11 месяцев назад
RUTUBE Животные Компиляция Видео
1
3
bruzgoff
bruzgoff

Если на мелких ошибках учатся, то на крупных — защищают диссертации⁠⁠

11 месяцев назад

Диктант написать не смогу, а вот диссертацию - запросто...

Плагиат → позаимствовал у одного.

Компиляция → позаимствовал у двух.

Позаимствовал у трёх → диссертация.

¯\_(ツ)_/¯

Плагиат Компиляция Диссертация Юмор Ошибка Творчество Текст
2
1
merlinus

Любимые стихи в своём аккаунте: Обработка текста дворовой песни «О Дикий Запад»⁠⁠

1 год назад

О Дикий Запад, страна скалистых гор,

Страна ковбоев и голубых озер.

Кто нас здесь тронет, тот смерть свою найдёт,

В руке моей не дрогнет старый воронёный кольт


Во имя Сэма, я во Вьетнаме был,

Для дяди Сэма деревни там бомбил,

Но залп зенитный, наш лайнер запылал.

И я поймав волну мэйдэй на базу передал.

Под облаками наш самолет горит.

И вместе с нами, на землю он летит.

А жить осталось лишь несколько минут,

И в цинковых коробках нас в Америку свезут!


О Дикий Запад, страна скалистых гор,

Страна ковбоев и голубых озер.

А до Вьетнама я в Аризоне жил,

И там себе я старый воронёный кольт купил.


Земля всё ближе, клубится чёрный дым

В кабине трое, а парашют один

Дерутся двое, а я слабее всех

Лежа с пробитой головой решился я на грех.

Я из кармана свой револьвер достал,

И бортмеханик к моим ногам упал,

В крови весь штурман, хрипит что "Это Ад!",

О мама, мама, мама, забери меня назад!


О Дикий Запад, страна скалистых гор,

Страна ковбоев и голубых озер.

Мы жили в мире, мы были лучше всех,

Но кровью искупили за навязанный нам грех.


Вы новобранцы, совет держите мой

Вы новобранцы, вас отвезут в Ханой,

Там партизаны стреляют всех подряд

Бросайте автоматы и в Америку назад.

Всем генералам на вас давно плевать

Двадцатилетних вас гонят воевать

И во Вьетнаме вы свой найдете крест

В Америке прибавится заплаканных невест.


Ах Джонни, виски ты мне ещё налей

Я пью сегодня за всех своих друзей

Их не воротишь, они не прилетят

Ведь это с ними улетел я в тот кромешный ад.


О Дикий Запад, страна скалистых гор,

Страна ковбоев и голубых озер.

Куда не кинешь, ты свой орлиный взгляд

Лишь горе и могилы невернувшихся солдат!

Показать полностью
[моё] Лирика Поэзия Двор Война в Афганистане Война во Вьетнаме Стихи Народное творчество Обработка Компиляция Кавер Ремикс Ремейк Юрий Хой Юность Песня под гитару Текст
3
6
user7788906
user7788906

Стекло волос⁠⁠

1 год назад

Белеет парус одинокий.

Не парус – облако в штанах.

И глупый пингвин толстобокий,

И гроб хрустальный на цепях.

И эти жёлтые ботинки

Во глубине сибирских руд...

Я проиграю в поединке –

Там призраки живут...

Гуляет день по тротуарам.

Не буду больше молодым...

– Скажи-ка, дядя, ведь недаром

Твоих волос стеклянный дым?..

– Не сыпь мне соль, прошу, на рану.

И без того болит она...

На кухне мама мыла раму.

И ухмыляется луна...

Показать полностью
[моё] Стихи Компиляция Классика Слова Строки Текст
0
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Маркет Промокоды Пятерочка Промокоды Aroma Butik Промокоды Яндекс Путешествия Промокоды Яндекс Еда Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии