Андрей Ипполитов – Ассемблер ARM64 (страница 11)
.skip 64
.section
Открывает произвольную секцию с указанием атрибутов (например, .section .rodata,"a").
.section .rodata,"a"
.func / .endfunc
Явно ограничивает границы функции (полезно для отладчиков).
.func my_func … .endfunc
.cfi_*
Директивы для генерации информации о раскладке стека (Call Frame Information) – нужны отладчикам и исключениям.
.cfi_startproc … .cfi_endproc
Как они взаимодействуют
Секции (.text, .data, .bss, .rodata и т.п.) определяют, где в объектном файле будет размещён код или данные.
Выравнивание (.align, .org) гарантирует, что последующие инструкции/данные находятся на корректных границах, что критично для производительности и корректного доступа к памяти.
Экспорт/импорт (.global, .type) позволяют другим объектным файлам видеть функции/переменные.
Константы и макросы (.equ, .macro) упрощают поддержку кода и позволяют менять параметры без правки множества мест.
Условные директивы (.if/.else/.endif) позволяют писать один файл, который собирается по‑разному для разных целевых платформ (например, наличие криптографических инструкций).
Эти директивы составляют основу любого проекта на ассемблере и позволяют контролировать как генерацию машинного кода, так и структуру итогового исполняемого файла.
Выравнивание (Alignment)
Процессоры, работают эффективнее, когда доступ к данным происходит по адресам, кратным размеру этих данных.
•
32-битные данные (4 байта) лучше всего загружаются/сохраняются по адресам, кратным 4.
•
64-битные данные (8 байт) лучше всего загружаются/сохраняются по адресам, кратным 8.
Если вы попытаетесь загрузить 64-битное значение по адресу, не кратному 8, это может привести к:
•
Исключению (
Alignment
Fault
): Процессор может вызвать ошибку.
•
Снижению производительности: Процессор может выполнить несколько операций для чтения данных, или операционная система может исправить ошибку “на лету”, что замедлит выполнение.
Ассемблер и линкер на macOS обычно автоматически позаботятся о выравнивании для статических данных (используя директивы типа .align). Однако, при работе с динамической памятью или при ручном управлении смещениями, вам может потребоваться учитывать выравнивание самостоятельно.
Глава 3 Инструкции по передачи данных
Инструкции по передаче данных являются фундаментальными элементами ассемблера. Они позволяют перемещать данные между регистрами, памятью и непосредственными значениями, обеспечивая основу для любых операций в программе. В этой главе мы рассмотрим основные инструкции передачи данных, их синтаксис, примеры использования и особенности применения.
Перемещение константы в регистр
Инструкция MOV является основным инструментом для копирования значений. Когда речь идет о перемещении константы (непосредственного значения) в регистр, MOV также является выбором номер один.
MOV <Rd>, #immediate
•
Регистр назначения, куда будет помещено непосредственное значение. Это может быть 64-битный регистр (
x
0-
x
30,
xzr
) или 32-битный регистр (
w
0-
w
30,
wzr
).
•
Непосредственное значение, которое должно быть помещено в регистр.
Как это работает:
Инструкция MOV с непосредственным значением напрямую встраивает значение в код программы. Ассемблер преобразует это число в машинный код, который процессор может непосредственно использовать.
; Поместить число 100 в 64-битный регистр x0
mov x0, #100
После выполнения этой инструкции, регистр x0 будет содержать значение 100. Старшие 32 бита регистра x0 будут заполнены нулями, поскольку 100 – это положительное число, помещающееся в 32 бита.
Перемещение 32-битного значения:
mov x1, #255
После выполнения этой инструкции, младшие 32 бита регистра x1 (т.е. w1) будут содержать 255. Старшие 32 бита регистра x1 будут обнулены.
mov x5, #0