Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЯМП ответы.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
710.66 Кб
Скачать

36.Арифметические команды в языке ассемблера.

Команды сложения и вычитания реализуют хорошо всем известные арифметические операции. Единственное, что нужно учитывать при использовании этих команд – особенности сложения и вычитания, связанные с представлением чисел в памяти компьютера.

ADD <операнд1>, <операнд2>

SUB <операнд1>, <операнд2>

Команда ADD складывает операнды и записывает их сумму на место первого операнда. Команда SUB вычитает из первого операнда второй и записывает полученную разность на место первого операнда. Операнды должны иметь одинаковый размер. Возможно сложение и вычитание как знаковых, так и беззнаковых чисел любого размера. Команды меняют флаги AF, CF, OF, PF, SF и ZF.

a dd 45d

b dd -32d

c dd ?

mov eax, a

add eax, b

mov c, eax ; c = a + b

Команды инкремента и декремента увеличивают и уменьшают на 1 свой операнд.

INC <операнд>

DEC <операнд>

Операндом может быть регистр или ячейка памяти любого размера. Команды меняют флаги AF, OF, PF, SF и ZF. Команды инкремента и декремента выгодны тем, что они занимают меньше места, чем соответствующие команды сложения и вычитания.

inc eax

К арифметическим операциям можно также отнести команду изменения знака:

NEG <операнд>

Операндом может быть регистр или ячейка памяти любого размера. Команда NEG рассматривает свой операнд как число со знаком и меняет знак операнда на противоположный. Команда меняет флаги AF, CF, OF, PF, SF и ZF.

mov ax, 1

neg ax ; AX = -1 = ffffffffh

mov bl, -128

neg bl ; BL = -128, OF = 1

Команды умножения и деления

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

MUL <операнд>

Операнд, указываемый в команде, – это один из сомножителей. Он может быть регистром или ячейкой памяти, но не может быть непосредственным операндом.Местонахождение второго сомножителя и результата фиксировано, и в команде явно не указывается.

Команда меняет флаги CF и OF. Если произведение имеет такой же размер, что и сомножители, то оба флага сбрасываются в 0. Если же размер произведения удваивается относительно размера сомножителей, то оба флага устанавливаются в 1.

x dw 256

mov ax, 105

mul x ; AX = AX * x, AX = 26880, CF = OF = 0

mov eax, 500000

mov ebx, 100000

mul ebx ; EDX:EAX = EAX * EBX, EDX:EAX = 50000000000, CF = OF = 1

Для знакового умножения используется команда IMUL:

IMUL <операнд>

IMUL <операнд>, <непосредственный операнд>

IMUL <операнд1>, <операнд2>, <непосредственный операнд>

IMUL <операнд1>, <операнд2>

Команда знакового умножения имеет несколько вариантов. Первый соответствует команде MUL – один из сомножителей указывается в команде, второй должен находиться в регистре EAX/AX/AL, а результат помещается в регистры EDX:EAX/DX:AX/AX.

Второй вариант команды IMUL позволяет указать регистр, который будет содержать один из сомножителей. В этот же регистр будет помещён результат. Второй сомножитель указывается непосредственно в команде.

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

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

Команда IMUL устанавливает флаги так же, как и команда MUL. Однако расширение результата в регистр EDX/DX происходит только при использовании первого варианта команды IMUL. В остальных случаях часть произведения, не помещающаяся в регистр-результат, теряется, даже если в качестве результата указан регистр EAX/AX. При умножении двух 1-байтовых чисел, произведение которых больше байта, но меньше слова, в регистре-результате получается корректное произведение.

mov eax, 5

mov ebx, -7

imul ebx ; EAX = ffffffdd, EDX = ffffffff, CF = 0

mov ebx, 3

imul ebx, 6 ; EBX = EBX * 6

mov ebx, 500000

imul eax, ebx, 100000 ; EAX = EBX * 100000, старшая часть результата теряется

x dd 40

mov eax, 55

imul eax, x ; EAX = EAX * x

Команды деления Деление, как и умножение, реализуется двумя командами, предназначенными для знаковых и беззнаковых чисел:

DIV <операнд> ; Беззнаковое деление

IDIV <операнд> ; Знаковое деление

В командах указывается только один операнд – делитель, который может быть регистром или ячейкой памяти, но не может быть непосредственным операндом. Местоположение делимого и результата для команд деления фиксировано.

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

mov ax, 127

mov bl, 5

div bl ; AL = 19h = 25, AH = 02h = 2

mov ax, 127

mov bl, -5

idiv bl ; AL = e7h = -25, AH = 02h = 2

mov ax, -127

mov bl, 5

idiv bl ; AL = e7h = -25, AH = feh = -2

mov ax, -127

mov bl, -5

idiv bl ; AL = 19h = 25, AH = feh = -2

; x = a * b + c

mov eax, a

imul b

add eax, c ; Операнды команды сложения вычисляются слева направо

mov x, eax

; x = a + b * c

mov eax, b

imul c

add eax, a ; Операнды команды сложения вычисляются справа налево

mov x, eax