Главная страница
Предыдущая страница (зачем нужен Ассемблер)

Для нормального составления программ с использованием данного руководства требуется как минимум процессор Intel Pentium 60 Mhz (конечно, лучше если у вас Intel Pentium II или Intel Pentium III). Если у вас процессор ниже (например, Intel 80486), то могут возникнуть проблемы (некоторые команды не поддерживаются). Также здесь будут описаны команды расширения MMX (требуется Intel Pentium II) и команды расширения SSE (требуется Intel Pentium III). В данном руководстве мы считаем, что базы всех регистров установлены в ноль (используется самая простая модель памяти, всё в одном сегменте – и программа, и данные, и стек). Поэтому не будем использовать и писать сегментные регистры. Для написания программ подходит компилятор Free Pascal 1.94 for DOS (он удовлетворяет данным требованиям). Для программирования на ассемблере используйте ассемблерные вставки. Если вы не знаете Паскаль, то можете не читать данное руководство, так как ничего не поймёте

ALU (арифметико-логическое устройство)
Условные обозначения
r – регистр r32 – 32-разрядный r16 – 32-разр r8 – 8-разр
m – ячейка памяти m32 – 32-разрядная m16 – 16-разр m8 – 8-разр
C – константа C32 – 32-разрядная C16 – 16-разр C8 – 8-разр

То есть если мы пишем "r32", то предполагаем, что это один из восьми 32-разрядных регистров (eax, ebx, ecx, edx, esi, edi, ebp, esp). Если мы пишем m16 – то это переменная типа integer (или word), m32 – переменная типа longint, m64 – переменная типа int64. Если мы пишем C8, то это 8-разрядная константа (от -128 до 255) (так как ассемблер не знает, со знаком у нас числа, или без знака, то ему всё равно. Например, если cl=-1, а dl=255, то cl=dl)
Правила записи команд: "команда приёмник, источник" – так записывается большинство команд. При записи большинства команд разрядности приёмника и источника должны совпадать. После выполнения большинства команд источник не меняется. Обычно меняется приёмник

| – значок ИЛИ & – значок И \ – значок И_НЕ

Обозначения флагов процессора всегда будем делать синим цветом
Команды процессора всегда будут выделены жирным
Предупреждения всегда будем делать красным цветом
Примеры, пояснения и комментарии будут зелёными
Если найдёте ошибки, пишите мне на ICQ: 397-731-673

Процессор и память

Вот основные регистры процессора: eax, ebx, ecx, edx, esi, edi, ebp, esp – 32-разрядные регистры. ax, bx, cx, dx, si, di, bp, sp – их младшие половины (16-битные слова). Регистры ax, bx, cx, dx – доступны по байтам, например, ah – cтарший байт ax, al – младший байт ax. Старшие половины 32-разрядных регистров недоступны напрямую (наверное, Intel так сделала для упрощения процессора)

Вообще, каждый регистр процессора по определению служит определённой цели, и используя регистры по назначению, по-видимому, можно улучшить программу, хотя не факт. Вот для чего нужны данные регистры:
1) eax – аккумулятор (для хранения результата действий)
2) ebx – регистр базы (используется в качестве базы для адресации)
3) ecx – используется в качестве счётчика (в циклах)
4) edx – регистр данных (подобно eax)
5) esi – индекс источника
6) edi – индекс приёмника
7) ebp – регистр базы (используется компилятором)
8) esp – регистр стека (используется компилятором)
Но при этом, повторяю, вы можете использовать регистры по своему усмотрению и для любых целей, кроме ebp и esp (они используются с определёнными ограничениями). Вставка на Ассемблере всегда должна возвращать в исходное состояние регистры ebp и esp

1) Задание адреса: [C32 + r32 + 1|2|4|8*(r32\esp)], где “C32” может быть как положительным, так и отрицательным, и нулём. Если получается число больше 4 Gb, берётся остаток от деления. Например, [eax] и [eax+4*ecx], где ecx=1073741824 – два одинаковых адреса. Если вы используете сложный тип адресации, например, dword ptr [eax+4*ebx+10], это не страшно – процессор хорошо справляется с подобными вещами. Он это выполняет почти с такой же скоростью, как, например, при использовании dword ptr [eax]. Дело в том, что вычисление выражений подобного рода в процессоре сильно оптимизировано. Более того, эту способность процессора быстро вычислять выражения определённого типа можно использовать для быстрых вычислений (иногда помогает). Получить адрес глобальной переменной можно с помощью offset. Например, пусть “x” – глобальная переменная типа longint. Тогда после команды “mov eax, offset x” регистр eax получит адрес переменной “x”. Если далее выполнить команду “mov dword ptr [eax], 100”, то переменная “x” получит значение 100
2) При записи ячеек памяти (переменных) в командах пишут обозначения:
byte ptr – 8-разрядная переменная (типы byte и shortint)
word ptr – 16-разрядная переменная (типы integer и word)
dword ptr – 32-разрядная переменная (типы longint, dword и single)
qword ptr – 64-разрядная переменная (типы int64 и double)
tbyte ptr – 80-разрядная переменная (тип extended)
То есть, если мы пишем dword ptr x, то имеем ввиду, что "x" – 32-разрядная переменная (типа longint, single и т п)
3) Закон Intel: в ОЗУ данные, состоящие более чем из одного байта хранятся таким образом, что младший байт всегда хранится по младшему адресу, поэтому адрес массива – это всегда адрес его младшей ячейки. Отрицательные числа в процессоре хранятся в дополнительном обратном коде, поэтому команды сложения и вычитания знаковых и беззнаковых чисел одинаковые
4) В программах для процессоров Intel стек идёт сверху вниз, при занесении данных в стек указатель стека esp уменьшается на число байтов, занесённых в стек. В стек можно занести только 2 или 4 байта (1 байт нельзя)

Флаги процессора

Описание регистра флагов здесь
ZF – флаг нуля. Устанавливается в 1, если результат предыдущей операции – ноль
SF – флаг знака. Он всегда равен старшему биту результата
CF – флаг переноса. Устанавливается в 1, если результат предыдущей операции над беззнаковыми числами не уместился в приёмнике и произошёл перенос из старшего бита, или если требуется заём (при вычитании), иначе 0
OF – флаг переполнения. Устанавливается в 1, если результат предыдущей арифметической операции над числами со знаком выходит за допустимые для них пределы
AF – флаг полупереноса. Устанавливается в 1, если в результате предыдущей операции произошёл перенос или заём из третьего бита в четвёртый. Этот флаг используется автоматически командами двоично-десятичной коррекции. Например, после двух команд: mov eax, 15; inc eax; флаг AF будет равен единице. После последовательности команд: mov eax, 16; dec eax; флаг AF также будет равен единице
PF – флаг чётности. Устанавливается в 1, если младший байт результата предыдущей команды содержит чётное число битов, равных единице, иначе 0. Например, после двух команд: mov al, 2; inc al; флаг PF установится в 1
IF – флаг прерываний. 1 – прерывания разрешены, 0 – прерывания запрещены
DF – флаг направления. 0 – строки обрабатываются в сторону увеличения адресов, 1 – в сторону уменьшения адресов

Следующая страница (описание простейших команд Ассемблера)