Регистрация: 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
|