Лабораторная работа №33 / 3
.docСанкт-Петербургский Государственный Электротехнический Университет
Кафедра вычислительной техники
Лабораторная работа №3
3-ий семестр, программирование на языке ассемблера
«Представление чисел и арифметические операции»
Студент гр. 181x:
Санкт-Петербург
2002
Задание.
Для чисел, вводимых с клавиатуры, выполнить требуемое действие и результат вывести на экран. Форма представления и вид обработки определяется заданием.
Вариант |
Действие |
Форма представления |
Размер |
2 |
вычитание |
дв.-десят. |
4 байта |
Ход выполнения работы.
Написание программы.
Текст программы:
;
.386
cod segment use16
assume cs:cod,ds:dat
;--- cls, regured: ---
;clear db 27,'[2J$'
;ansi.sys loaded
cls proc
push ax
mov ah,09h
mov dx,offset clear
int 21h
pop ax
ret
cls endp
;--- / ---
;--- input decimal number from 0 to 99, save in AH as BCD. ---
inpdec proc
inpt1: mov di,0 ;clear DI for result
mov ah,08h ;input without echo
int 21h
cmp al,'9'
ja inpt1
cmp al,'0'
jb inpt1
mov ah,02h ;print pressed number
mov dl,al ;save in dx for printing
int 21h ;for function 02h
sub al,'0' ;convert to bin
xor ah,ah ;clear AH
mov bx,10h
mul bx ;AX*10h
mov di,ax ;save in di
xor bx,bx
inpt2: mov ah,08h ;input without echo
int 21h
cmp al,'9'
ja inpt2
cmp al,'0'
jb inpt2
mov ah,02h ;print pressed number
mov dl,al ;save in dx for printing
int 21h ;for function 02h
sub al,'0' ;convert to bin
xor ah,ah ;clear AH
add ax,di ;now result in AX
ret
inpdec endp
;--- / ---
;--- convert BCD to ASCII. BCD in AH, result in AL ---
bcd_asc proc
mov ah,al
and ah,0fh
add ah,'0'
and al,0f0h
shr al,4
add al,'0'
ret
bcd_asc endp
;--- / ---
begin: mov ax,dat
mov ds,ax
call cls
mov ah, 9
mov dx, offset first
int 21h
mov cx,4
mov si,0
input1: call inpdec
mov var1[si],al
inc si
loop input1
mov ah, 9
mov dx, offset retu
int 21h
mov ah, 9
mov dx, offset second
int 21h
mov cx,4
mov si,0
input2: call inpdec
mov var2[si],al
inc si
loop input2
mov ah, 9
mov dx, offset retu
int 21h
;вычитание
mov al,var1[3]
sub al,var2[3] ;вычитание
das ;коррекция
mov var3[3],al
mov cx,3
mov si,2
subing: mov al,var1[si]
sbb al,var2[si] ;вычитание с заёмом
das ;коррекция
mov var3[si],al
dec si
loop subing
jc minus
jmp done
minus: mov ah, 9
mov dx, offset minuss
int 21h
jmp endd
done: ;convert to ASCII
mov cx,4
mov si,0
conv: mov al,var3[si]
call bcd_asc
push ax
mov ax,si
add ax,ax
mov bx,ax
pop ax
mov var4[bx],ax
inc si
loop conv
mov ah, 9
mov dx, offset third
int 21h
mov ah, 09h
mov dx, offset var4
int 21h
endd: mov ax,4c00h
int 21h
cod ends
dat segment use16
var1 db 4 dup (0)
var2 db 4 dup (0)
var3 db 4 dup (?)
var4 dw 4 dup (' ')
var5 db '$'
minuss db 'the result is negative$'
clear db 27,'[2J$'
retu db 13,10,'$'
first db 'input first number from 0 to 99999999 with leading zeros: $'
second db 'input second number from 0 to 99999999 with leading zeros: $'
third db 'result is: $'
dat ends
stk segment
db 256 dup(?)
stk ends
end begin
Примечания:
В код программы были введены несколько процедур:
cls – очищает экран дисплея, используя esc-последовательность. Для её правильной работы в системе должен быть установлен ANSI-драйвер.
inpdec – процедура ввода двузначного числа от 00 до 99 с клавиатуры. Выводит число на экран дисплея и сохраняет его в старшей части регистра AX (AH) в упакованном BCD формате.
bcd_asc – процедура конвертирования двузначного упакованного BCD числа из старшей части регистра AX (AH) и помещения его ASCII кодов в регистр AX.
Программа предлагает пользователю ввести первое число от 0 до 99999999 с ведущими нулями, если разрядность числа меньше восьми. Затем сканирует введённые с клавиатуры цифры и сохраняет соответствующие значения в переменной var1 в упакованном BCD формате. После программа предлагает ввести второе число по такому же принципу и также его сохраняет, только в переменной var2.
Затем программа выполняет вычитание чисел, содержащихся в переменных var1 и var2 между собой, помещает результат в переменную var3.
Вычитание выполняется следующим образом:
Сначала из последнего двузначного упакованного BCD числа из переменной var1 вычитаются такое же число из переменной var2, результат корректируется командой das, т.к. вычитание производилось двух BCD чисел. Откорректированный результат помещается в конец переменной var3.
Похожие действия совершаются над следующими числами (от конца к началу), с той лишь разницей, что при их сложении учитывается состояние флага переноса.
Если после операции над старшими числами взводится флаг переноса, то на дисплей выводится сообщение о том, что результат отрицательный. В противном случае программа конвертирует число из переменной var3 в ASCII коды и сохраняет их в строку var4.
После, программа выводит строку var4 на экран.
Отладка.
На запрос программы о вводе первого числа, введём 91919191. На запрос ввода второго числа – 90909090. Программа выведет на дисплей:result is: 01010101.
Отсюда видно, что программа правильно выполнила вычисления, правильно учла все переносы, возникшие при вычислении разницы каждой пары двух упакованных BCD чисел, и корректно отобразила результат.
Теперь последовательно введём следующую пару чисел: 00000001 и 00000002. Программа выдаст: The result is negative.
Вывод – программа отвечает возложенным на неё требованиям и в дальнейшей отладке не нуждается.
Документация на исполняемый файл.
Программа выполняет вычитание двух положительных чисел от 0 до 99999999, вводимых с клавиатуры, и выводит результат на экран монитора. Следует заметить, что если разрядность числа меньше 8, то перед ним нужно ввести недостающее количество нулей. Также программа не предусматривает отображение отрицательного результата, а выводит сообщение – The result is negative.