Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Базовые операции над целочисленными даннымиСодержание книги
Поиск на нашем сайте
Команда XCHG позволяет совершить обмен значений двух операндов. В качестве операндов должны выступать регистры или ячейки памяти. Операнды должны быть одинаковой длины. Например, команда xchg eax,Z произведён обмен значений между регистром eax и двойным словом Z. Команды INC и DEC (Increment и Decrement) прибавляют и вычитают единицу из указанного операнда. Например, команда inc X увеличивает на 1 значение переменной X, а команда dec ebx уменьшает на единицу содержимое регистра ebx. Команда NEG изменяет знак числа, хранимого в регистре или ячейке памяти, на противоположный, конвертируя число в двоичный дополнительный код. Напомним, что для получения двоичного дополнительного кода надо инвертировать все биты и прибавить к числу единицу. Для получения полной информации по этим и другим командам процессора Intel достаточно заглянуть в Приложение Б или воспользоваться англоязычной справкой masm32 ® Help ® Opcodes Help. Для умножения и деления 8-, 16- и 32-разрядных целых чисел в процессоре Intel предусмотрены четыре команды: MUL, DIV, IMUL, IDIV. Эти команды кроме объявленных действий изменяют флаги, однако суть этих изменений мы рассмотрим в следующем параграфе. Команда MUL служит для умножения 8-, 16- и 32-разрядного беззнакового целого числа, находящегося в одном из регистров общего назначения или в памяти, с операндом, расположенным в аккумуляторе (AL, AX, EAX). Расположение множимого, множителя и произведения зависит от размера множимого: Таблица 1.2.1. Расположение множимого, множителя
Чтобы в результате не возникло переполнения, размер памяти, отводимый под произведение, должен в два раза превышать размер множимого и множителя. Синтаксис команды MUL предусматривает указание только одного операнда, являющегося множителем. Множимое указывать в команде не надо, т.к. оно всегда расположено в аккумуляторе – это особенность архитектуры процессоров Intel. Пример 1.2.7. В приведённой ниже программе выполняется умножение 8-разрядных чисел без знака (5´10h = 50h), в результате чего получается 16-разрядное число 0050h, которое размещается в регистре AX: .code start: mov al, 5h; al=5h mov bl, 10h; bl=10h mul bl; ax=0050h PrintHex ax ret end start Пример 1.2.8. В приведённой ниже программе выполняется умножение 16-разрядных чисел без знака (100h´2000h = 200000h), в результате чего получается 32-разрядное число 00200000h, которое размещается в регистровой паре DX:AX таким образом, что младшие 16 разрядов произведения записываются в регистр AX, а старшие 16 разрядов – в регистр DX: .data X word 2000h .code start: mov ax,100h; ax=100h mul X; dx:ax=00200000h PrintHex ax; ax=0000h PrintHex dx; dx=0020 ret end start Пример 1.2.9. В приведённой ниже программе выполняется умножение 32-разрядных чисел без знака (12345h´100000h = 1234500000h), в результате чего получается 64-разрядное число 0000001234500000h, которое размещается в регистровой паре EDX:EAX .code start: mov eax,12345h; eax=12345h mov ecx,100000h; ecx=100000h mul ecx; edx:eax=0000001234500000h PrintHex eax; eax=34500000h PrintHex edx; edx 00000012h ret end start Команда IMUL служит для умножения целых чисел со знаком. Результат умножения является знаковым. Формат команды IMUL отличается от команды MUL. Один операнд: IMUL reg8/mem8; ax = al * reg8/mem8 IMUL reg16/mem16; dx:ax = ax * reg16/mem16 IMUL reg32/mem32; edx:eax = eax * reg32/mem32 Два операнда: IMUL reg16,reg16/mem16/imm; reg32=reg16*reg16/mem16/imm IMUL reg32,reg32/mem32/imm; reg32=reg32*reg32/mem32/imm Три операнда: IMUL reg16,reg16/mem16,imm; reg16=reg16/mem16*imm IMUL reg32,reg32/mem32,imm; reg32=reg32/mem32*imm Пример 1.2.10. В приведённой ниже программе выполняется умножение 8-разрядных чисел со знаком (30h ´ 4 = С0h), в результате чего получается 16-разрядное число 00С0h, которое размещается в регистре AX: .code start: mov al, 30h; al=30h mov bl, 4h; bl=4h imul bl; ax=00C0h PrintHex ax ret end start Пример 1.2.11. В приведённой ниже программе выполняется умножение 8-разрядных чисел со знаком (-4 ´ 4 = FFF0h), в результате чего получается 16-разрядное число FFF0h (-16), которое размещается в регистре AX: .code start: mov al, -4h; al=-4h (в дополнительном коде FC) mov bl, 4h; bl=4h imul bl; ax=FFF0h PrintHex ax ret end start Команда DIV служит для деления на 8-, 16- и 32-разрядное беззнаковое целое число, находящееся в одном из регистров общего назначения или в памяти, операнда, расположенного в регистрах AX, DX:AX или EDX:EAX. Расположение делимого, делителя, частного и остатка зависит от размера делителя: Таблица 1.2.2. Расположение исходных данных и результатов деления
Пример 1.2.12. В приведённой ниже программе выполняется деление на 8-разрядное число без знака (25h / 2 = 12h), в результате чего получается 8-разрядное частное 12h и остаток 1, которые размещаются в регистрах AL и AH соответственно: .code start: mov ax, 25h; ax=25h mov bl, 2h; bl=2h div bl; ax=0112h (остаток=01, частное = 12h) PrintHex ax ret end start Команда IDIV служит для деления целых чисел со знаком. Она имеет те же форматы операнда, что и команда DIV. При делении на 8‑разрядное число, перед выполнением команды IDIV при необходимости нужно расширить знак делимого в регистр AH с помощью команды CBW (Convert byte to word). Пример 1.2.13. В приведённой ниже программе выполняется деление числа -48 на 5: .data X sbyte -48d .code start: mov al,X; al=-48d cbw; расширяем знак регистра AL в AH mov bl,5; bl=5d idiv bl PrintDec al; al=-9d PrintDec ah; ah=-3d ret end start При делении на 16-разрядное число, необходимо вначале расширить знак делимого, находящегося в регистр AX, в регистр DX с помощью команды CWD (Convert word to Doubleword). Пример 1.2.14. В приведённой ниже программе выполняется деление числа -48 на 5: .data X sword -5004d .code start: mov ax,X; ax=-5004d cwd; расширяем знак регистра AX в DX mov bx,500d; bx=500d idiv bx PrintDec ax; ax=-10d PrintDec dx; dx =-4d ret end start При делении на 32-разрядное число, необходимо вначале расширить знак делимого, находящегося в регистр AX, в регистр DX с помощью команды CDQ (Convert Doubleword to Quardword). Пример 1.2.15. В приведённой ниже программе выполняется деление числа -48 на 5: .data X sdword -50004d .code start: mov eax,X; eax=-5004d cdq; расширяем знак регистра EAX в EDX mov ebx,5000d; ebx=500d idiv ebx PrintDec eax; eax=-10d PrintDec edx; edx =-4d ret end start Упражнения для закрепления материала Упражнение 1.2.4. Напишите последовательность команд, в которой умножается число -5 на 3 и результат записывается в 16-разрядную переменную со знаком. Упражнение 1.2.5. Напишите последовательность команд, в которой число -276 делится на 10 и результат записывается в 16-разрядную переменную со знаком. Упражнение 1.2.6. Напишите программу для вычисления 5!=1×2×3×4×5. Результат сохраните в переменную без знака. Упражнение 1.2.7. Объявите в программе массив десятичных чисел 1, -2, 3, -4, 5 и найдите сумму его элементов. Упражнение 1.2.8. Объявите в программе массив чисел 1h, 123h, 12345h, 1234567h и найдите сумму его элементов. Упражнение 1.2.9. Объявите в программе строку с Вашей фамилией и вычислите произведение ASCII-кодов первого и последнего символов фамилии. Упражнение 1.2.10. Объявите в программе переменную 12345678h и вычислите произведение старшей и младшей половины числа. Результат сохраните в другой переменной. Вопросы для самопроверки 1. В каком случае операторы SIZEOF и LENGTHOF вернут одинаковые значения? 2. Каково отличие между оператором offset и командой lea? 3. В чём отличие ближних и дальних указателей? 4. Для чего используются команды расширения целых чисел? 5. В чём отличие команды NEG и команды NOT? 6. В чём отличие формата команды IMUL от формата команды MUL? 6. Как работают трёхаргументные команды умножения целых чисел со знаком? 7. Почему размер произведения больше размера любого из множителей в два раза? 8. Для чего используются команды расширения знака делимого? Управление вычислительным процессом Использование стека Команда push помещает в стек двухбайтовое число из регистра, памяти или непосредственно указанное в команде число, предварительно уменьшив содержимое указателя стека ESP на 4. Команда pop выталкивает из стека двухбайтовое число и размещает его в двухбайтовом регистре или памяти, после чего увеличивает регистр ESP на 4. Таким образом, стек растёт в сторону меньших адресов, а уменьшается в сторону б о льших адресов. Важно соблюдать в программе баланс команд push и pop: сколько раз в программе была выполнена команда push, столько же раз должна быть выполнена команда pop. Если это правило не соблюдать, то при завершении программы будет потерян адрес возврата. Пример 1.3.1. Ниже приведена программа, демонстрирующая различные способы работы со стеком. .486 .model flat, stdcall option casemap: none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc include \masm32\include\debug.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib includelib \masm32\lib\debug.lib .data Z dword 12345678h .code start: mov ebx, 0AAAAAAAAh PrintHex esp; esp=0012FFA4h push ebx PrintHex esp; esp=0012FFA0h push Z PrintHex esp; esp=0012FF9Ch push 12345678h PrintHex esp; esp=0012FF98h pop Z PrintHex esp; esp=0012FF9Ch pop ebx PrintHex esp; esp=0012FFA0h pop ecx PrintHex esp; esp=0012FFA4h ret end start Упражнение 1.3.1. Определите содержимое переменной Z и используемых регистров после завершения работы программы из примера 1.3.1. Дополнительные стековые команды: · pushfd – помещает в стек содержимое регистра флагов EFLAGS. · popfd – выталкивает из стека двухбайтовое число и помещает его в регистр EFLAGS. · pushad – помещает в стек значения всех 32-разрядных регистров общего назначения в следующем порядке: EAX, ECX,EDX, EBX, ESP (то значение, которое было до выполнения команды), EBP, ESI, EDI. · popad – выполняет обратную операцию, т.е. восстанавливает из стека значения указанных регистров в обратном порядке. Упражнение 1.3.2. Разработайте программу вывода на печать содержимого регистра флагов в шестнадцатеричном представлении.
|
||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2016-06-29; просмотров: 491; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.144.39.11 (0.009 с.) |