Ассемблер
Как выглядит код на ассемблере
Код на ассемблере выглядит как набор коротких инструкций, меток, секций данных и операций с регистрами. Он не похож на Python или JavaScript, потому что работает ближе к процессору: вместо «вывести строку» вы явно кладете адрес строки в регистр, указываете длину и вызываете механизм операционной системы
Пример маленького фрагмента
section .data
number db 5
section .text
global _start
_start:
mov al, [number]
add al, 3
Этот фрагмент не выводит результат на экран, но показывает базовый вид ассемблерного кода:
section .data— область данных;number db 5— один байт со значением 5;section .text— область кода;_start:— метка;mov al, [number]— загрузить байт из памяти в регистр;add al, 3— прибавить 3 к регистру.
Из чего состоит код
В ассемблере часто встречаются:
- инструкции:
mov,add,sub,cmp,jmp; - регистры:
rax,eax,al,rbx,rcx; - метки:
start:,loop:,done:; - секции:
.data,.text,.bss; - директивы ассемблера:
global,db,equ; - комментарии.
Комментарии обычно пишутся через ; в NASM/MASM-подобной записи:
mov eax, 1 ; положить 1 в eax
Почему примеры отличаются
Один и тот же смысл может выглядеть по-разному. NASM, MASM, FASM и GAS используют разные правила записи. Еще важнее архитектура: x86-64, ARM, AVR, Z80 и i8080 — это разные миры. Поэтому правильный вопрос не только «как выглядит ассемблер», а «как выглядит ассемблер для какой платформы»
Например, в x86 часто встречается:
mov eax, 10
А в Z80-подобном коде можно увидеть:
LD A, 10
Обе строки похожи по смыслу: положить значение в регистр. Но синтаксис и регистры разные
Как читать код новичку
Читайте ассемблер сверху вниз и задавайте четыре вопроса:
- Какие данные объявлены?
- Какие регистры используются?
- Какие инструкции меняют значения?
- Где есть переходы и условия?
Если видите cmp, ищите рядом условный переход. Если видите call, ищите подпрограмму. Если видите квадратные скобки вроде [number], это обращение к памяти, а не просто имя переменной
Чем ассемблер отличается от машинного кода
Ассемблер читается человеком: mov, add, cmp. Машинный код — это байты, которые выполняет процессор. Ассемблер переводит мнемоники в машинные инструкции. Поэтому ассемблерный код еще нужно собрать, прежде чем он станет исполняемой программой
Частые ошибки
Думают, что весь ассемблер одинаковый
Нет. Вид кода зависит от процессора, операционной системы и ассемблера
Не отличают директивы от инструкций
db и section нужны ассемблеру. mov и add — инструкции процессора
Не замечают обращения к памяти
number и [number] могут означать разные вещи: адрес и значение по адресу
Что почитать дальше по ассемблеру
Если нужен общий маршрут по теме, откройте рубрику ассемблеру. Для соседних задач пригодятся эти разборы:
- Как выглядит программа на ассемблере
- Как запустить код на ассемблере
- CMP в ассемблере
- CMP в ассемблере: как работает сравнение
Как проверить результат на практике
Для ассемблера важно сначала понять, под какую среду написан пример: DOSBox/TASM, Linux x64/NASM, Visual Studio/MASM или микроконтроллер. Один и тот же смысл может записываться разным синтаксисом, поэтому не переносите команды между средами вслепую. Создайте отдельную папку для примера, сохраните файл с расширением .asm, выполните сборку именно тем инструментом, который указан в уроке, и сравните вывод или состояние регистров с ожидаемым результатом
Если пример не собирается, читайте первую ошибку ассемблера: обычно она указывает на строку, неизвестную инструкцию, неверную метку, неправильную секцию или конфликт синтаксиса. Исправляйте одну ошибку за раз. В ассемблере это особенно важно, потому что маленькая опечатка в метке, регистре или размере операнда может полностью изменить поведение программы