ЛЕКЦИЯ № 7 КОМАНДЫ РАБОТЫ СО СТЕКОМ Стек – это область памяти, специально выделяемая для временного хранения данных программы. Регистры, предназначенные для работы со стеком: ss; sp/esp; bp/ebp Основные особенности работы со стеком: • Запись и чтение данных в стеке осуществляется по принципу «Последним пришел – первым ушел» . • По мере записи данных в стек последний растет в сторону младших адресов. • При использовании регистров sp/esp; bp/ebp для адресации памяти ассемблер автоматически считает, что содержащиеся в нем значения представляют собой смещения относительно сегментного регистра ss.
Концептуальная схема организации стека Регистр esp/sp всегда указывает на текущую верщину стека. Для доступа к данным, расположенным не на вершине стека используется регистр ebp/bp.
Адресная пара ss: ffff – это максимальное для реального режима значение адреса начала стека. Значение смещения начала стека равно размеру стека, указанному при описании программистом сегмента стека. Команда записи в стек push источник Алгоритм работы команды push: • (sp)=(sp)-2; • значение из источника записывается по адресу ss: sp.
Команда чтения из стека pop назначение Алгоритм работы команды pop: • запись значения, расположенного по по адресу ss: sp по месту, указываемому операндом назначение; • (sp)=(sp)+2.
Команды групповой записи в стек: pusha, pushaw. Команды, обратные командам pusha, pushaw: popa, popaw.
Команды сохранения в стеке и восстановления регистра флагов: pushf – popf; pushfw – popfw. Основные виды операций, при которых неизбежно использование стека: • вызов подпрограмм; • временное сохранение значений регистров; • определение локальных переменных.
АРИФМЕТИЧЕСКИЕ КОМАНДЫ Классификация арифметических команд
Форматы арифметических данных Целые двоичные числа Размерность поля Целое без знака Целое со знаком Байт 0 … 255 -128 … +127 Слово 0 … 65 535 -32 768 … +32 767 Двойное слово 0 … 4 294 967 295 -2 147 483 648 … + 2 147 483 647 Десятичные числа • упакованный BCD формат; • неупакованный BCD формат.
Представление BCD чисел
Для описания двоично-десятичных чисел можно использовать только директивы описания и инициализации данных db и вdt. …. data ; сегмент данных per 1 db 2, 3, 4, 6, 8, 2 ; неупакованное BCD- число 286432 per 2 dt 9875645 ; упакованное BCD- число 9875645 … Арифметические операции над целыми двоичными числами Сложение двоичных чисел без знака Набор команд: • inc операнд • add операнд 1, операнд 2 (операнд 1=операнд 1+операнд 2) • adc операнд 1, операнд 2 (операнд 1=операнд 1+операнд 2+значение cf)
Сложение двоичных чисел со знаком Основной особенностью является анализ флагов cf, of ПРИМЕРЫ 30566 = 0111 0110 + 00687 = 00000010 10101111 = 31253 = 01111010 00010101 результат правильный. 30566 = 0111 0110 + 30566 = 0111 0110 = 61132 = 1110 1100 результат неправильный, произошел перенос из 14 разряда, из 15 разряда переноса нет – переполнение.
-30566 = 1000 10011010 + -04875 = 11101100 11110101 = -35441 = 01110101 10001111 результат неправильный (вместо отрицательного числа получилось положительное), произошел перенос из 15 разряда, из 14 разряда переноса нет. -4875 = 11101100 11110101 + -4875 = 11101100 11110101 = -9750 = 11011001 11101010 из 14 и 15 разрядов. результат правильный, есть переносы Ситуация переполнения (установка флага of в 1) происходит при переносе: • из 14 разряда для положительных чисел со знаком; • из 15 разряда для отрицательных чисел.
Вычитание двоичных чисел без знака Если уменьшаемое больше вычитаемого, разность представима как число без знака и проблем нет. В противном случае микропроцессор выполняет заем из несуществующего разряда, следующего за старшим с установкой флага cf. 5 = (1) 00000101 10 = 00001010 = -5 = 11111011 Тот же результат можно получить путем сложения 5 +(-10) Команды вычитания: • dec операнд • sub операнд 1, операнд 2 (операнд 1=операнд 1 -операнд 2) • sbb операнд 1, операнд 2 (операнд 1=операнд 1 -операнд 2 -значение cf)
Вычитание двоичных чисел со знаком Примеры: 45 = 0010 1101 -127= 10000001 = -44 = 10101100 Результата неверный. of=1 (изменился старший бит) -45 = 1101 0011 + -45 = 1101 0011 = -90 = 10100110 Результат правильный Умножение двоичных чисел без знака команда mul сомножитель1
Расположение операндов и результата при умножении ПРИМЕР: ; prog_mul masm model small stack 256. data rez label word rez 1 db 45 rez 2 db 0
. code main: mov ax, @ , data mov ds , ax xor ax , ax mov al , 25 mul rez 1 jnc m 1 mov rez 2 , ah m 1: mov rez 1 , al mov ax , 4 c 00 h int 21 h end main Умножение двоичных чисел со знаком Команда imul операнд 1
Деление двоичных чисел без знака Команда div делитель Расположение операндов и результата при делении Особенность – возможность возникновения прерывания 0 (относящегося к исключениям) в случае, если либо делитель равен нулю, либо частное не входит в отведенную для него разрядную сетку.
Для деления двоичных чисел со знаком используется команда idiv делитель Команды преобразования типов 1. Команды без операндов: cbw (al ah: al), cwd (ax dx: ax), cwde (ax eax), cdq (eax edx: eax) 1. 2. Команды 2. movsx операнд_1, операнд_2 3. movzx операнд_1, операнд_2 4. Команды 5. xadd назначение , источник 6. neg операнд
ПРИМЕР: masm model small stack 256. data a db 5 b db 10 c db 2 y dw 0. code main: … xor ax , ax mov al , a cbw movsx bx , b add ax , bx idiv c ; в al - частное, в ah – остаток mov ax , 4 c 00 h int 21 h end main