Лістинг на Assembler
title Lab_4 .MODEL LARGE, C LOCALS @@ .DATA ; ГЛОБАЛЬНЫЕ переменные EXTRN C array:WORD, array_size:WORD, exist:BYTE .CODE EXTRN C RangeError: Far; ВНЕШНЯЯ процедура PUBLIC C calc arr EQU array[BX] calc proc far ARG L:WORD RETURNS res:WORD mov exist,0; ok! mov res,1; res = 1; XOR SI,SI; j=0; XOR BX,BX; регистр-индекс ; Подводим указатель BX к последнему элементу mov DI,array_size dec DI; array_size-1 mov cx, DI JCXZ @@Exit @@Begin1: inc BX inc BX LOOP @@Begin1 ;------------------- СОБСТВЕННО РЕШЕНИЕ ЗАДАЧИ: mov cx, array_size @@Begin: mov DI,arr; array[i]; cmp DI,0; if (array[i]>0) JLE @@Cont; НЕТ ;========== array[i]>0 =========================== inc SI; j++; ; сохранение регистров перед вызовом внешней процедуры push ax bx cx dx DI SI ; Визуализация вычислений на С++ call RangeError C, SI,DI ; восстановление регистров после отработки внешней процедуры pop SI DI dx cx bx ax ;res *= array[i]; mov ax,res MUL DI; <dx:ax>=<ax>*res JC @@ERROR; ловим переполнение mov res,ax; регистром DX ПРЕНЕБРЕГАЕМ!!! ;if (j==l) return res cmp SI,L JE @@Exit @@Cont: ; i--; dec BX dec BX LOOP @@Begin cmp SI,0; нашли положительные элементы? JG @@Exit; ДА mov exist,-1; НЕТ положительных элементов!!! @@Exit: ret @@ERROR: mov exist,1; признак ошибки по переполнению умножения JMP @@Exit calc endp end
Лістинг на С++ /* Lab4.cpp Borland C++ 5.02 Проект!!!!!! Application.exe === > DOS (standard)!!!!!! Лабораторная работа # 4. Найти произведение последних L положительных элементов массива int array[array_size], 2<=array_size<=100 */
#include <iomanip.h> // манипулятор setw(8) #include <conio.h> //getch(); clrscr(); #include <fstream.h> #include <stdlib.h> // void randomize(void); int random (int) #include "convert.h" // Перекодировка КИРИЛЛИЦЫ Win--->DOS
const char* DATA_ERROR = TXT("Ошибка при вводе данных!!!\n"); const char* REPEAT = TXT("Повторите еще раз, пожалуйста...\n"); const char* VALUE = TXT("Значение должно быть от "); const char* TO = TXT(" до "); const char* VALUE_RANGE = TXT("Значение превысило допустимый диапазон\n"); const char* TITLE = TXT("Найти произведение последних L положительных элементов массива\n"); const char* ENTER_LEN = TXT("Введите длину массива или "); const char* MEMORY = TXT("НЕВОЗМОЖНО распределить память для массива!!!\n"); const char* MULT = TXT("Введите количество умножаемых элементов\n"); const char* NO_ELEM = TXT("В данном массиве НЕТ положительных элементов!!!\n"); const char* RESULT_RANGE = TXT("Ошибка!!! Результат превышает допустимый диапазон: 65535\n"); const char* ASM_CALC = TXT("\nАссемблер: Произведение до конца вычислить НЕ удалось!!!\n"); //const char* RES_ASM = TXT("Произведение БЕЗ последнего элемента: ");
const int N=100;
//ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ int array[N]; unsigned int array_size; char exist=0;
extern "C" { unsigned int far calc(int L); void RangeError(int i, int buf); }
////////// Визуализация вычислений в С++ и на Ассемблере ///////////////// // void RangeError(int j, int buf) { if (j==1) cout << buf; else cout << "*" << buf; }
//////////////////////// КОРРЕКТНЫЙ ВВОД ///////////////////////// // template <class typData> int input (typData& k) { ifstream my_inp ("CON"); my_inp >> k; switch (my_inp.rdstate()) { case ios::failbit: case ios::badbit: cout << DATA_ERROR << REPEAT; cout.flush(); return 1; default: return 0; // ok! } }
/////////////////// ВВОД С КОНТРОЛЕМ ДИАПАЗОНА ////////////////////// // template <class typData> int InputNum(typData& z, const long MIN=2L, const long MAX=N) { long int temp; //!!!!!!!!!! int exit_func=0; while (exit_func==0) { cout << VALUE << MIN << TO << MAX << " ===> "; cout.flush(); while (input(temp)); if ((temp>=MIN)&&(temp<=MAX)) exit_func = 1; else { textcolor(LIGHTRED); clreol(); cout << VALUE_RANGE; textcolor(GREEN); clreol(); cout.flush(); } } z=(typData)temp; return exit_func; }
///////////////////////// ВВОД ЭЛЕМЕНТОВ МАССИВА /////////////// // void inputArray(int A[], int array_size) { randomize(); int j=1; for (int i=0; i<array_size; i++) if (array_size<11) { cout << "Enter A[" << i << "]"<< endl; InputNum(A[i],-32768L, 32767L); } else { j = -j; array[i]= j*random (130); } }
///////////////////////// ВЫВОД ЭЛЕМЕНТОВ МАССИВА //////////////////// // void outputArray(const int A[], int n) { cout << "\n================================================================\n" << " Array: \n"; for (int i=0; i<n; i++) cout << setw(8) << A[i]; cout << endl; }
//////////////////////// ОСНОВНАЯ ЗАДАЧА //////////////////////////// // double calc_c(const int array[], const int l, const int array_size) { double res = 1; //!!!!!!!!!!!!!!!!! exist=0; int i=array_size-1; int j=0; // счетчик положительных элементов while (i>=0) { if (array[i]>0) { j++; RangeError(j, array[i]); // Визуализация вычислений res *= array[i]; exist=1; if (j==l) return res; } i--; } return res; }
///////////////////////////////////////////////////////////////// // main program void main() { int l,t=1; for(;;) { textcolor(WHITE); clrscr(); cout << "\n========= test #" << t++ << "===============\n" << TITLE << "int array[array_size], 2<=array_size<=" << N << endl; cout << ENTER_LEN << " Ctrl-C (exit)" << endl; // Ввод числа элементов массива InputNum(array_size); // Ввод элементов массива inputArray(array, array_size); outputArray(array, array_size); cout << MULT; cout.flush(); // Ввод числа перемножаемых элементов массива InputNum(l, 1, array_size); textcolor(WHITE); // Вычисления на С++ cout << "\nC++ function calculation\n"; double res = calc_c(array, l, array_size); if (exist == 0) cout << "C++: " << NO_ELEM << endl; else { cout << " = " << res << endl; if (res > 65535L) cout << RESULT_RANGE; } // Вычисления на Ассемблере cout << "\nAsm function calculation\n"; unsigned resAsm = calc(l); if (!exist) cout << " = " << resAsm << endl; else if (exist == -1) cout << "ASM: " << NO_ELEM << endl; else if (exist == 1)cout << ASM_CALC << endl; cout.flush(); getch(); } }
|