· Начало · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Несколько вопросов от начинающего...

. 1 . 2 . >>

Посл.отвђт Сообщенiе


Дата: Окт 31, 2003 23:59:20
Правка

Неохота было делать несколько тем, так как их объединяет мой переход с ЯВУ на Ассемблер...

1. Есть структура на ObjectPascal:
TStruct = record
f1: function(a:Integer; b:Integer):Byte;
f2: function:Boolean;
...
end;

Как это сделать на Асме?
Просто определить структуру, где членами были бы указатели на эти процедуры? А отдельно определять прототипами эти самые функции? Точнее, на Асме, как я понял, это один чёрт.

2. Есть функция, возвращающая что-то большое, типа структуры:
TStruct = record
so: TObject;
sa: array[0..254] of Byte;
end;

function Some(a: Boolean):TStruct;
begin
...
Result.so:= ...
Result.sa[0]:= 0;
end;

Как быть здесь? Саму структуру возвратить не получится, придётся возвращать указатель. Но на что? Выделять память в процедуре и заполнять её, попутно приобразовывая?
А возвращать указатель? Или есть альтернатива?


Дата: Ноя 1, 2003 00:25:51
Правка

И ещё вопрос о соглашении о вызовах:

я пишу плагин к приложению, использующему cdecl.
Как определить этот вызов в своей процедуре, оставив глобальное stdcall?

test proc cdecl var:DWORD

test endp

Или как? Книг мало, я покопался, там даются описания, а как на примере?

offtopic
Почему не работают кнопочки стиля текста? Сначала работали, а потом перестали...


Дата: Ноя 1, 2003 01:27:29

Ответ к вопросу номер 1:
Нужно создать структуру, содержащую указатели на функции (это ты и сам, конечно, понял). Возвращаемое функцией значение принято помещать в регистр EAX/AX (имеется в виду помещение возвращаемого значения перед выходом из функции), но можно и в другой.

Вот пример под Win32

_1027209586__Question1.zip


Дата: Ноя 1, 2003 01:52:25
Правка

Спасибо, всё так, как я и думал насчёт использования.
А для invoke, видимо, нужно отдельно объявлять...

А как насчёт второго вопроса? И с соглашениями проблема...


Дата: Ноя 1, 2003 02:06:32 · Поправил: Sk. Inc.

Ответ к вопросу номер 2:
Что будет возвращать функция, зависит от метода объявления переменной (в данном случае именуемой Result). Если переменная Result объявлена в секции данных (.data), то она является глобальной и возвращать ничего не нужно.
Для Win32:Можно выделять память под структуру и внутри функции (HeapAlloc), но тогда придется возвращать указатель на память, а после того, как структура будет больше не нужна, эту память необходимо будет высвободить (HeapFree).


Дата: Ноя 1, 2003 02:11:03
Правка

И вот ещё, что я заметил (с удивлением):
Functions	MyStruct <offset funct1,offset funct2>


То есть, это секция инициализированных данных, и структура заполняется уже реальными смещениями? Но ведь функции объявлены после структуры, откуда компилятор узнал о смещениях? Или он несколько раз проходит по исходному тексту? Тогда почему не проходит такое:
Func1 proc
 
 invoke Func2
 ret
Func1 endp

Func2 proc

 ret
Func2 endp

, а с call проходит? Да и с LEA EAX,Func2 ?


Дата: Ноя 1, 2003 02:23:18
Правка

Если переменная Result объявлена в секции данных
Это понятно, просто в ObjectPascal не поймёшь, где какая секция :)

Выделять память внутри структуры...
А кто же её освободит? Если я передам указатель на память при выходе из про... из подпрограммы основному приложению... Впрочем, можно и самому почистить, когда оно будет прощаться со мной.
Нужно будет MemoryManagement почитать хорошенько!


Дата: Ноя 1, 2003 02:46:57 · Поправил: Sk. Inc.

Компилятор проходит код несколько раз (кажется 2), поэтому и знает обо всех объявлениях в исходном коде. Это также относится к call и lea eax,Funct2.
По поводу invoke, я где-то слышал, что это макрокоманда (и addr - тоже). А то, что на invoke компиляция вываливается с ошибкой, похоже, говорит, что обработка макрокоманд и прототипов происходит за один и тот же проход.


Дата: Ноя 1, 2003 02:59:30 · Поправил: Sk. Inc.

По поводу выделения памяти внутри процедуры, я предлагаю делать так:
start proc
local	hMem:DWORD
	...
	call	MyProc
	mov	hMem,eax	; после вызова функции указатель на память в EAX
	...
	invoke	GetProcessHeap
	invoke	HeapFree,eax,null,hMem
	...
start endp


MyProc proc
local	hMem:DWORD
	...
	invoke	GetProcessHeap
	invoke	HeapAlloc,eax,HEAP_ZERO_MEMORY,размер_структуры
	mov	hMem,eax
	...
	mov	eax,hMem
	ret
MyProc endp


Дата: Ноя 1, 2003 02:59:56
Правка

я где-то слышал, что это макрокоманда
Да, это я уже вычитал, обе команды — макро.

По-видимому, в MASM компиляция происходит как и в других компиляторах с поддержкой макросов:
сначала идёт препроцессор (и он, видимо, в MASM идёт только один раз), потом уже сам интерпретатор или транслятор (кажется, MASM — это транслятор?), вероятно, два раза.


Дата: Ноя 1, 2003 03:10:43
Правка

По поводу выделения памяти внутри процедуры, я предлагаю делать так
Ага, только MyProc — моя процедура, а start — процедура управляющего приложения (или как его назвать?) и неизвестно, что оно делает с моей памятью.

Как вариант — при завершении попробовать освободить выделенную мной память. А что будет, если два раза вызвать xxFree (Virtual, Heap)?

И ещё:
Я делаю так:
.data
myStruc: MYSTRUCT <>
szStr1 : PCHAR ?

, а что будет, если я помещу переменную типа структуры в секцию неинициализированных данных?
Переменные этой секции выделяются динамически (кажется), а как с местом? Или загрузчик просто даст 4 байта под указатель на мою структуру, а для неё самой места не хватит? И я перепишу при записи в неё следующие за ней данные (szStr1)?


Дата: Ноя 1, 2003 03:13:51

IceStudent
я пишу плагин к приложению, использующему cdecl.
А что такое cdecl?


Дата: Ноя 1, 2003 03:23:04
Правка

Опа!
И ещё вопрос о соглашении о вызовах
Это такое соглашение, С и С++ его используют.
Там передача параметров справа налево, как в stdcall, но о стеке заботится не подпрограмма, а вызывающая... м-м-м... вызывающая подпрограмма.
Как по мне, так это чушь, куда проще в процедуре один раз поправить стек, чем n раз после каждого вызова. Разве что компилятор сам об этом позаботится...
Но потому я и спрашиваю, что не понял, как ему намекнуть об этом.


Дата: Ноя 1, 2003 03:24:02

IceStudent
Если ты объявляешь переменную как структуру, то под нее (переменную) выделяется место равное размеру этой структуры, независимо от типа секции данных.


Дата: Ноя 1, 2003 03:37:13

IceStudent
Это такое соглашение, С и С++ его используют
А С и С++ под какой операционкой работают: Dos или Win32?

. 1 . 2 . >>