На главную  Программирование на Ассемблере в Fasm  Операционные Системы  Написать Автору  Полезные ссылки



Для поиска введите икомое слово в текстовое поле и нажмите Enter:


Основы.

Когда-то очень давно программы писались в машинных кодах.В шестнадцитиричном счислении это выглядит так:
b409ba0901cd21cd2048656c6c6f20776f726c642124
Затем люди решили приблизить язык програмирования к людскому(раз люди тупые,значит машина должна поумнеть-так думали корифеи программерской науки) и изобрели Ассемблер.Вот эта же прога на Ассемблере FASM.

; fasm example of writing 16-bit COM program

        org     100h               ; code starts at offset 100h
        use16                      ; use 16-bit code

;display_text = 9

        mov     ah,9;display_text
        mov     dx,hello
        int     21h
        int     20h

hello db 'Hello world!',24h

Конечно люди на этом не остановились.Языков програмирования и их диалектов становитя всё больше и больше.Из них наибольшее распространение получил С.Кроме того до сих пор живы ADA,FORTRAN,PASCAL.Появились C++,JAVA,C# и другие приблуды.Но до сих пор есть вещи,которые может сделать только Ассемблер.Поэтому он до сих пор востребован и несмотря на то что большинство старых языков давно забыты,он и теперь нужен и о нём помнят (Конечно некоторые используют его для создания вирусов,кейгенов,кряков,модификаторов и иных гадких програм,но большинство использует его в мирных целях.)

Коды ассемблера представляют непосредственно команды процессора, которые он может выполнять. Для примера:

add eax, edx

Эта инструкция, add, складывает вместе два значения. Eax и edx называются регистрами, они могут содержать значения, которые хранятся внутри процессора. Этот код будет преобразован в 66 03 C2 (шестнадцатиричный код). Процессор читает эти коды, и выполняет операцию, которую они представляют. Языки высокого уровня, например С, при компиляции преобразовывается в ассемблер, а ассемблер в двоичный код.

Коды операции (опкоды)

Программы Ассемблера пишутся в опкодах. Опкоды это команды, которые понимает процессор. Например:

ADD eax, 3

ADD имеет 2 операнда. В в этом случае, это источник и приемник. Он(Опкод ADD) добавляет значение источника к значению приемника и сохраняет результат в приемнике. Операнды могут быть разных типов: регистры, ячейки памяти, непосредственные значения .Подробней изучить опкоды вы сможете прочитав Fasmbook от i2k.

Регистр

Регистр - это область памяти в процессоре.

Значит так, регистры: 
eax/ax/ah/al,ebx/bx/bh/bl,edx/dx/dh/dl,ecx/cx/ch/cl,ebp/bp,esi/si,edi/di,esp/sp -это ячейки памяти,которые могут содержать следующее: 

  • операнды логических и арифметических операций 
  • компоненты адреса 
  • указатели на ячейки памяти
Регистры классифицируются по размерам и назначению.

Размеры регистров:

Регистры бывают разных размеров : 8 бит, 16 бит, 32 бит (и больше ). Вы можете использовать регистры как 8 и 16 размером бит.
Некоторые регистры являются частью других; например, если EAX содержит значение 12345678h, вот то, что содержат другие регистры.

EAX 12 34 56 78
AX 12 34 56 78
AH 12 34 56 78
AL 12 34 56 78

регистры ax, ah, al - части регистра eax. Eax это 32-битный регистр , ax содержит младшие 16 бит (2 байта) регистра eax, ah содержит старший байт регистра ax, и al содержит младший байт регистра ax. Регистр ax - 16 битный, al и ah - 8 битные. Получается:

eax12345678h  (32-бит)
ax5678h       (16-бит)
ah56h         (8-бит )
al = 78h         (8-бит )

Назначение регистров:

Универсальные регистры:
Большинство регистров вы можете использовать как хотите (например я люблю хранить что-то в ebx).Вот они:
eax/ax/ah/al
ebx/bx/bh/bl
edx/dx/dh/dl
ecx/cx/ch/cl

Вы спросите как их можно ипользовать в своих программах?Вот так:
mov eax,32  -Помещаем в eax 32.
mov ebx,20  -Помещаем в ebx 20.
sub eax,ebx -Из eax вычитаем ebx.Теперь в eax у нас 12(32-20=12).
Стоит отметить что в некоторых командах использование какого-то из этих регистров обязательно.Вот назначения этих регистров для некоторых команд.
eax/ax/ah/al -(Accumulator register) Аккумулятор. Применяется для хранения промежуточных данных.
ebx/bx/bh/bl - (Base register)Базовый регитр. Применяется для хранения базового адреса некоторого обьекта в памяти.
edx/dx/dh/dl -(Data register) - Регистр данных.Применяется для хранения промежуточных данных. В некоторых командах его использование обязательно, для некоторых команд это происходит неявно.
ecx/cx/ch/cl-(Count register) Регистр-счетчик. Применяется в командах, производящих некоторые повторяющиеся действия.Его использование зачастую неявно и скрыто в алгоритме работы соответствующей команды.Например команда оргинизации цикла loop, кроме передачи управления команде, находящейся по некоторому адресу, анализирует и уменьшает на еденицу значение регистра ecx/cx.

Регистры указателя


