Умножение беззнаковых чисел

MUL OP2; (OP2)*(AL) Ú (AX) Ú (EAX) ® AX Ú DX:AX Ú EDX:EAX.

Содержимое ОР2 умножается на содержимое AL, AX, EAX в зависимости от типа операнда и пересылается в них же соответственно.

Умножение знаковых чисел.

IMUL OP2; аналогично MUL

IMUL OP1, OP2 ;i386 и >

Содержимое первого операнда умножается на содержимое второго и результат записывается в первый операнд.

IMUL op1, op2, op3 ; i186 и >

Содержимое второго умножается на содержимое третьего и результат в первый.

OP1 всегда регистр, OP2 – непосредственный операнд, регистр или память.

При умножении результат имеет удвоенный формат по отношению к сомножителям. Иногда мы точно знаем, что результат может уместиться в формат сомножителей, тогда мы извлекаем его из AL, AX, EAX.

Размер результата можно выяснить с помощью флагов OF и CF.

Если OF = CF = 1, то результат занимает двойной формат, и OF = СF = 0 , результат умещается в формат сомножителей.

Остальные флаги не изменяются.

Деление беззнаковых чисел: Деление знаковых чисел.

DIV OP2; OP2 = r Ú m IDIV OP2; OP2 = r Ú m

(AX) Ú (DX:AX) Ú (EDX:EAX) делится на указанный операнд и результат помещается в AL Ú AX Ú EAX, остаток помещается в AH Ú DX Ú EDX.

Значение флагов не меняется, но может наступить деление на 0 или переполнение, если 1) op2 = 0, 2) частное не умещается в отведенное ему место. Например:

MOV AX, 600

MOV BH, 2

DIV BH; 600 div 2 = 300 - не умещается в AL.

При использовании арифметических операций необходимо следить за размером операндов. При необходимости их нужно расширять.

Пример:

Необходимо цифры целого беззнакового байтового числа N записать в байты памяти, начиная с адреса D как символы. N - (abc)

c = N mod 10

b = (N div 10) mod 10

a = (N div 10) div 10

Перевод в символы: код(i) = код (‘0’) + i

---------------------

N DB ?

D DB 3 Dup (?)

------------------

MOV BL, 10; делитель

MOV AL, N; делимое

MOV AH, 0; расширяем делимое до слова

; или CBW AH конвертируем до слова

DIV BL; A L= ab, AH = c

ADD AH, ‘0’

MOV D+2, AH

MOV AH, 0

DIV BL; AL = a, AH = b

ADD AL, ‘0’

MOV D, AL

ADD AH, ‘0’

MOV D+1, AH

----------------------

7) Основные элементы языка Ассемблера: имена, константы, переменные, выражения.

Алфавит из 26 латинских букв и цифр. Прописные и строчные буквы не различаются.

Символические имена в Ассемблере могут состоять из строчных и прописных букв латинского алфавита, цифр от 0 до 9 и некоторых символов ‘_’, ‘.’, ‘?’, . Могут состоять из произвольного количества символов, но значащими будут считаться только первые 31.

Константы – неизменные в процессе программы величины. Ассемблер может работать с именованными и неименованными. В программе на Ассемблере могут использоваться константы пяти типов: целые двоичные, десятичные, шестнадцатеричные, действительные с плавающей точкой, символьные.

Целые двоичные – это последовательности 0 и 1 со следующим за ними символом ‘b’, например, 10101010b или 11000011b.

Целые десятичные - это обычные десятичные числа, возможно заканчивающиеся буквой d, например, – 125 или 78d.

Целые шестнадцатеричные числа – должны начинаться с цифры и заканчиваются всегда ‘h’, если первый символ – ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, то перед ним необходимо поставить 0, иначе они будут восприниматься как символические имена.

Числа действительные с плавающей точкой представляются в виде мантиссы и порядка, например, – 34.751е+02 – это 3475.1 или 0.547е-2 – это 0.00547.

Символьные данные – это последовательности символов, заключенные в апострофы или двойные кавычки, например,

'abcd', 'a1b2c3', ‘567'.

Также, как и в языках высокого уровня, в Ассемблере могут использоваться именованные константы. Для этого существует специальная директива EQU. Например,

M EQU 27; директива EQU присваивает имени М значение 27.

Переменные в Ассемблере определяются с помощью директив определения данных и памяти, например,

V1 DB ?

V2 DW 34

или с помощью директивы ‘ = ’

v3 = 100

v3 = v3+1

Константы в основном используются в директивах определения или как непосредственные операнды в командах.

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

