Лабораторная работа №32 / lab3
.docЗадание:
Разработать на языке Ассемблер IBM PC программу, которая
по заданным целым значениям a,b,i,k вычисляет:
а) значения i1 = f1(a,b,i) и i2 = f2(a,b,i);
b) значения res= fres(i1,i2,k),
Значения a,b,i,k являются исходными данными, которые должны
задаваться в процессе исполнения программы в режиме отладки.
При этом следует рассмотреть всевозможные комбинации
параметров a,b и k, позволяющие проверить различные маршруты
выполнения программы.
Функции имеют вид:
/ 3i-4 ,(a>b)
F1= <
\ 3(i+1) ,(a<=b)
/ 4i-10 ,(a>b)
F2= <
\ 4i+5 ,(a<=b)
/ max(f1,10-f2) , (k<0)
Frez=<
\[f1-f2] , (k>=0)
Замечание:
1)Для ввода данных в программе используется самый простой способ: данные вводятся непосредственно во время отладки. То есть в нужную ячейку памяти вводится число через командную строку.
Возможны также следующие варианты:
-ввод данных с использованием средств Assembler, например через 21ое прерывание DOS
-ввод данных с использованием языков высокого уровня.
В процедуру, написанную на Ассемблере данные передать как параметры, либо как глобальные переменные.
2)Для реализации алгоритмов не был использован математический сопроцессор.
Все расчеты проводились с использованием стандартных функций процессора i086
3)Вместо умножения используется побитовый сдвиг.
4)Ветвления алгоритма реализуются с помощью условных и безусловных переходов.
Текст программы:
TITLE LAB03 (EXE) Условное вычисление функций
;--------------------------------------------------
stack SEGMENT PARA STACK 'stack'
dw 32 DUP(0)
STACK ENDS
;--------------------------------------------------
DATA SEGMENT PARA 'data'
i dw ?
a dw ?
b dw ?
k dw ?
f1 dw ?
f2 dw ?
f3 dw ?
DATA ENDS
;--------------------------------------------------
CODE SEGMENT PARA 'code'
main proc far
assume ss:stack,ds:data,cs:code
mov ax,data ;Инициализация сегмента
mov ds,ax ;data
;Вычисление f1 и f2-----------
mov ax,a ;заносим значение а в ах
mov dx,b ;заносим значение b в dx
mov cx,i ;заносим i в cx
cmp ax,dx ;Сравнение значений a и b
jg A1 ;если a>b то на A1
inc cx ;если a<=b то i:=i+1
shr cx,1 ;умножение i+1 на 2
mov ax,cx
add ax,cx ;2(i+1)+(i+1)=3(i+1)
mov f1,ax ;сохранение результата в f1
mov cx,i ;восстанавливаем значени i в cx
shr cx,1 ;i:=2*i
shr cx,1 ;i:=4*i
mov ax,cx
sub ax,10 ;ax=4i-10
mov f2,ax ;сохраняем рез-т в f2
jmp A2 ;Пропускаем следующие шаги
A1: ;если a>b
mov cx,i ;восстановление значения i в cx
shr cx,1 ;i:=2*i
add cx,i ;i:=2i+i=3i
sub cx,4 ;cx=3i-4
mov f1,cx ;сохраняем результат в f1
mov cx,i ;восстанавливаем значение i в cx
shr cx,1 ;i:=2*i
shr cx,1 ;i:=2i*2
mov ax,cx
add ax,5 ;ax=4i+5
mov f2,ax ;сохраняем результат в f2
A2: ;-----------------------------
;Вычисление f3-----------
mov ax,k
mov bx,0
cmp ax,bx ;сравниваем k и 0
jge B1 ;если k>=0 то перейти на B1
;----k<0
mov ax,f1
mov dx,10
sub dx,f2
cmp ax,dx ;Сравниваем 10-f2 и f1
jge C1
mov f3,dx ;f1<10-f2 то f3:=10-f2
jmp C2
C1: mov f3,ax ;f>=10-f2 то f3:=f1
C2:
jmp B2 ;Пропускаем след вычисления
B1: ;k>=0
mov ax,f1
mov dx,f2
cmp ax,dx ;Сравниваем f1 и f2
jge D1
sub dx,ax ;f2>f1 => f3:=f2-f1
mov f3,dx
jmp D2
D1: ;f1>=f2 => f3:=f1-f2
sub ax,dx
mov f3,ax
D2: ;-----------------------------
B2:
mov ax,4c00h ;Завершить работу
int 21h
main endp ;Конец процедуры
CODE ENDS ;Конец сегмента
END MAIN ;Конец программы
Протокол работы на компьютере:
1)Компиляция программы.
2)Запуск программы из отладчика.
3)Указание нужным ячейкам памяти нужных значений.
Файл диагностических сообщений:
Microsoft (R) Macro Assembler Version 5.10 4/6/5
LAB03 (EXE) Условное вычисление функций Page 1-1
TITLE LAB03 (EXE) Условное вычисление фун
кций
;----------------------------------------------
----
0000 stack SEGMENT PARA STACK 'stack'
0000 0020[ dw 32 DUP(0)
0000
]
0040 STACK ENDS
;----------------------------------------------
----
0000 DATA SEGMENT PARA 'data'
0000 0000 i dw ?
0002 0000 a dw ?
0004 0000 b dw ?
0006 0000 k dw ?
0008 0000 f1 dw ?
000A 0000 f2 dw ?
000C 0000 f3 dw ?
000E DATA ENDS
;----------------------------------------------
----
0000 CODE SEGMENT PARA 'code'
0000 main proc far
assume ss:stack,ds:data,cs:code
0000 B8 ---- R mov ax,data ;Инициализация сегмента
0003 8E D8 mov ds,ax ;data
;Вычисление f1 и f2-----------
0005 A1 0002 R mov ax,a ;заносим значение а в а
х
0008 8B 16 0004 R mov dx,b ;заносим значение b в d
x
000C 8B 0E 0000 R mov cx,i ;заносим i в cx
0010 3B C2 cmp ax,dx ;Сравнение значений a и
b
0012 7F 1D jg A1 ;если a>b то на A1
0014 41 inc cx ;если a<=b то i:=i+1
0015 D1 E9 shr cx,1 ;умножение i+1 на 2
0017 8B C1 mov ax,cx
0019 03 C1 add ax,cx ;2(i+1)+(i+1)=3(i+1)
001B A3 0008 R mov f1,ax ;сохранение результата
в f1
001E 8B 0E 0000 R mov cx,i ;восстанавливаем значен
и i в cx
Microsoft (R) Macro Assembler Version 5.10 4/6/5
LAB03 (EXE) Условное вычисление функций Page 1-2
0022 D1 E9 shr cx,1 ;i:=2*i
0024 D1 E9 shr cx,1 ;i:=4*i
0026 8B C1 mov ax,cx
0028 2D 000A sub ax,10 ;ax=4i-10
002B A3 000A R mov f2,ax ;сохраняем рез-т в f2
002E EB 22 90 jmp A2 ;Пропускаем следующие ш
аги
0031 A1: ;если a>b
0031 8B 0E 0000 R mov cx,i ;восстановление значени
я i в cx
0035 D1 E9 shr cx,1 ;i:=2*i
0037 03 0E 0000 R add cx,i ;i:=2i+i=3i
003B 83 E9 04 sub cx,4 ;cx=3i-4
003E 89 0E 0008 R mov f1,cx ;сохраняем результат в
f1
0042 8B 0E 0000 R mov cx,i ;восстанавливаем значен
ие i в cx
0046 D1 E9 shr cx,1 ;i:=2*i
0048 D1 E9 shr cx,1 ;i:=2i*2
004A 8B C1 mov ax,cx
004C 05 0005 add ax,5 ;ax=4i+5
004F A3 000A R mov f2,ax ;сохраняем результат в
f2
0052 A2: ;----------------------
-------
;Вычисление f3-----------
0052 A1 0006 R mov ax,k
0055 BB 0000 mov bx,0
0058 3B C3 cmp ax,bx ;сравниваем k и 0
005A 7D 1B jge B1 ;если k>=0 то перейти н
а B1
;----k<0
005C A1 0008 R mov ax,f1
005F BA 000A mov dx,10
0062 2B 16 000A R sub dx,f2
0066 3B C2 cmp ax,dx ;Сравниваем 10-f2 и f1
0068 7D 07 jge C1
006A 89 16 000C R mov f3,dx ;f1<10-f2 то f3:=10-f2
006E EB 04 90 jmp C2
0071 A3 000C R C1: mov f3,ax ;f>=10-f2 то f3:=f1
0074 C2:
0074 EB 1A 90 jmp B2 ;Пропускаем след вычисл
ения
0077 B1: ;k>=0
0077 A1 0008 R mov ax,f1
007A 8B 16 000A R mov dx,f2
007E 3B C2 cmp ax,dx ;Сравниваем f1 и f2
0080 7D 09 jge D1
0082 2B D0 sub dx,ax ;f2>f1 => f3:=f2-f1
Microsoft (R) Macro Assembler Version 5.10 4/6/5
LAB03 (EXE) Условное вычисление функций Page 1-3
0084 89 16 000C R mov f3,dx
0088 EB 06 90 jmp D2
008B D1: ;f1>=f2 => f3:=f1-f2
008B 2B C2 sub ax,dx
008D A3 000C R mov f3,ax
0090 D2: ;----------------------
-------
0090 B2:
0090 B8 4C00 mov ax,4c00h ;Завершить работу
0093 CD 21 int 21h
0095 main endp ;Конец процедуры
0095 CODE ENDS ;Конец сегмента
END MAIN ;Конец программы
Microsoft (R) Macro Assembler Version 5.10 4/6/5
LAB03 (EXE) Условное вычисление функций Symbols-1
Segments and Groups:
N a m e Length Align Combine Class
CODE . . . . . . . . . . . . . . 0095 PARA NONE 'CODE'
DATA . . . . . . . . . . . . . . 000E PARA NONE 'DATA'
STACK . . . . . . . . . . . . . 0040 PARA STACK 'STACK'
Symbols:
N a m e Type Value Attr
A . . . . . . . . . . . . . . . L WORD 0002 DATA
A1 . . . . . . . . . . . . . . . L NEAR 0031 CODE
A2 . . . . . . . . . . . . . . . L NEAR 0052 CODE
B . . . . . . . . . . . . . . . L WORD 0004 DATA
B1 . . . . . . . . . . . . . . . L NEAR 0077 CODE
B2 . . . . . . . . . . . . . . . L NEAR 0090 CODE
C1 . . . . . . . . . . . . . . . L NEAR 0071 CODE
C2 . . . . . . . . . . . . . . . L NEAR 0074 CODE
D1 . . . . . . . . . . . . . . . L NEAR 008B CODE
D2 . . . . . . . . . . . . . . . L NEAR 0090 CODE
F1 . . . . . . . . . . . . . . . L WORD 0008 DATA
F2 . . . . . . . . . . . . . . . L WORD 000A DATA
F3 . . . . . . . . . . . . . . . L WORD 000C DATA
I . . . . . . . . . . . . . . . L WORD 0000 DATA
K . . . . . . . . . . . . . . . L WORD 0006 DATA
MAIN . . . . . . . . . . . . . . F PROC 0000 CODE Length = 0095
@CPU . . . . . . . . . . . . . . TEXT 0101h
@FILENAME . . . . . . . . . . . TEXT lab3
@VERSION . . . . . . . . . . . . TEXT 510
100 Source Lines
100 Total Lines
24 Symbols
47188 + 442841 Bytes symbol space free
0 Warning Errors
0 Severe Errors
Вывод:
Реализация алгоритмов на Ассемблере является наиболее результативной, но ввод данных целесообразнее осуществлять с помощью языков программирования высокого уровня.
В программе вместо операции умножения используется операция побитового сдвига вправо shr, которая использует два операнда (поэтому в программе встречается комбинация shr cx,1), чтобы этого избежать можно подключить директиву .286.