|
|
| Посл.отвђт | Сообщен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? |