Арифметические операции: ‘+’, ‘-‘, ‘*’, ‘/’, mod.

Логические операции: NOT, AND, OR, XOR (исключ. или).

Операции отношений: LT(<), LE(£), EQ(=), NE(¹), GT(>), GE(³).

Операции сдвига: сдвиг влево (SHL), сдвиг вправо (SHR)

Специальные операции: offset и PTR

offset <имя> - ее значением является смещение операнда, а операндом может быть метка или переменная;

PTR – определяет тип операнда:

BYTE = 1 байт,

WORD = 2 байт,

DWORD = 4 байт,

FWORD = 6 байт,

QWORD = 8 байт,

TWORD = 10 байт;

или тип вызова: NEAR – ближний, FAR – дальний.

Примеры выражений: 1) 10010101b + 37d 2) OP1 LT OP2

3) (OP3 GE OP4) AND (OP5 LT OP6) 4) 27 SHL 3 ;

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

Директивы определения

Общий вид директивы определения следующий

[<имя>] DX <операнды> <; комментарии>,

где Х это B, W, D, F, Q или T.

В поле операндов может быть ‘?’, одна или несколько констант, разделенных запятой, определяющие содержимое выделенных ячеек памяти. Знак вопроса говорит о том, что выделенная область ничем не заполняется. Имя, если оно есть, определяет адрес первого байта выделяемой области. Директивой выделяется указанное количество байтов ОП и указанные операнды пересылаются в эти поля памяти. Если операнд – это ‘?’, то в соответствующее поле ничего не заносится.

Пример:

R1 DB 0, 0, 0; выделено 3 поля, заполненных 0.

R1

R1+1

R2 DB ?, ?, ? R2 (дорис) R1+2

R2+1

R2+2

1) Если операндом является символическое имя IM1, которое соответствует смещению в сегменте 03АС1h, то после выполнения

M DD IM1

будет выделено 4 байта памяти. Адрес – М. Значение - 03АС1h.

2) Если необходимо выделить 100 байтов памяти и заполнить 1, то это можно сделать с помощью специального повторителя DUP.

D DB 100 DUP (1)

3) Определение одномерного массива слов, адрес первого

элемента массива – имя MAS,значение его 1.

MAS DW 1, 7, 35, 75, 84

4) Определение двумерного массива:

Arr DB 7, 94, 11, -5

DB 5, 0, 1, 2

DB -5, 0, 15, 24

5)Const EQU 100

D DB Const DUP (?); выделить 100 байтов памяти. В директиве определения байта (слова) максимально допустимая константа – 255 (65535).

С помощью директивы определения байта можно определить символьную константу длинной 255 символов, а с помощью определения слова можно определить символьную константу, которая может содержать не более двух символов.

23) Команды безусловной передачи управления, обращения к подпрограмме и возврата из программы.

Команды управления позволяют изменить ход вычислительного процесса.

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

Команды безусловной передачи управления имеют вид

JMP <имя>,

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

JMP M1; по умолчанию М1 имеет тип NEAR

Если метка содержится в другом сегменте, то в том сегменте, в который передается управление, должно быть Public M1, а из которого –

EXTRN M1: FAR.

Кроме того, передачу можно осуществлять с использованием прямой адресации (JMP M1) или с использованием косвенной адресации (JMP [BX]).

Команда, осуществляющая близкую передачу, занимает 3 байта, а дальняя – 5 байтов. А если передача осуществляется не далее как на -128 или 127 байтов, то можно использовать команду безусловной передачи данных, занимающую 1 байт.

ADD AX, BX

JMP Short M1

M2: ------/-------

M1: MOV AX, CX

----------/-----------

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

Процедура обязательно имеет тип дальности и по умолчанию тип NEAR, а FAR необходимо указывать.

PP Proc FAR

------/-------

PP endp

Процедура типа NEAR может быть вызвана только из того кодового сегмента, в котором содержится ее описание. Процедура типа FAR может быть вызвана из любого сегмента. Поэтому тип вызова функции (дальность) определяется следующим образом: главная программа всегда имеет тип FAR, т.к. обращаются к ней из ОС или отладчика, если процедур несколько и они содержатся в одном кодовом сегменте, то все остальные, кроме главной, имеют тип NEAR. Если процедура описана в кодовом сегменте с другим именем, то у нее должен быть тип FAR.

1) Cseg segment….

assume …..

p1 proc far

-------------------------

call p2

m: mov AX, BX

--------------------------

ret

p1 endp

p2 proc near

m1: mov CX, DX

---------------------------

ret

p2 endp

Cseg ends

Наши рекомендации