Быстро кодируйте свои первые функции сборки (синтаксис Intel x86–64)
И понимать язык, на котором говорит ваш процессор
Хотя C можно считать языком низкого уровня, его синтаксис по-прежнему абстрагирует многие инструкции, сделанные вашим процессором. Вот почему вы можете захотеть узнать о языках программирования более низкого уровня, таких как Assembly.
Эта статья предоставит вам основные инструменты для понимания функций сборки, чтобы вы могли создавать свои собственные 👷♂️.
Начиная
Язык различается в зависимости от архитектуры вашего процессора. В следующих разделах я сосредоточусь на синтаксисе Intel x86–64, который используется на большинстве настольных компьютеров.
Инструменты
Вы можете написать свой ассемблерный код внутри .s
файлов и скомпилировать их с nasm
компилятором.
Аргумент
-f
позволяет указать формат вывода. В данном случае macho64 - это формат современных исполняемых файлов macOS.
Отлаживать
Как только вы начнете кодировать свои собственные функции, я настоятельно рекомендую вам ознакомиться с такими инструментами отладки, как lldb
и gdb
.
Язык
Ассемблер описывает последовательность команд, которые будет выполнять ваш процессор. Одна строка означает одну инструкцию.
Машинный код
Одна из распространенных ошибок - думать, что язык ассемблера - это то же самое, что и машинный код. Машинный код - это двоичный, исполняемый компьютером. Сборка по-прежнему требует компиляции, имеет то преимущество, что она более читаема людьми и лучше подходит для структурирования вашей программы (с именами переменных, макросами, разделами и т. Д.).
Файловая структура и области статических данных
Файл .s
можно разделить на 4 типа разделов: data
, rodata
, bss
, text
. Если ничего не указано, по умолчанию используется text
.
Выше описаны 3 области статических данных. В разделе .text
хранится логика кода. В следующих разделах будет описано, как вы можете построить эту логику.
Доступ к памяти
В вашем распоряжении 3 типа памяти: регистры, адреса памяти (RAM) и константы. Регистрация проходит очень быстро, но в вашем распоряжении всего дюжина. Адреса памяти могут хранить много данных, но работают медленнее.
Общие регистры
rax, rbx, rcx, rdx
Они используются в большинстве инструкций. Их имена на самом деле не имеют значения, но вот их значение.
a
: Регистр накопителяb
: Базовый регистрc
: Регистр счетчикаd
: Регистр данных
Регистры индексов
EDI
: Регистр назначенияESI
: Реестр источниковEBP
: Указатель базы стекаESP
: Регистр указателя стекаEIP
: указатель индекса, сохраняет указатель следующей инструкции
Сегментные регистры
Вероятно, они вам не понадобятся для простых функций: CS
(сегмент кода), DS
(сегмент данных), SS
(сегмент стека), ES
FS
GS
инструкции
Каждая строка представляет одну инструкцию. Обычно у вас есть идентификатор команды, за которым следуют аргументы.
CMD ARG1, ARG2
Перемещение ценностей
mov - <dst> [reg, mem]
, <src> [reg, mem, const]
Он копирует элемент данных, указанный в src
, в расположение dst
. Однако вы не можете копировать данные между двумя адресами памяти mov mem0, mem1
(вы можете сделать это, используя две инструкции и один регистр).
push - <data> [reg, mem, const]
Перенести данные в стек (подробнее о стеке).
поп - <dst> [reg, mem]
Вставить первое доступное в стеке значение в dst
.
lea - <dst> [reg]
, [<src>] [mem]
Обозначает «эффективный адрес загрузки». Он сохраняет адрес src
в данном регистре.
Математические операции
добавить - <dst> [reg]
, <src> [reg]
Складывает dst
и src
и сохраняет результат в dst
.
sub - <dst> [reg]
, <src> [reg]
Вычтите dst
и src
и сохраните результат в dst
.
декабрь - <dst> [reg]
Уменьшает на 1 данный регистр.
inc - <dst> [reg]
Увеличивает на 1 данный регистр.
Инструкции по потоку управления
call - <function_name>
— вызов функции
jmp - <dst_location>
- Перейти к разделу
Передает выполнение инструкции, указанной в операнде.
j ‹condition› - <dst_location>
- переход к разделу, если условия соблюдены
То же, что и jmp
, но только если условие верно. Полный список условий доступен здесь.
Тестирование и сравнение значений
cmp - <reg0> [reg]
, <reg1> [reg]
- Установить коды условий для reg1-reg0
test - <reg0> [reg]
, <reg1> [reg]
- Установите коды условий для reg0 & reg1
ret - завершение функции.
Соглашения о вызовах
Существует много условностей. Например, аргументы обычно передаются в таком порядке %rdi, %rsi, %rdx, %rcx, %r8 and %r9
. Для получения более подробной информации перейдите по ссылке ниже.
Системные вызовы
Ядро предоставляет вам множество системных вызовов. Полный список находится здесь.
Некоторые базовые примеры
ft_isascii
Память и стек
На эту тему ушла бы целая статья среднего размера. Я обновлю эту статью, когда сделаю это.
Ресурсы для развития
Я реализовал в Assembly многие базовые функции. Если хотите посмотреть, вот репо 😊.
Я открываю новый сайт под названием myopen.market. Он все еще находится на начальной стадии, но если вы сочли эту статью полезной, подписка на ее рассылку будет лучшим способом воодушевить меня ❤️