Цель работы: получение
навыков разработки структурной организации ассемблерных программ и ее
реализации на основе аппарата процедур, изучение способов организации связи по
данным между процедурами.
Лабораторное
задание: разработать программу вычисления функции y=f(a,b,c,d,e). Значения аргументов a, b, c, d, e должны вводиться с
клавиатуры ПЭВМ. Значение функции y
следует вывести на экран дисплея.
Методические
указания: для ввода-вывода числовых
данных использовать следующий формат: ЗнЦЦЦ…Ц,
где Ц – цифра (0…9), Зн – знак (+,-). Предусмотреть в программе вывод текста, содержащего
вычисляемую функцию и формат аргументов, а также выдачу запроса на ввод каждого
аргумента. Вычисление функции и преобразование вводимых и выводимых данных
оформить в виде процедур: func –
вычисление заданной функции, ascbin –
преобразование числа из строки ASCII-кодов в двоичное число, binasc – преобразование числа,
представленного в виде двоичного кода, в строку ASCII кодов.
Передача аргументов между вызывающей и вызываемой
процедурами может осуществляться несколькими способами (или их комбинацией):
Способ передачи
|
Передаются данные
|
Передаются адреса
|
Через регистры
|
1
|
2
|
Через сегмент стека
|
3
|
4
|
Через сегмент данных
|
5
|
6
|
Через сегмент кода
|
7*
|
8*
|
№
|
f
|
Вызов/возврат
(func) |
Вызов/возврат
(ascbin) |
Вызов/возврат
(binasc) |
Формат
|
1)
|
30
|
1/2
|
3/4
|
5/6
|
b
|
* –
Если реализация данного варианта невозможна по объективным причинам
(ограничения накладываемые операционной системой и средой разработки), то
вариант заменяется на подобный, не указанный в задании.
Варианты
заданий: для каждого варианта указан номер, под
которым функция f приведена в
описании лабораторной работы №1, способ передачи данных между вызывающей и
вызываемой процедурами соответственно для func,
ascbin, binasc, а также формат данных (b
– байт, w – слово): y=a*b+c*d/e
Листинг
программы:
#include <stdio.h>
#include <conio.h>
#include <memory.h>
int result;
char digit;
int res[50];
char str[50];
int num,i;
_declspec(naked) // (3/4) Через сегмент стека
int func() //y=a/b+c*d-e
{
_asm
{
mov
al, [esp+20] //
cbw //
mov
bl, [esp+16] //
div bl
//
mov bl,
[esp+12] //
mov cl, [esp+8] //Вычисление
значения функции
imul bl,cl //
mov
cl, [esp+4] //
sub
bl, cl //
add
al,bl //
mov
[esp+24], al //
ret 20 //восстановление
стека
}
}
_declspec(naked) // (5/6)
Через сегмент данных
int ascbin()
{
_asm
{
mov
num, 0
mov
eax, num
LabelStart3:
xor
ecx, ecx
mov cl,
[edi]
cmp
esi, edi
je
LabelEnd3
sub ecx,
0x30
mov
digit, cl
xor
ebx,ebx
mov bx,
10
mul bx
xor ebx,
ebx
mov bl,
digit
add eax,
ebx
inc
edi
jmp
LabelStart3
LabelEnd3:
ret
}
}
_declspec(naked) // (1/2) Через регистры
char binasc()
{
_asm
{
LabelStart2:
cmp esi,
edi
je
LabelEnd2
mov
edx, [esi+4]
add
edx,0x30
mov digit, dl
mov
[eax], dl
add
esi,4
inc
eax
jmp
LabelStart2
LabelEnd2:
mov i,
eax
ret
}
}
void main()
{
int a,b,c,d,e;
printf("a:
");
scanf("%d",&a);
printf("b: ");
scanf("%d",&b);
printf("c: ");
scanf("%d",&c);
printf("d: ");
scanf("%d",&d);
printf("e: ");
scanf("%d",&e);
_asm
{
push 0//
push a//
push b//
Помещение исходных данных в стек
push c//
push d//
push e//
call func//вызов процедуры, вычисляющей значение функции y=a/b+c*d-e
pop result// выталкивание из стека результата
(выталкивается зарезервированное под результат место)
mov ecx, result
lea esi,
res
mov
edi, esi
lea eax,
str
call
binasc
mov
esi, i
lea
edi,str
call
ascbin
mov
num, eax
}
printf("y = %d", result);
getch();
}
Результат
работы программы:
Комментариев нет:
Отправить комментарий