Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

Организация циклов.

Иногда надо организовать цикл, т. е. совершить повторение количество раз, которое указано в регистре ECX. Следовательно, надо у теле цикла уменьшать значение ECX. Именно для этого предназначена команда loop. Он проверяет, равен ли регистр ECX нулю, если он не равен нулю, то значение регистра ECX уменьшается на 1 и совершается ближний прыжок на смещение указанное в операнде.

Mov ecx, 023h

repeat:

::..; обязательно ближнее расстояние

Loop repeat

Тело цикла выполнится 23h раза.

Команда loope делает то же самое, но перед прыжком проверяет, установлен ли флаг ZF, если он установлен, то прыжок совершается. Точно тоже самое делает команда loopz. Команды loopne и loopnz делают то же сомое что и loope, но прыгают, если флаг ZF сброшен.

С переходами разобрались. Разобрались не только с переходами, но и с циклами.

Урок 8

Арифметические операции - ADD, SUB, MUL, DIV. Многие опкоды делают вычисления. Вы можете узнать многие из них по их названиям: add (addition - добавление), sub (substraction - вычитание), mul (multiply - умножение), div (divide - деление).

Опкод add имеет следующий синтаксис:

add приемник, источник

Выполняет вычисление : приемник = приемник + источник.

Имеются также другие формы:

приемник

источник

пример

регистр

регистр

add ecx, edx

регистр

память

add ecx, dword ptr [104h] / add ecx, [edx]

регистр

значение

add eax, 102

память

значение

add dword ptr [401231h], 80

память

регистр

add dword ptr [401231h], edx

Эта команда очень проста. Она добавляет значение источника к значение приемника и помещает результат в приемник. Другие математические команды:

НЕ нашли? Не то? Что вы ищете?

sub приемник, источник (приемник = приемник - источник)

mul множимое, множитель (множимое = множимое * множитель)

div делитель (eax = eax / делитель, edx = остаток)

Поскольку регистры могут содержать только целочисленные значения (то есть числа, не, с плавающей запятой), результат деления разбит на частное и остаток. Теперь, в зависимости от размера источника, частное сохраняется в eax, а остаток в edx:

размер источника

деление

частное в...

остаток в...

BYTE (8-bits)

ax / делитель

AL

AH

WORD (16-bits)

dx:ax* / делитель

AX

DX

DWORD (32-bits)

edx:eax* / делитель

EAX

EDX

* = Например: если dx = 2030h, а ax = 0040h, dx: ax = h. Dx:ax - значение dword, где dx представляет старшее word, а ax - младшее. Edx:eax - значение quadword (64 бита), где старшее dword в edx и младшее в eax.

Источник операции деления может быть:

