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

Мой Любимый Кот

Новеллы, Головоломки, Коты

Играть

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

  • cristall75 cristall75 6 постов
  • 1506DyDyKa 1506DyDyKa 2 поста
  • Animalrescueed Animalrescueed 35 постов
Посмотреть весь топ

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

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

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

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

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

Используем C в Ассембли⁠⁠

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

Разрабатывая стандартную библиотеку для своего языка, столкнулся с проблемой: как связывать код написанный на C с ассембли. Первый подход – компиляция C в ассембли и ручное копирование кода – оказался не самым удобным. Две проблемы этого способа это несовместимость синтаксиса GCC и Nasm и постоянное дублирование кода при малейших изменениях.

Решение

Теперь расскажу о способе, который является оптимальным – линковке объектных файлов.

Пример

Приведу пример из моего языка программирования – функция для печати целых чисел.

debug.c

Важно, что функция объявлена с модификатором extern, то есть доступна глобально.


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

debug.c

debug.h

Теперь, создаём объектный файл.

gcc -nostdlib -no-pie -fno-stack-protector -c debug.c -o debug.o

Флаги -no-pie и -fno-stack-protector нужны для совместимости с ассембли.

main.asm

Компилируем и компонуем с объектным файлом стандартной библиотеки

nasm -f elf64 main.asm -o main.o

gcc -nostdlib -no-pie main.o debug.o -o main

Получаем одиночный бинарный файл, в котором включены и стандартная библиотека и главный файл.

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


P.S: Тело функции

Показать полностью 5
[моё] Программирование Языки программирования Компиляция Компилятор Гайд Обучение Длиннопост
13
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
NutrientElement
NutrientElement
Arduino & Pi

Немного подкопотника компиляторов⁠⁠

2 года назад

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

Компиляторы могут быть разными по своему устройству, функциональности и целям. Например, есть компиляторы, которые транслируют код с одного языка на другой, например, Babel или TypeScript. Есть компиляторы, которые оптимизируют код для конкретной архитектуры или платформы, например, GCC или LLVM. Есть компиляторы, которые используют динамическую компиляцию, то есть компилируют код во время его исполнения, например, JIT-компиляторы в Java или .NET. Есть компиляторы, которые реализуют специальные возможности или фичи языков, например, векторизация, макросы, рефлексия и т.д.

Интересные факты и фичи языков программирования у нас в канале, заходи :)

[моё] Программирование Программист IT Linux Разработка Компиляция Текст
0
1863
Maryanix
Maryanix
IT-юмор

Ошибочка…⁠⁠

2 года назад
Ошибочка…
Показать полностью 1
IT IT юмор Программист Программирование Компилятор Компиляция Картинка с текстом Кот
52
5
TB3Zveno7
TB3Zveno7
Лига программистов

Кто недавно CS50 проходил, не являясь студентом Гарварда, у вас их IDE работала?⁠⁠

3 года назад

Ууууух, блэт! Качественно намудохался с их средой, и так и не нашёл актуальные команды к терминалу.


Написал прогу Хало Ворлд из третьей лекции от 2015 года, тут же решил сохранить и скомпилировать её через make. Хуй там! В ответ появился вопрос Did you type helloword.c? Эмм... Почему-то в демонстрации у гарвардского препода такой проблемы не было. Вспоминая, как он в другой ситуации просто ввёл букву y, чтобы дать положительный ответ, повторил за ним. Терминал команду не понял. От нефиг делать написал слово полностью - yes. Терминал лёг, спамя буквой y.

Благо, в лекции показали староверскую версию команды - clang. Один хуй, компилятор не завёлся.


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


Теперь думаю, ну нахой этот CS50, пойду качну нормальную оффлайн IDE и книгу Кернигана\Ритчи.

Показать полностью 1
Программирование IDE C++ IT Компиляция Cs50 Обучение Вопрос Гарвард Мат
26
22
an0nims

Про ошибки исполнения⁠⁠

4 года назад

Вдохновение... Хочется открыть IDE, написать говнокод, и дебажить, дебажить задыхаясь от восторга...

Про ошибки исполнения

Шутка моя, а картинка найдена на просторах интернета.

IT юмор Картинка с текстом Юмор Мемы Том и Джерри IT Программирование Ошибка Программист Программа Компиляция Отладка Исключение
4
1469
EHOTnOTACKYH
EHOTnOTACKYH
IT-юмор

За пределами наших владений⁠⁠

4 года назад
За пределами наших владений

Локальная переменная: А что там за пределами фигурных скобок?

Компилятор: Это за пределом твоих границ.

Программирование IT юмор Компиляция
72
10
O..O
O..O

Каждая ошибка была знаменитой на весь мир⁠⁠

4 года назад
Каждая ошибка была знаменитой на весь мир

Или же, если хотите стать знаменитым и богатым, научитесь устранять ошибки в кратчайшие сроки)

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