Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.01.2011, 14:04   #1
toosya
 
Регистрация: 27.04.2009
Сообщений: 7
По умолчанию Зависает программа на паскале при обращении к модулю АСМ

Программа вычисления целочисленного результата выражения. Паскаль считает нормально, подключает асм-модуль, передает данные, асм их обрабатывает и возвращает. И тут она зависает. При отключении вызова процедуры из асма, программа завершается нормально. Не могу понять в чем ошибка. Подскажите, буду благодарна.

ПАСКАЛЬ:
Код:
program Lab3P;
{-Вариант 3 (-2*с + d*82)/(a/4 - 1);-}
{$L Lab3asm} {вызов асм-модуля lab3asm.obj}
{$f+}
Uses CRT, InputNum;
Const
  inv2='Результат';
  invAi='A (integer)';
  invCi='C (integer)';
  invDi='D (integer)';
  invAs='A (ShortInt)';
  invCs='C (ShortInt)';
  invDs='D (ShortInt)';

  {Допустимый диапазон}
  IntMin=-32768;
  IntMax=32767;
  ShortMin=-128;
  ShortMax=127;

var
  a,c,d,x,Numerator        :LongInt;
  aS,ccS,ddS               :ShortInt;
  xI,aI,cI,ddI,Denominator :Integer;
  ch                       :Char;

{Внешние процедуры на асм}
Procedure Lab3I(var x:Integer; aI,cI,ddI:Integer); external;
Procedure Lab3S(var x:Integer; aS,ccS,ddS:ShortInt); external;

{Функция вычисления x=(-2*c + d*82)/(a/4 - 1) с проверкой}
function F (a,c,d:LongInt; Min,Max:LongInt): Boolean;
var x1 : LongInt;
    s1 : String;
begin
    F:=True; {ошибок нет}
    x1:=a div 4 - 1;
  {проверка выхода за диапазон знаменателя}
    if (x1<Min)OR(x1>Max) then
         begin
           s1:='Знаменатель     '+inv3; {сообщение об ошибке}
           Writeln(s1,'[',Min,'..',Max,']!!!!');
           {Вывод полученного значения выходящего за допустимый диапазон*}
           Writeln(x1);
           Writeln(inv1);
           F:=False; {признак ошибки}
           Exit;
         end;
    if (x1=0) then
         begin
           Writeln('Ошибка! Деление на ноль!');
           F:=False; {Признак ошибки}
         end
    else
         begin
           x:=-2*c+d*82;
           Writeln('Pascal:');
           Writeln('Числитель     ',x);
           Writeln('Знаменатель   ',x1);
           x:=x div x1;
           Writeln('        x=',x);
{Проверка выхода за диапазон результата}
    if (x<Min)OR(x>Max) then
         begin
           s1:=inv1+' '+inv3; {сообщение об ошибке}
           Writeln(s1,'[',Min,'..',Max,']!!!!');
         {Вывод полученного значения, выходящего за диапазон}
           Writeln(x);
           Writeln(inv1);
           F:=False; {признак ошибки}
           Exit;
         end
    end
end;

{-----------блок процедур работы с определенным типом данных----------------}
Procedure ExpI; {Integer}
begin
  Writeln('==========================Integer==========================');
  {проверка вводимых данных}
  Repeat
    InputNumber(a,invAi,IntMin,IntMax);
    InputNumber(c,invCi,IntMin,IntMax);
    InputNumber(d,invDi,IntMin,IntMax);
  until (F(a,c,d,IntMin,IntMax));
    aI:=a; cI:=c; ddI:=d;
    Lab3I(xI,aI,cI,ddI);
    Writeln('ассемблер:');
    Writeln('Числитель     ',Numerator);
    Writeln('Знаменатель   ',Denominator);
    Writeln('        x= ',xI);
end;

Procedure ExpS; {ShortInt}
begin
  Writeln('=========================ShortInt==========================');
  {Проверка вводимых данных}
  Repeat
    InputNumber(a,invAs,ShortMin,ShortMax);
    InputNumber(c,invCs,ShortMin,ShortMax);
    InputNumber(d,invDs,ShortMin,ShortMax);
  until (F(a,c,d,IntMin,IntMax));
    aS:=a; ccS:=c; ddS:=d;
    Lab3S(xI,aS,ccS,ddS);
    Writeln('ассемблер: ');
    Writeln('Числитель    ',Numerator);
    Writeln('Знаменатель  ',Denominator);
    Writeln('        x= ',xI);
end;
{------------------------------------------------------------------------}
Procedure Main;
  var i:Integer;
  begin
    Writeln('Вычислить:     x = (-2*c + d*82)/(a/4 - 1);');
    Repeat
      Writeln('Введите ваш выбор параметров x,a,d');
      Writeln('        1 - Integer');
      Writeln('        2 - ShortInt');
      Writeln('        3 - Выход');
{контроль ввода не числовых значений}
    {$I-}
      Readln(i); {промежуточный буфер ввода}
    {$I+}
  Until (IOResult=0);
  case i of
    1: ExpI;
    2: ExpS;
    3: HALT(0); {выход с кодом 0}
  else Exit;
  end
end;
begin
  Repeat
    ClrScr;
    Main;
    Writeln('Повторим? (y/n)');
    ch:=ReadKey;
  Until (ch='n') or (ch='N');
end.
АСМ-модуль:
Код:
title lab3asm.asm
	.MODEL Large, Pascal
	.data
	Extrn	Numerator:DWord
	Extrn 	aS:Byte, ccS:Byte, ddS:Byte
	Extrn	xI:Word
	Extrn	Denominator:Word
	.code	
	Public Lab3S
Lab3S	proc	far
; Знаменатель - Denominator -----------------------
	mov	cL, 4
	mov	aL, aS
	CBW
	idiv	cL
	dec	aL
	CBW
	mov	Denominator,ax
; Числитель - Numerator ---------------------------
	mov	cL,-2
	mov	aL,ccS
	Imul	cL
	push	ax
	mov	cL,82
	mov	aL,ddS
	Imul	cL
	pop	bx
	add	ax,bx
	CWD
	mov	WORD PTR Numerator, AX
	mov	WORD PTR Numerator+2, DX
; Результат
	IDIV	Denominator
	mov 	xI,ax
	ret
Lab3S	endp
	
	Public Lab3I
Lab3I	proc	far
	; ПОКА ПУСТО!!!!
	mov xI, ax
	ret
Lab3I	endp
end
toosya вне форума Ответить с цитированием
Старый 29.01.2011, 14:19   #2
toosya
 
Регистрация: 27.04.2009
Сообщений: 7
По умолчанию

Процедура Lab3I пока не описана. Проблема появилась при выполнении Lab3S
toosya вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Указание диапазонов при обращении к функции Parabellum Microsoft Office Excel 16 22.01.2011 23:59
При второй синхронизации программа зависает bulldog5293 Работа с сетью в Delphi 0 27.11.2010 14:42
Проблема при обращении эксель к ворду. RGZZ Microsoft Office Excel 0 16.06.2010 17:17
Ошибка при обращении к интернет странице Alter Свободное общение 2 06.08.2008 22:25
VB6. Программа зависает при выполнении. Artinka Помощь студентам 2 03.04.2008 00:06