Как выглядит ассемблер

Ассемблер выглядит как набор коротких инструкций, которые работают с регистрами, памятью, флагами и переходами. Вместо привычных if, for и функций высокого уровня вы видите mov, add, cmp, jmp, метки и обращения к памяти. При этом внешний вид зависит от синтаксиса: NASM, MASM, TASM и GAS могут записывать похожие идеи по-разному

Простой фрагмент

Вот как может выглядеть небольшой фрагмент в Intel/NASM-стиле:

mov eax, 5
add eax, 3
cmp eax, 8
je equal

Читается так:

  • положить 5 в регистр eax;
  • прибавить 3;
  • сравнить eax с 8;
  • перейти на метку equal, если значения равны.

Ассемблер выглядит коротко, но каждая строка очень конкретна

Регистры

В коде часто встречаются имена регистров:

rax
rbx
rcx
rdx
rsp
rbp

В 32-битном x86 будут:

eax
ebx
ecx
edx
esp
ebp

Регистр — это маленькая быстрая ячейка внутри процессора. Ассемблерный код часто выглядит как перекладывание значений между регистрами и памятью

Метки и переходы

Метка выглядит как имя с двоеточием:

loop_start:
    add ecx, 1
    cmp ecx, 10
    jl loop_start

Это похоже на ручное управление потоком выполнения. jl loop_start означает: если условие выполнено, вернуться к метке loop_start

Данные и секции

Полная программа часто имеет секции:

section .data
    msg db "Hello", 10

section .text
    global _start

Секция .data хранит данные. Секция .text хранит код. Директивы вроде section и global нужны assembler, а не самому процессору

Обращения к памяти

В Intel/NASM-синтаксисе память часто пишется в квадратных скобках:

mov eax, [rbp-4]
mov [rbp-8], eax

Это означает чтение или запись по адресу. Например, [rbp-4] часто указывает на локальную переменную в стеке

В AT&T-синтаксисе похожая запись выглядит иначе:

movl -4(%rbp), %eax

Поэтому один и тот же ассемблерный смысл может выглядеть непривычно в разных источниках

Как выглядит DOS/TASM

Учебный DOS-пример может выглядеть так:

.model small
.stack 100h

.data
    msg db 'Hello$'

.code
main proc
    mov ax, @data
    mov ds, ax
    mov ah, 09h
    lea dx, msg
    int 21h
main endp
end main

Здесь видны DOS-прерывания, .model small и int 21h. Такой код отличается от Linux x64 примеров

Как выглядит Linux x64

Пример Linux x64:

section .text
global _start

_start:
    mov rax, 60
    xor rdi, rdi
    syscall

Здесь rax хранит номер системного вызова, rdi — аргумент, а syscall обращается к ядру Linux

Частые ошибки в чтении

Считать все ассемблеры одинаковыми

Синтаксис и платформа сильно влияют на внешний вид

Путать директивы и инструкции

mov — инструкция процессора. section — директива assembler

Не понимать скобки

rbp — регистр. [rbp-4] — память по адресу rbp - 4

Что почитать дальше по ассемблеру

Если нужен общий маршрут по теме, откройте рубрику ассемблеру. Для соседних задач пригодятся эти разборы:

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x