esi (si)   -Индекс источника
edi (di)  -Индекс приемника
eip (ip)  -Указатель команды

Вы можете использовать регистры указателя, как универсальные регистры (eip - исключение), пока вы сохраняете их первоначальные значения. Регистры указателя называются так потому, что их часто используют для сохранения адресов памяти. Некоторые опкоды (movb,scasb, и т.д.) также их используют.
esi (si) - (Soutce Index register) - Индекс источника.Этот регистр в цепочных операциях содержит текущий адрес в цепочке-источнике.
edi (di) - (DestinationIndex register) - Индекс приемника.Этот регистр в цепочных операциях содержит текущий адрес в цепочке-приемнике.
Оба регистра используются для строковых операций.В них адресс строки-источника помещается в esi,а адресс строки-приёмника в edi.Пример:

cld                           - Сброс флага DF
mov esi,STR1          - Загрузка str  в si
mov edi,STR2         - Загрузка str2 в di
mov ecx,5                - Загрузка в cx, 5 повторений для rep
rep movsb                - Пересылка строк

Этот фрагмент кода  загружает 5 байт из STR1 в STR2.

Регистр EIP (или IP в 16-разрядных программах) содержит указатель на команду, которую собирается выполнить процессор. Так что вы не можете использовать регистр eip как универсальный.

Регистры указателя стека

ebp/bp -(Base Pointer register)Регстр указателя базы кадра стека. Предназначен для организации произвольного доступа к данным внутри стека(используется  как указатель на локальные переменные).
esp/sp
-(Stack Pointer register)Регистр указателя стека. Содержит указатель вершины стека в текущем сегменте стека( текущую позицию стека в памяти).

Сегментные регистры

Сегментные регистры определяют сегмент(участок) памяти, которая используется. Вероятнее всего, они вам не понадобятся в win32, потому, что windows использует flat систему памяти. В DOS, память разделена на сегменты по 64kb, так, что если вы хотите определить адрес памяти, вы определяете сегмент и смещение (например 0172:0500 (сегмент:смещение)). В windows, сегменты имеют размер 4Gb.Так что при адреассации  просто надо  указать смещение . Сегментные регистры всегда - 16-битные.

Каждый сегментный регистр обеспечивает адресацию 64К памяти, которая называется текущим сегментом. Как показано ранее, cегмент выравнен на границу параграфа и его адрес в сегментном pегистре предполагает наличие справа четырех нулевых битов.

Р е г и с т р CS. Регистр сегмента кода содержит начальный адрес сегмента кода. Этот адрес плюс величина смещения в командном указателе (IP) определяет адрес команды, которая должна быть выбрана для выполнения. Для обычных программ нет необходимости делать ссылки на регистр CS.

Р е г и с т р DS. Регистр сегмента данных содержит начальный адрес сегмента данных. Этот адрес плюс величина смещения, определенная в команде, указывают на конкретную ячейку в сегменте данных.

Р е г и с т р SS. Регистр сегмента стека содержит начальный адрес в сегменте стека.

 Р е г и с т р ES. Некоторые операции над строками используют дополнительный сегментный регистр для управления адресацией памяти. В данном контексте регистр ES связан с индексным регистром DI. Если необходимо использовать регистр ES, ассемблерная программа должна его инициализировать.

Регистры FS (только с 286+)  и GS (только с 386+) -Универсальные сегментные регистры.С чем их едят,не знаю...

Память.

В 16-разрядных программах(в DOS) память была разделена на сегменты. Эти сегменты имели размер 64kb. Для доступа к памяти были необходимы: указатель на сегмент и указатель смещения. Указатель сегмента указывал, какой сегмент (секцию 64kb) использовать, указатель смещения указывал непосредственно на место в сегменте. Смотрите таблицу:
Память
Сегмент 1 (64kb)
Сегмент 2 (64kb)
Сегмент 3 (64kb)
Сегмент 4(64kb)
и так далее

Учтите, что это объяснение для 16-разрядных программ, о 32-разрядных я расскажу позже, (но не пропускайте эту часть, важно понять, что такое 32-разрядность).
Таблица выше иллюстрирует общую память, разделенную на сегменты по 64kb. Здесь максимум 65536 сегментов. Теперь возмите один из сегментов:

Сегмент 1(64kb)
Смещение 1 Смещение 2 Смещение 3 Смещение 4 Смещение 5 и так далее

Чтобы указать на местоположение в сегменте используется смещение. Смещение - это местоположение внутри сегмента. Здесь в сегменте максимум 65536 смещений. Запись адреса в памяти:

СЕГМЕНТ:СМЕЩЕНИЕ (SEGMENT:OFFSET)

Например:

0030:4012 (все числа шестнадцатиричные)

Это означает: сегмент 30, смещение 4012. Чтобы узнать, что находится в том адресе, вы сначала переходите на сегмент 30, а затем в сегменте смещаетесь на 4012

В 32-х разрядных программах(Windows)есть только смещения и они теперь 32-разрядные (в диапазоне от 0 до 4,294,967,295). Каждая ячейка в памяти указывается смещением,так как один сегмент равен 4ГБ(ГигаБайт) и возиться с сегментами нам не надо.(Ура!Работы меньше!!).

Страница1 из 2НаверхСтраница2 из 2
Сайт управляется системой uCoz