Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Реализация математических вычислений на языке ассемблера
Арифметические команды любого микропроцессора привлекают к себе наибольшее внимание. Хотя их немного, они выполняют основное количество преобразований данных в процессоре. В реальных же условиях арифметические команды занимают лишь малую часть всех исполняемых команд, но имеют определенную специфику выполнения. Языки высокого уровня отличаются многообразием и мощью своих математических функций. Однако в основе математических библиотек языков высокого уровня лежит относительно простой набор команд основного процессора и сопроцессора. В языке ассемблера нет таких комплексных функций и библиотек, однако можно разработать свои процедуры, ничем не уступающие функциям языков высокого уровня. Для этого нужно лишь использовать те возможности, которые предоставили нам разработчики фирмы Intel.

Начнем с рассмотрения арифметических команд основного процессора, а именно с команды сложения add. Команда add выполняет сложение указанных операндов, представленных в двоичном дополнительном коде. Результат помещается в первый операнд, а второй операнд не изменяется.
Команда корректирует регистр флагов в соответствии с результатом сложения.
Например, вызов add EAX, ЕВХ
суммирует содержимое регистров ЕАХ И ЕВХ, а результат помещает в регистр ЕАХ.
Биты регистра флагов устанавливаются в соответствии с тем, был ли результат нулевым, отрицательным, имел ли четность, перенос или переполнение. Операция сложения выполняется только для однотипных операндов.

В качестве операндов могут выступать регистры, ячейки памяти и непосредственные операнды, однако нельзя складывать два операнда в ячейках памяти. Команда сложения с переносом adc — это модификация команды add, за исключением того, что в сумму включается флаг переноса. Обе команды — add и adc— устанавливают в положение 1 флаг переноса, если произошел перенос из старшего разряда результата. Команда add складывает два операнда без учета флага переноса, а команда adc учитывает флаг переноса. При установленном в 0 флаге переноса результат выполнения adc совпадает с результатом выполнения команды add. Если же флаг переноса установлен в положение 1, то результат выполнения команды adc будет больше на единицу результата команды add. Таким образом, программа может использовать флаг переноса для выполнения операций повышенной точности. Приведем листинг программы сложения для двух чисел с повышенной точностью (листинг 2.13).

Листинг 2.13. Программа сложения двух чисел с повышенной точностью .386
.model flat, stdcall
option casemap :none ; различаем регистр символов
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
объявления и инициализация переменных
mes
conTitle
len mes
DB "Adding of two integers", 0
DB "The result of adding -8709 and 3657 = ", 0
EQU $-mes
charBuf DB ii 0
len charBuf DD $-charBuf
il DD -8709
i2 DD 3657
lpFmt DB II О
readBuf DB ?
lenReadBuf DD 1
hStdln DD О
hStdOut DD О
chrsRead DD О
chrsWritten DD О
STD_INP_HNDL DD -10
STD_OUTP_HNDL DD -11
. code
start:
call AllocConsole
test EAX, EAX
jz ex
; инициализация консольного приложения
push offset conTitle
call SetConsoieTitieA
test EAX, EAX
jz ex
call getout_hndl
call getinp_hndl
; сложение двух двойных слов
mov AX, WORD PTR il
add WORD PTR i2, AX ; сложение младших 16 разрядов
mov AX, WORD PTR il+2 ; сложение старших 16 разрядов
adc WORD PTR i2+2, AX
; преобразование результата сложения в строку
push DWORD PTR i2
push offset IpErtit
push offset charBuf
call wsprintf
add ESP, 12
; вывод сообщения в окно консоли
push ЕВХ
mov ЕВХ, offset mes
mov ECX, lenjxies
call write_con
pop EBX
; вывод результата сложения в окно консоли
push ЕВХ
mov ЕВХ, offset charBuf
mov ECX, len_charBuf
call write_con
pop EBX
; ожидание ввода и выход из программы
call read_con
ex:
push О
call ExitProcess
; Процедуры
getout_hndl proc
push STD_OUTP_HNDL
call GetStdHandle
mov hStdOut, EAX
ret
getout_hndl endp
getinp_hndl proc
push STD_INP_HNDL
call GetStdHandle
mov hStdln, EAX
ret
getinp_hndl endp
write_con proc
push 0
push chrsWritten
push ECX
push EBX
push hStdOut
call WriteConsoleA
ret
write_con endp
read_con proc
push 0
push chrsRead
push lenReadBuf
push offset readBuf
push hStdln
call ReadConsoleA
ret
read_con endp
end start

Операция суммирования в этой программе выполняется последовательностью следующих команд:
mov AX, WORD PTR il
add WORD PTR i2, AX
mov AX, WORD PTR il+2
adc WORD PTR i2+2, AX


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru