- •Что надо знать, перед изучением ассемблера.
- •Какие системы счисления использует ассемблер
- •Понятие системы счисления
- •Двоичная
- •Восьмеричная
- •Шестнадцатеричная
- •Как и где программа хранит код и данные
- •Виды памяти
- •Способы адресации
- •Сегменты
- •Страницы
- •Регистры
- •Регистры общего назначения (РОН)
- •Регистры данных
- •Регистры указатели
- •Сегментные регистры
- •Служебные регистры
- •Как программа исполняется ЦПУ
- •Структура программы на Ассемблере MASM32
- •Комментарии
- •Сегменты
- •Переменные
- •Метки
- •Инструкции ассемблера
- •Основные инструкции ассемблера х86:
- •Используемая литература
dw |
word |
2 |
Int16, кодсимволаUTF-16. |
dd |
dword |
4 |
Int32, float |
df . |
- |
6 |
|
dt. |
- |
10 |
80-бит действительное число. |
Существует триспособа инициализации переменной:
1)Одним скалярным значением, например:
;объявляет переменную alpha, выделяет 1 ячейку памяти, размером в 1 байт и заполняет значением 1. alpha db 1
;объявляет переменную beta, выделяет 1 ячейку памяти, размером в 2 байта и заполняет значением 23. beta dw 23
;объявляет переменную gamma, выделяет 1 ячейку памяти, размером в 1 байт и заполняет кодом символа ‘a’. gamma db ’a’
2)Массив, заполненный одним значением:
;объявляет переменную delta, выделяет 256 ячеек памяти, размером по 1 байту и заполняет их значением 0. delta db 100h dup(0)
;объявляет переменную theta, выделяет 256 ячеек памяти, размером по 1 байту и не заполняет их.
theta db 100h dup(?)
3)Строка:
; объявляет переменную sigma, выделяет 5 ячеек памяти, размером по 1 байту и заполняет их строкой ‘hallo’. sigma db ’hallo’
Так же данные способы можно комбинировать:
;объявляет переменную omega, выделяет 24 ячейки памяти, размером по1 байту и заполняет их
;указанными значениями в том же порядке, в котором они перечислены через запятую.
omega db 0, 10 dup(1), ’a’, ‘hallo world$’
МЕТКИ
В любом месте программы могут стоять метки. Меткой может быть любая последовательность латинских символов и цифр, начинающаяся с цифры и оканчивающаяся символом двоеточия. В программе обязательно должна присутствовать метка startи конструкция ENDstartв конце программы. Она играет роль точки входа в программу, то есть программа всегда начинается с инструкции следующей за меткой start.Это некий аналог функции main()из С++.
ИНСТРУКЦИИ АССЕМБЛЕРА
В ассемблере MASM32 используется двухадресный код. Это означает, что любая команда, направляемая процессору, состоит из кода операции и двух операндов, хотя второй операнд, в некоторых операциях может не использоваться.
Общий шаблон инструкции процессора:
<КОД ОПЕРАЦИИ><ОПЕРАНД 1>,<ОПЕРАНД 2>
Основные инструкции ассемблера х86:
|
Имя |
|
Шаблон |
Поведение |
Пример |
||||
|
|
|
|
|
Арифметика и работа с памятью |
|
|
||
|
|
|
mov<РЕГИСТР 1>,<РЕГИСТР 2> |
|
|
Копирует значение из регистра 2 в |
mov ax, bx |
||
|
|
|
|
|
|
|
регистр 1. |
|
|
|
mov |
|
mov<РЕГИСТР>,<АДРЕС В ПАМЯТИ> |
|
Копирует значение из памяти в регистр |
mov ax, word ptrds:[003Ah] |
|||
|
|
|
|
|
|
|
|
|
movbx, word ptres:[003Ah] |
|
|
|
|
|
|
|
|
|
movcx, word ptr [003Ah] |
|
|
mov< АДРЕС В ПАМЯТИ>,<РЕГИСТР> |
|
Копирует значение из регистра в памят |
mov word ptrds:[003Ah], ax |
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
mov word ptres:[003Ah], bx |
|
|
|
|
|
|
|
|
|
|
|
|
mov word ptr [003Ah], cx |
add |
|
add<РЕГИСТР 1>,<РЕГИСТР 2> |
|
|
|
Вычисляет сумму регистра 1 и регистра |
|
|||||
|
|
|
|
|
|
|
|
|
|
2 и помещает в регистр 1. |
|
|
sub |
|
sub<РЕГИСТР 1>,<РЕГИСТР 2> |
|
|
|
Вычисляет разность регистра 1 и |
|
|||||
|
|
|
|
|
|
|
|
|
|
регистра 2 и помещает в регистр 1. |
|
|
mul |
|
mul<МНОЖИТЕЛЬ> |
|
|
|
|
если множитель имеет |
mulbl |
||||
|
|
|
|
|
|
|
|
|
|
|
размер byte, то в качестве |
mulbx |
|
|
|
|
|
|
|
|
|
|
|
второго сомножителя будет |
mulebx |
|
|
|
|
|
|
|
|
|
|
|
взят регистр al. |
mul word ptr[beta] |
|
|
|
|
|
|
|
|
|
|
|
если множитель имеет |
|
|
|
|
|
|
|
|
|
|
|
|
размер word, то в качестве |
|
|
|
|
|
|
|
|
|
|
|
|
второго сомножителя будет |
|
|
|
|
|
|
|
|
|
|
|
|
взят регистр ax. |
|
|
|
|
|
|
|
|
|
|
|
|
если множитель имеет |
|
|
|
|
|
|
|
|
|
|
|
|
размер dword, то в качестве |
|
|
|
|
|
|
|
|
|
|
|
|
второго сомножителя будет |
|
|
|
|
|
|
|
|
|
|
|
|
взят регистр eax. |
|
|
|
|
|
|
|
|
|
|
|
Результат: |
|
|
|
|
|
|
|
|
|
|
|
|
|
при умножении байтов |
|
|
|
|
|
|
|
|
|
|
|
|
результат помещается в ax; |
|
|
|
|
|
|
|
|
|
|
|
|
при умножении слов |
|
|
|
|
|
|
|
|
|
|
|
|
результат помещается в пару |
|
|
|
|
|
|
|
|
|
|
|
|
dx:ax. То есть младшее слово |
|
|
|
|
|
|
|
|
|
|
|
|
в ax, а старшее в dx. |
|
|
|
|
|
|
|
|
|
|
|
|
при умножении двойных |
|
|
|
|
|
|
|
|
|
|
|
|
слов результат помещается в |
|
|
|
|
|
|
|
|
|
|
|
|
пару edx:eax. |
|
|
|
|
|
|
|
|
||||||
div |
|
div<ДЕЛИТЕЛЬ> |
|
|
|
если делитель имеет размер |
div bl |
|||||
|
|
|
|
|
|
|
|
|
|
|
byte, то в качестве делимого |
div bx |
|
|
|
|
|
|
|
|
|
|
|
будет взят регистр ax. |
div ebx |
|
|
|
|
|
|
|
|
|
|
|
Частное будет помещено в |
div word ptr[beta] |
|
|
|
|
|
|
|
|
|
|
|
al, остаток в ah. |
|
|
|
|
|
|
|
|
|
|
|
если делитель имеет размер |
|
|
|
|
|
|
|
|
|
|
|
|
|
word, то в качестве делимого |
|
|
|
|
|
|
|
|
|
|
|
|
будет взята пара dx:ax. |
|
|
|
|
|
|
|
|
|
|
|
|
Частное будет помещено в |
|
|
|
|
|
|
|
|
|
|
|
|
ax, остаток в dx. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Сравнение значений |
|
|
cmp |
|
cmp<ОПЕРАНД 1>,<ОПЕРАНД 2> |
|
Вычитает из первого операнда второй, |
|
|||||||
|
|
|
|
|
|
|
|
|
|
но результат никуда не помещает, а |
|
|
|
|
|
|
|
|
|
|
|
|
всего лишь запоминает, как операнды |
|
|
|
|
|
|
|
|
|
|
|
|
соотносятся друг с другом |
|
|
|
|
|
|
|
|
|
|
|
|
(больше/меньше/равно/нуль и т.д.) |
|
|
test |
|
test<ОПЕРАНД 1>,<ОПЕРАНД 2> |
|
Выполняет операцию логического «И» |
|
|||||||
|
|
|
|
|
|
|
|
|
|
для указанных операндов, но результат |
|
|
|
|
|
|
|
|
|
|
|
|
никуда не помещает, а всего лишь |
|
|
|
|
|
|
|
|
|
|
|
|
запоминает, как операнды соотносятся |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
друг с другом |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(больше/меньше/равно/нуль и т.д.) |
|
|
|
|
|
|
Операции перехода, вызовы прерываний и подпрограмм. |
|||||||||||
jmp |
|
jmp<АДРЕС ПЕРЕХОДА> |
|
|
Данная инструкция не выполняет |
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
операций над данными, но заставляет |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
процессор безусловно перейти к |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
выполнению инструкции по |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
указанному адресу. |
|
|
|
|
Инструкции условного перехода. Являются полными аналогами инструкции jmp, за исключением |
|
||||||||||||
|
|
того, что инструкция выполняется процессором, только если выполнено соответствующее |
|
||||||||||||
|
|
условие. Все указанные условия проверяются для операндов последней выполненной |
|
||||||||||||
|
|
арифметической инструкции или же инструкции сравнения. |
|
||||||||||||
jb |
|
jb<АДРЕС ПЕРЕХОДА> |
|
|
|
|
|
если меньше, для чисел без знака |
|
||||||
ja |
|
ja<АДРЕС ПЕРЕХОДА> |
|
|
|
|
|
если больше, для чисел без знака |
|
||||||
je |
|
je<АДРЕС ПЕРЕХОДА> |
|
|
|
|
|
если равно |
|
|
|||||
jz |
|
jz<АДРЕС ПЕРЕХОДА> |
|
|
|
|
|
если нуль |
|
|
|||||
jae |
|
jae<АДРЕС ПЕРЕХОДА> |
|
|
|
если больше или равно, для чисел без |
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
знака |
|
|
jbe |
|
jbe<АДРЕС ПЕРЕХОДА> |
|
|
|
если меньше или равно, для чисел без |
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
знака |
|
|
jne |
|
jne<АДРЕС ПЕРЕХОДА> |
|
|
|
если не равно, для чисел без знака |
|
|
|||||||
jna |
|
jna<АДРЕС ПЕРЕХОДА> |
|
|
если небольше, для чисел без знака |
|
|
||||||||
jnb |
|
jnb<АДРЕС ПЕРЕХОДА> |
|
|
если неменьше, для чисел без знака |
|
|
||||||||
jg |
|
jg<АДРЕС ПЕРЕХОДА> |
|
|
|
|
если больше, для чисел со знаком |
|
|
||||||
jl |
|
jl<АДРЕС ПЕРЕХОДА> |
|
|
|
|
если меньше, для чисел со знаком |
|
|
||||||
jge |
|
jge<АДРЕС ПЕРЕХОДА> |
|
|
|
если больше или равно, для чисел со |
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
знаком |
|
|
jle |
|
jle<АДРЕС ПЕРЕХОДА> |
|
|
|
если меньше или равно, для чисел со |
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
знаком |
|
|
jo |
|
jo<АДРЕС ПЕРЕХОДА> |
|
|
|
если переполнение |
|
|
|||||||
call |
|
call<АДРЕС ПЕРЕХОДА> |
|
|
помещает в стек адрес следующей |
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
инструкции и переходит по адресу, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
который указан в качестве операнда. |
|
|
ret |
|
ret |
|
|
Достаёт из стека адрес и переходит по |
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
нему. |
|
|
int |
|
int<НОМЕР ПРЕРЫВАНИЯ> |
|
Работает аналогично call, но переходит |
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
не по любому адресу, а по адресу, в |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
котором хранится функция-обработчик |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
для прерывания с соответствующим |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
номером. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ТУТ можно посмотреть коды всех прерываний. Позже включу основные из них в методичку.