Лабораторная работа по ассемблеру процедуры

Цель работы:   получение навыков разработки структурной организации ассемблерных программ и ее реализации на основе аппарата процедур, изучение способов организации связи по данным между процедурами.
Лабораторное задание:   разработать программу вычисления функции 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();
}

Результат работы программы:


Комментариев нет:

Отправить комментарий