2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Pascal+assembler
Сообщение05.06.2010, 16:10 
Здравствуйте. Пишу программу c использованием этих 2-х языков. В паскале прописываются только данные, вызов процедуры и вывод на экран; тело процедуры пишется на асме и хранится во внешнем odj - файле. Вцелом механизм передачи параметров ясен, непонятно как работать с передачей параметра по ссылке. к примеру, вызывается процедура:
Код:
procedure Res(var R:integer; i,f: integer)

R-результат, возврашаемый процедурой. здесь в стек сбросится, не значение ячейки памяти R, а ее адрес. соответстенно вопрос: как в процедуре на асме присвоить R получившееся число, если известно, что адрес R хранится в стеке? извлечь адрес из стека - это само собой, а вот дальше-то как с ним работать :roll:
ps. надеюсь на вашу подсказку, т.к. ни в книжках ни в интернете ничего внятного по этому поводу не нашел.

 
 
 
 Re: Pascal+assembler
Сообщение05.06.2010, 16:18 
Аватара пользователя
А в ASM-е вроде же был оператор WORD PTR?

В Паскале или в Дельфи появились ассемблерные процедуры, что-то вроде:
Код:
Procedure MyProc(param: integer) assembler
   MOV ...
end;


Этот способ был проще по использованию, хотя детали я забыл.

 
 
 
 Re: Pascal+assembler
Сообщение05.06.2010, 16:40 
то есть можно сделать так:
Код:
mov word ptr [adress], cx

где adress - адрес R (извлеченный из стека), cx - регистр с результатом.
я вас правильно понял?
AlexDem писал(а):
Этот способ был проще по использованию, хотя детали я забыл.

с ассемблерной всавкой прога готова, действительно проще. но теперь нужно именно с внешней ассемблерной(

 
 
 
 Re: Pascal+assembler
Сообщение05.06.2010, 16:43 
Аватара пользователя
fit в сообщении #328027 писал(а):
где adress - адрес R (извлеченный из стека), cx - регистр с результатом.я вас правильно понял?

Да, примерно так, надо попробовать.

 
 
 
 Re: Pascal+assembler
Сообщение05.06.2010, 16:47 
спасибо. попробую)

 
 
 
 Re: Pascal+assembler
