Быстро кодируйте свои первые функции сборки (синтаксис 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. Он все еще находится на начальной стадии, но если вы сочли эту статью полезной, подписка на ее рассылку будет лучшим способом воодушевить меня ❤️