
- •5.Препроцессор. Директивы препроцессора.
- •7.Работа с файлами. Текстовый и двоичный режим.
- •8.Указатели. Адресная арифметика.
- •10.Перечислимый тип. Структуры. Объединения.
- •11.Поразрядные операции.
- •13.Спецификаторы класса памяти.
- •14.Пространства имён.
- •15.Компоновка. Правило одного определения.
- •16.Понятие класса.
- •17.Функции-члены класса. Указатель this.
- •18.Конструкторы. Деструкторы.
- •19.Преобразования объектов класса.
- •20.Доступ к членам класса.
- •21.Статические члены класса.
- •22.Друзья класса.
- •23.Совместное использование.
- •24.Перегрузка операций.
- •25.Шаблоны.
- •26.Обработка исключительных ситуаций.
- •27.Производные классы.
- •28.Виртуальные функции. Абстрактные классы.
- •29.Указатели на члены класса.
- •30.Множественное наследование.
- •31.Структура dll-библиотеки.
- •32.Статическое и динамическое подключение dll-библиотек.
- •34.Регистры процессора.
- •35.Использование стека. Команды работы со стеком в языке ассемблера.
- •36.Арифметические команды в языке ассемблера.
- •37.Команды сравнения и перехода в языке ассемблера.
- •38.Команды работы с битами в языке ассемблера.
- •39.Процедуры в языке ассемблера. Передача параметров в процедуру.
- •40.Процедуры в языке ассемблера. Возврат результата. Локальные данные.
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