8-бит регистр (al, ah, cl,.бит регистр (ax, dx, .бит регистр (eax, edx, ecx...) 8-бит значение из памяти (byte ptr [xxxx]) 16-бит значение из памяти (word ptr [xxxx]) a 32-бит значение памяти (dword ptr [xxxx])

Источник не может быть непосредственным значением, потому что тогда процессор не сможет определить размер исходного операнда.

Логические операции с битами - OR, XOR, AND, NOT. Эти команды работают с приемником и источником, исключение команда 'NOT'. Каждый бит в приемнике сравнивается с тем же самым битом в источнике, и в зависимости от команды, 0 или 1 помещается в бит приемника:

команда

AND

OR

XOR

NOT

Бит источника

0

0

1

1

0

0

1

1

0

0

1

1

0

1

Бит приемника

0

1

0

1

0

1

0

1

0

1

0

1

X

X

Бит результата

0

0

0

1

0

1

1

1

0

1

1

0

1

0

AND (логическое И) устанавливает бит результата в 1, если оба бита, бит источника и бит приемника установлены в 1.

OR (логическое ИЛИ) устанавливает бит результата в 1, если один из битов, бит источника или бит приемника установлен в 1.

XOR (НЕ ИЛИ) устанавливает бит результата в 1, если бит источника отличается от бита приемника.

NOT инвертирует бит источника.

Пример:

mov ax, 3406d

mov dx, 13EAh

xor ax, dx

ax = 3406 (десятичное), в двоичном - .

dx = 13EA (шестнадцатиричное), в двоичном - .

Выполнение операции XOR на этими битами:

Источник = (dx)

Приемник = (ax)

Результат = (новое значение в ax)

Новое значение в ax, после выполнения команды - в десятичном, 1EA5 - в шестнадцатиричном).

Другой пример:

mov ecx, FFFF0000h

not ecx

FFFF0000 в двоичном это -

Если вы выполните инверсию каждого бита, то получите:

, в шестнадцатиричном это 0000FFFF

Значит после операции NOT, ecx будет содержать 0000FFFFh.

Увеличение/Уменьшение - INC/DEC. Есть 2 очень простые команды, DEC и INC. Эти команды увеличивают или уменьшают содержимое памяти или регистра на единицу.

Просто поместите:

inc регистр ; регистр = регистр + 1

dec регистр ; регистр = регистр - 1

inc dword ptr [103405] ; значение в [103405] будет увеличено на 1.

dec dword ptr [103405] ; значение в [103405] будет уменьшено на 1.

Ещё одна команда сравнения - test. Команда Test выполняет операцию AND (логическое И) с двумя операндами и в зависимости от результата устанавливает или сбрасывает соответствующие флаги. Результат не сохраняется. Test используется для проверки бит, например в регистре:

test eax, 100b

jnz смещение

Команда jnz выполнит переход, если в регистре eax третий бит справа - установлен. Очень часто комманду test используют для проверки, равен ли регистр нулю:

test ecx, ecx

jz смещение

Команда jz выполнит переход, если ecx = 0.

Ничего не делающая команда - nop. Эта команда не делает абсолютно ничего (пустая команда). Она только занимает пространство и время. Используется для резервирования места в сегменте кода или организации программной задержки.

Обмен значениями - XCHG. Команда XCHG также весьма проста. Назначение: обмен двух значений между регистрами или между регистрами и памятью:

mov eax, 237h

mov ecx, 978h

xchg eax, ecx

в результате:

eax = 978h

ecx = 237h

Урок 9

На этом уроке я вам расскажу про подпрограммы и структуры. Подпрограмма по-простому это процедура (или функция: без разницы, язык Pascal дал этим терминам разные определения), а структура это запись.

Подпрограммы.

Подпрограммы удобны, когда некоторое действие повторяется несколько раз в программе. Процедуры делают программу более читабельной и надёжнее, в такой программе легче устранять ошибки и улучшать.

Процедуры задаются директивами proc и endp. Proc обозначает начало процедуры, а endp конец процедуры. Вот пример объявления процедуры:

SameProc proc

...more code...

Ret ; обязательно

SameProc endp

Вызов процедуры

...

Call SameProc

...

Если вызывающий использует, какие либо регистры и подпрограмме нельзя изменять их то для этого эти регистры надо сохранять в стеке.

SameProc proc

Push ebx

Push edi

...more code...

Mov esi, edx

:изменяем сохранённые регистры:.

Pop edi

Pop ebx

Ret

SameProc endp

Специально для этого создана директива uses.

SameProc proc uses ebx, esi

...more code...

Mov esi, edx

...изменяем сохранённые регистры...

Ret ; обязательно

SameProc endp

И всё теперь вместо всяких "пушев" и "попов" ставите ret, TASM сделает всё за вас: в начале поставит "пуши" вместо ret поставит "попы" (извините за выражение) и ret.

Имя процедуры становится обычной меткой. Можно получать значение, на которое она указывает (обычно это значение равно опкоду первой инструкции процедуры), но изменить его получится, поскольку секция кода доступна только для чтения.

Структуры.

Структура это набор переменных (данных). Структура задаётся с помощью директивы struct и ends.

SOMESTRUCTURE STRUCT

dword1 dd?

dword2 dd?

some_word dw?

abyte db?

anotherbyte db?

SOMESTRUCTURE ENDS

(имя структуры не должно содержать прописных букв).

Вы также можете объявить ваши переменные как в секции с инициализированными данными, так и в секции с неинициализированными данными, со знаком вопроса.

MYSTRUCT struc

dword1 dd?

dword2 dd?

some_word dw?

abyte db?

anotherbyte db?

MYSTRUCT ends

.data

msg MYSTRUCT <?>

или

MYSTRUCT struc

dword1 dd?

dword2 dd?

some_word dw?

abyte db?

anotherbyte db?

MYSTRUCT ends

.data?

msg MYSTRUCT <?>

одинаковый результат, но во втором случае размер файла будет меньше.

Для того чтобы получить доступ к записи надо указать метку переменной, которой она обозначена и через точку указать имя поля.

mov [msg. dword1], 45h

xor eax, eax

mov eax, [msg. dword1] ; eax = 45

при этом запись msg. dword1 считается обычной меткой данных: берётся смещение метки msg плюс смещение поля dword1 в структуре, размер данных по умолчанию равен размеру директивы указанной после метки поля. Также можно пользоваться обращением к полю при обращении к записи через регистр:

mov [msg. dword2], 45h

xor eax, eax

lea ebx, msg

mov eax, [ebx].dword2 ; eax = 45

в данном случае к смещению, которое указано в ebx прибавляется смещение dword2 в своей структуре. Так как имя поля не гарантирует уникальности то лучше использовать такой тип использования записи так:

mov [msg. dword2], 45h

xor eax, eax

lea ebx, msg

mov eax, [ebx].MYSTRUCT. dword2 ; eax = 45

это безопаснее. Для того, что бы окончательно разобраться с записями приведу ещё один пример, в котором используется доступ к полю записи в лоб:

mov [msg. abyte], 45h

xor eax, eax

lea ebx, msg

mov al, [ebx+10d] ; al = 45

к ebx я прибавил 10d, потому что смещение поля abyte в структуре равно 10d.

Урок 10

Главной альтернативой секции .const является простое объявление символьной константы. Всё гениальное просто (слишком сильно сказано):

CONST_VALUE = 678h

.data

Dd CONST_VALUE

.code

...more code...

Mov edi, CONST_VALUE

Xor eax, CONST_VALUE

Вторая не менее важная альтернатива это определение "макросимвола" (я это сам придумал, а по научному абсолютный символ или "прозвище"). Он задаётся через директиву equ.

примеры

CONST1 equ 0123h

CONST2 equ 14d*15h

CONST3 equ "slovo"

CONST4 equ 56-45

CONST5 equ (offset metka1)

CONST6 equ (offset metka2+offset metka3)

CONST7 equ (CONST2+10b)

CONST8 equ CONST7/2

CONST9 equ (offset metka1-offse metka5)

CONST10 equ (offset metka4+CONST4)

CONST11 equ add edx, edi

... и так далее до посинения...

Директива equ используется в там же, где определяются символьные константы. Это ещё не все возможности этой директивы. О ней можно говорить очень много. Я вам объяснил, как надо объявлять численные константы, но также можно дать прозвище некоторой команде, например:

Command1 equ mov eax, esi.

После этого при каждом упоминании command1 будет подразумеваться команда move eax, esi.

Пример

Mov eax, CONST1

Add edi, CONST2

Xor ebp, CONST7

CONST11

Sub edx, CONST8

Объявлять equ надо в начале файла там же где объявляются структуры и константы.

Макрос - это набор команд. С помощью equ мы могли создавать "прозвище" только для одной команды, а с помощью макросов можно создавать "прозвище" для нескольких команд. Для создания макроса надо использовать директивы macro и соответственно endm.

Firstmacro macro

Sub ebp, esp

Mov eax, ebp

Endm

Теперь если компилятор встречает слово Firstmacro, то он автоматически заменяет его на тело макроса. Также макросу можно передавать параметры.

Secondmacro macro param1, param2

Add edi, param1

Sub esi, param2

endm

.code ; использование

..........

Secondmacro 55h, edx

У макросов очень много возможностей. Я объяснил самые важные из них, а на объяснение всех возможностей этого урока не хватит. Макросы очень часто используются в MASM.

Иногда надоедает (особенно при создании оконных приложений) объявлять в каждой программе одни и те же структуры и константы. Хотелось бы один раз их задать, а потом их использовать в каждой своей программе как в Си или Паскале. Для этого предназначены включаемые файлы *.inc. В них можно задать структуры, константы, макросы. Для включения такого файла надо использовать директиву include. После этой директивы надо указать путь к включаемому файлу абсолютный или относительный. При написании такого файла просто думайте, что вы находитесь после директивы. model и до. data.

Пример:

Файл sample. asm

;=======[CUT HERE]========

.386

.model flat, stdcall

include sample. inc

extrn MessageBoxA:PROC

.data

Msg db "First ASSEMBLER program",0h

Ttl db 'Hello, World!!!!',0h

RCTNGL RECT?

.code

start:

call MessageBoxA,0,offset Msg, offset Ttl, MB_OKCANCEL

call ExitProcess, 0

end start

;=====[CUT HERE]==========

Файл sample. inc

;=======[CUT HERE]========

extrn ExitProcess:PROC

UINT EQU <dd> ; 32 bits for WIN32

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5