Сообщение05.06.2010, 21:58 
как не крутил программа упрямо выводит 0 :-( что-то не так с этим R

 
 
 
 Re: Pascal+assembler
Сообщение05.06.2010, 22:12 
Аватара пользователя
Соглашение вызова stdcall, cdecl? Какое-нибудь значение параметра видно внутри функции? Ух, я уже много лет с этим не связывался, может, что-то ещё упускаю...

 
 
 
 Re: Pascal+assembler
Сообщение05.06.2010, 22:35 
использую ближний вызов near. вот для наглядности код

(вызов процедуры на паскале)

Код:
program new;
uses crt;
procedure Res(I,F:integer; var R:integer);external;
{$L 9.obj}
var R:integer;
begin
Res(1,1,R);
writeln(R);
readkey;
end.

(тело процедуры на tasm)

Код:
public Res

.data
L1 dw ?
L2 dw ?
adress dw ?

.code

Res proc near
push bp
mov bp,sp

V1 equ [bp+8]
V2 equ [bp+6]
Ad equ [bp+4]
mov ax, V1
mov L1,ax
mov ax, V2
mov L2,ax
mov ax, Ad
mov adress,ax

   mov   cx,L1
   mov   ax,L2
repeat:   add   cx,1
   mul   cx
   jo   great
   jmp   repeat
great:   sub   cx,1
   mov   word ptr [adress],cx
   pop bp
   ret
Res endp
end

задачка простая, найти максимальное число факториал которого может содержать регистр ax.
в процедуре использую локальные переменные L1, L2 и adress, в которых содержатся взятые из стека параметры. запустил exe-шник в дебагере, вроде как программа даже не доходит до основной части процедуры (где вычисление значения).

 
 
 
 Re: Pascal+assembler
Сообщение05.06.2010, 23:17 
Аватара пользователя
fit в сообщении #328140 писал(а):
procedure Res(I,F:integer; var R:integer);external;

Мне кажется, здесь нужно явно указать соглашение о вызове, у Вас это "pascal":
Код:
procedure Res(I,F:integer; var R:integer);pascal;external;

Бывают register, cdecl, pascal, stdcall, пишут, что при включенной директиве оптимизации {$O+} идёт "register". Может, в этом проблема?

Поисковик находит вроде примеры по запросу "pascal cdecl" и подобным - попробуйте поискать.

-- Вс июн 06, 2010 00:41:00 --

AlexDem в сообщении #328151 писал(а):
у Вас это "pascal"

Или подождите... Если бы это был "pascal", то тогда при возврате нужно было бы чистить стек: "ret 6"... Получается, что cdecl подразумевался (только я что-то в порядке параметров запутался), но не был указан?

Вот пример, хотя там нет явного указания соглашения.

 
 
 
 Re: Pascal+assembler
Сообщение06.06.2010, 00:49 
вроде бы по умолчанию параметры в стек всегда передаются слева направо (по крайней мере при работе с ассемблерными вставками это так) и очистка стека тоже на совести паскаля (если не ошибаюсь).
каламбур в том, что при попытке прописать "pascal", "cdecl" или что-то еще вами предложенное паскаль начинает ругаться, не хочет понимать.
скорее всего проблема в неправильной работе с адресом переменной R. но сколько не искал в интернетах, не нашел нигде что-то конкретного о передаче параметра через var во внешнюю ассемблеровскую процедуру :-(

 
 
 
 Re: Pascal+assembler
Сообщение06.06.2010, 00:55 
Аватара пользователя
Посмотрите тогда пример, ссылку на который я привёл - может, поможет. А синтаксис я подзабыл - надо смотреть, куда этот модификатор вписывается. Это и в документации должно быть, или примеры, опять же, поискать. Я думаю, что затык где-то здесь - в соглашении о вызове. Ещё бы порядок параметров проверить нужно.

-- Вс июн 06, 2010 01:56:50 --

fit в сообщении #328159 писал(а):
скорее всего проблема в неправильной работе с адресом переменной R. но сколько не искал в интернетах, не нашел нигде что-то конкретного о передаче параметра через var во внешнюю ассемблеровскую процедуру

А если через AX вернуть результат и процедуру в функцию переделать, то всё работает?

 
 
 
 Re: Pascal+assembler
Сообщение06.06.2010, 00:57 
1. Указатель имеет тип dword (сегмент:смещение)
2. ret 8
3. Переменную для смещения я бы не заводил, а просто сохранил бы смешение в регистре bx. Присвоение значения я бы делал тогда так: mov word ptr ds:[bx],cx

Проверьте, а то я совсем засыпаю!

Код:
.model small

.data
L1 dw ?
L2 dw ?

.code
Public Res
Res proc near
push bp
mov bp,sp

V1 equ word ptr[bp+10]
V2 equ word ptr[bp+8]
Ad equ word ptr[bp+4]
mov ax, V1
mov L1,ax
mov ax, V2
mov L2,ax
mov ax, Ad
mov bx,ax

   mov   cx,L1
   mov   ax,L2
repeat:   add   cx,1
   mul   cx
   jo   great
   jmp   repeat
great:   sub   cx,1

   mov   word ptr ds:[bx],cx
   pop bp
   ret 8
Res endp
end


-- Вс 06.06.2010 00:05:03 --

У меня лишний код для совместимости с Вашим текстом.
Уберите ненужное сами.

 
 
 
 Re: Pascal+assembler
Сообщение06.06.2010, 11:14 
В моем предыдущем тексте считается, что переменная R в сегменте данных (глобальная переменная). Если требуется общность (возможность использование локальных переменных или переменных кучи), то лучше не копировать сегмент в регистр ds, а использовать es.

AlexDem в сообщении #328161 писал(а):
А если через AX вернуть результат и процедуру в функцию переделать, то всё работает?
Поддерживаю. Если передавать через R значение в процедуру не надо, то так всегда и делают.

 
 
 
 Re: Pascal+assembler
Сообщение06.06.2010, 12:18 
AlexDem писал(а):
А если через AX вернуть результат и процедуру в функцию переделать, то всё работает?

да, с функцией все работает как надо) так действительно проще и рациональней.
GAA писал(а):
У меня лишний код для совместимости с Вашим текстом.

поправил. ваш код рабочий. ошибка понятна, для R нужно было учитывать адрес сегмента. спасибо за разъяснения.
ps. AlexDem,GAA с вашей помощью разобрался, спасибо :-)

 
 
 
 Re: Pascal+assembler
Сообщение06.06.2010, 12:25 
Аватара пользователя
Хорошо, что GAA вовремя помог, а то мы бы тут долго ещё ползали :D

 
 
 [ Сообщений: 15 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group