реклама
Бургер менюБургер меню

Андрей Ипполитов – Ассемблер ARM64 (страница 11)

18

.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

<Rd>:

Регистр назначения, куда будет помещено непосредственное значение. Это может быть 64-битный регистр (

x

0-

x

30,

xzr

) или 32-битный регистр (

w

0-

w

30,

wzr

).

#immediate:

Непосредственное значение, которое должно быть помещено в регистр.

Как это работает:

Инструкция 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