Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей
|
Как видно из этого фрагмента кода, операция сложения двух целочисленных
32-битовых операндов разбита на два этапа. Вначале находится сумма
двух младших слов обоих операндов, затем двух старших. К полученной
сумме добавляется содержимое флага переноса, а результат помещается
в переменную i2. Необходимо также поместить один из операндов в регистр.
Первое сложение выполняется командой add, т. к. текущее значение
флага переноса для него несущественно. После этого выполняется второе
сложение командой adc с учетом флага переноса, установленного предыдущим
сложением.
Для вывода полученного результата в окно консоли необходимо вначале преобразовать
целое число в строку символов. Такое преобразование можно выполнить
при помощи функции WIN API wsprintf. Эта функция очень полезна,
т. к. позволяет преобразовать данные арифметического типа в строку.
Функция wsprintf будет использоваться нами чрезвычайно широко в примерах
последующих глав, поэтому остановимся на ней более подробно.
Функция wsprintf форматирует и запоминает строки символов и арифметических
операндов в буфере. Любые аргументы конвертируются и запоминаются
в буфере в соответствии с определенными для них спецификациями
форматирования. Функция формирует в буфере строку с завершающим нулем
и возвращает размер строки в качестве результата. Функция wsprintf
объявляется следующим образом:
int wsprintf(LPTSTRlpOut, LPCTSTRlpFmt,...);
где параметры функции:
• LPTSTRlpOut — буфер вывода;
• LPCTSTRlpFmt — строка, задающая формат выводимых переменных.
Третьим параметром функции wsprintf является переменная или список
переменных, которые необходимо преобразовать. Иными словами, функция
wsprintf может принимать переменное число параметров.
Вызов этой функции в нашей программе и передаваемые параметры показаны
в следующем фрагменте кода:
charBuf DB " ", О
len charBuf DD $-charBuf
lpFmt DB "%d",
i2 DD 3657
push DWORD PTR i2
push offset lpFmt
push offset charBuf
call wsprintf
add ESP, 12
Параметры передаются, как обычно, через стек, справа налево. Но есть
один нюанс, связанный с так называемым соглашением о передаче параметров.
Все функции WIN API используют соглашение stdcaii. Это значит,
что по завершению выполнения вызываемой процедуры она сама очищает
стек. Однако функция wsprintf использует другое соглашение —
cdeci, а это означает, что очищать стек должна вызывающая процедура,
т. е. наша программа. Поэтому в исходный текст за оператором вызова процедуры
необходимо вставить следующую строку:
add ESP, 12,
Функция wsprintf принимает 3 параметра (это 12 байт), а поскольку стек
растет к меньшим адресам, то смысл этого оператора становится понятным.
Мы подробно остановимся на вопросах, касающихся передачи параметров
из языков высокого уровня в ассемблерные подпрограммы, в главе 3.
Можно рекомендовать программистам, пишущим на ассемблере, использовать
wsprintf и другие функции преобразования данных, входящие в интерфейс WIN API, в своих приложениях. Можно, конечно, разработать свои
собственные процедуры преобразования, например из числового формата в
строку и наоборот, однако в этом нет особого смысла. Процедуры преобразования
различных типов переменных, написанные разработчиками
Microsoft, хорошо оптимизированы, и их применение значительно сэкономит
время.
Сохраним текст нашей программы в файле с расширением ASM и откомпилируем
ее.
Мы так подробно рассмотрели наши первые приложения для того, чтобы в
последующих примерах главы не акцентировать внимание на интерфейсе с
операционной системой Windows, а сосредоточиться на анализе интересующего
нас кода.
Рассмотрим теперь вычитание двух операндов с повышенной точностью.
Для этой операции будем использовать команды sub и sbb.
Команды вычитания sub и sbb являются как бы зеркальным отображением
команд сложения. Команды устанавливают флаги состояния в соответствии
с результатом операции. Флаг переноса будет означать заем единицы. Например,
команда
sub ЕАХ, ЕВХ
выполнит вычитание содержимого регистра ЕВХ ИЗ содержимого регистра
ЕАХ, поместив результат в ЕАХ. Флаги состояния будут установлены в соответствии
с результатом выполнения команды.
Вычитание с заемом выполняется с помощью команды sbb. Эта команда
используется в операциях вычитания с повышенной точностью. При выполнении
команды sbb необходимо учитывать значение флага заема. Для
получения правильного результата значение заема вычитается из результата,
полученного при нормальном вычитании.
Для демонстрации вычитания с повышенной точностью воспользуемся исходным
текстом предыдущего примера, сделав некоторые изменения. Заменим
группу команд сложения
mov AX, WORD PTR il
add WORD PTR i2, AX
mov AX, WORD PTR il+2
adc WORD PTR i2+2, AX
на группу команд вычитания
mov АХ, WORD PTR il
sub WORD PTR i2, AX
mov AX, WORD PTR il+2
sbb 'WORD PTR i2+2, AX
Для разнообразия поменяем значения операндов il и i2 следующим образом:
11 DD 18709
12 DD -9657
Заголовок окна приложения также изменим:
conTitle DB "Substraction of two integers", 0
<< Назад В начало Далее >> |
|