· Начало · Статистика · WASM.RU · Noir.Ru ·

 WASM Phorum (Оффлайн - 24.11.2003) —› WASM.WIN32 —› Проблема!!! Как использовать STRUCT и динамическую

. 1 . 2 . 3 . >>

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


Дата: Авг 1, 2003 15:31:14 · Поправил: Безпощадный даос

Профи асма, ПОМОГИТЕ !!!
Тут у меня проблем есть:

Я создал структуру оператором STRUCT вот так:
STRINGS STRUCT
	next	dd ?
	prev	dd ?
	text	dd ?
STRINGS ENDS

Если кто не догадался - это двусвязный список.

Мне бы надо этот список разместить в динамической памяти.
Я делал это вот так:
...
pStrBeg		TYPEDEF ptr STRINGS
ppp			pStrBeg ?
...
invoke GlobalAlloc,GMEM_FIXED,sizeof STRINGS
mov ppp,eax        ;тут получаем указатель на блок ДП
mov ppp.next,eax   ;а вот на эту строчку компилятор жутко ругается - типа next - нету
Я и другие варианты пробовал, но безуспешно.
Кто когда нибудь работал со структурами - помогите разместить ее в ДП.


Дата: Авг 1, 2003 15:47:58

invoke GlobalAlloc, GMEM_FIXED, sizeof STRINGS 
mov ppp, eax
mov (STRINGS ptr [eax]).next, eax


И скорее всего GlobalAlloc те не нужен ибо:
"The global and local functions supported for porting from 16-bit code, or maintaining source code compatibility with 16-bit Windows. The global and local functions are slower than other memory management functions and do not provide as many features."

Так что лучше юзай HeapAlloc или сразу кусок для всего попроси VirtualAlloc.


Дата: Авг 1, 2003 16:01:59

profi_r
Вообще это называетсется ненаписанные главы "Управление памятью". :)))
То есть нужен мини мэнеджер управления... Но он очень лёгкий.
Объясняю алгоритм:
1. Памяти мало? Выделяем кусок по XXX Kб (лучше VirtualAlloc.)
2. Память есть, просматриваем, и в первом свободном месте создаём структуру
3. Свободное место -- нули, занятое -- ненули...

В кратсе это так...
Я не говорю о сборке мусора, дефрагментации и так далее
Только я что-то не понял, зачем вам такая структура?
Может можно как-то легче поступить?


Дата: Авг 1, 2003 17:42:07

Four-F пасибо за mov (STRINGS ptr [eax]).next, eax компилится !!! :-)
Ну я тока не понял что мне использовать если не GlobalAlloc ???

Edmond: это сложновато

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

А про VirtualAlloc я маловато знаю мож кто нить просветит.


Дата: Авг 1, 2003 18:12:03

profi_r
Нужно сделать список строк - длина строк должна изменятся и количество строк тоже.
Ну тогда вы совсем не в ту степть :(((
Я конечно понимаю, что Алгоритмы для списка сложнее, чем для ассоциативного. Ну а что ж.. Надо же когда-то начинать?
Вы можете просто пользоваться массивом из указателей...
Или Гранулированный массив..
(Надо как то расказть с чем едят)
А про VirtualAlloc я маловато знаю мож кто нить просветит.
Посмотри Туториалы. Там должно быть.
И на RSDN сходи..


Дата: Авг 1, 2003 18:19:56

profi_r
Кстати идея с массивом указателей лучше..
Неужели под каждую структуру вы будете выделять память???
Это же ужас!!!
Зачем тогда вообще на асме программировать?

-=-=-=-=-=-=-=

Возмите сделайте массив указателей.
Сделайте гранулированный массив. Это красивое решение.
Рассказываю.

Гранулированный массив -- это как совокупность структур списка...
Но в одной структуре (сегменте массива) помещаются сразу несколько указателей (пусть 256)

ТО есть имеем:

Блоки по 256*4 байт

Поледние 4-е байта структуры -- это указатель на на следующий 256*4 байт.

Первый 4 байта -- это состояние блока.
Например 0 - блок пуст
1 - нет
В более сложных алгоритмах -- я помещаю туда количество занятых байт, чтобы аналзировать насколько он полон.

Пока всё...
(Нас взламывают :))) пора дырки крыть)


Дата: Авг 1, 2003 19:25:36 · Поправил: Four-F

[ profi_r: что мне использовать если не GlobalAlloc??? ]

Это трудно сказать, т.к. у m$ богатый API для работы с памятью.
Если тупо, то скорее всего GetProcessHeap/HeapAlloc или HeapCreate/HeapAlloc.
Если объектов много то это не эффективно, но роботать будет в любом случае. Или Edmond'а слушай, но это сложнее ;-)

Ну а на будущее читать "Memory Management Reference" в Platform SDK.


Дата: Авг 1, 2003 19:55:25 · Поправил: Edmond

Four-F
Кстати, раз пошла такая пянка. у меня старый вопрос.
Этот GlobalAlloc до сих пор валиден в некоторых функциях, которые возвращают его дескриптор, скажи что она (GlobalAlloc) есть на самом деле?


Дата: Авг 1, 2003 20:41:36

Вариант с массивом указателей (проверен временем):
C_MAXSTRINGS        equ 64
ERROR_NO_FREE_SPACE equ 65

.DATA?
dNumStrings   dd ?
dArrayStrings dd C_MAXSTRINGS dup (?)

.CODE
; Добавить строку в массив:
; lpString -- указатель на новую строку
; Возвращает индекс вставленной строки
; или ERROR_NO_FREE_SPACE
addString PROC lpString:DWORD
LOCAL retVal:DWORD
   ; Есть свободное место?
   cmp dNumStrings,C_MAXSTRINGS
   jl @F
   mov eax,ERROR_NO_FREE_SPACE
   ret
@@:
   mov ecx,C_MAXSTRINGS
   mov retVal,ecx
   ; Найти следующую свободную ячейку
   lea esi,dArrayStrings
   cld
@@:
   lodsd
   test eax,eax
   loopnz @B
   jz @F
   ; Странно... места всё-таки нет!
   mov eax,ERROR_NO_FREE_SPACE
   ret
@@:
   sub retVal,ecx
   ; Тут создаём копию lpString через HeapAlloc
   ; или любым другим способом
   DupString lpSTring
   test eax,eax
   jnz @F
   mov eax,ERROR_NO_FREE_SPACE
   ret
@@:
   mov ecx,retVal
   mov DWORD PTR [OFFSET dArrayStrings + 4*ecx],eax
   inc dNumStrings
   mov eax,retVal
   ret
addString ENDP

; Удалить строку
delString PROC index:DWORD
   mov ecx,index
   mov eax,[OFFSET dArrayStrings + 4*ecx]
   test eax,eax
   jz @F
   ; Удалить строку через HeapFree, например
   delete eax
   xor eax,eax
   mov ecx,index
   ; Обнулить ячейку для реутилизации
   mov DWORD PTR [OFFSET dArrayStrings + 4*ecx],eax
   dec dNumStrings
   ret
@@:
   mov eax,ERROR
   ret
delString ENDP

; Удалить весь массив
delAll PROC
   cmp dNumStrings,0
   je _gotoret
   mov ecx,C_MAXSTRINGS
_loop_array:
   mov eax,[OFFSET dNumStrings + 4*ecx]
   test eax,eax
   jz @F
   push ecx
   delete eax
   pop ecx
   mov DWORD PTR [OFFSET dArrayStrings + 4*ecx],0
@@:
   loop _loop_array
_gotoret:
   xor eax,eax
   ret
delAll ENDP


Дата: Авг 1, 2003 21:28:26 · Поправил: Four-F

Не совсем понял вопрос. GlobalAlloc это и есть функция. Оставлена для обратной совместимости и не рекомендуется к употреблению. Возвращает указатель на выделенную память из стандартной кучи процесса. Под NT это на самом деле ntdll!RtlAllocateHeap. Вместо нее лучше юзать HeapAlloc. Остальное в MSDN.

Ммм.. Ну собсно и HeapAlloc это вообще сразу ntdll!RtlAllocateHeap через Forwarder Chain. Так что GlobalAlloc и HeapAlloc практически одно и то же. Главное всяких левых флагов, типа GMEM_FIXED, не использовать без надобности. Если интересно - копните их в дебаггере - там просто все.

ЗЫ: Все имеется ввиду под NT. Что там под 9x с этим делом хз.


Дата: Авг 1, 2003 21:29:02

Quantum: Спасибо за исходник! Тока надо немного его доработать - строки надо вставлять в массив по индексу и размерность массива должна быть изменяемой. Я попробую этот вариант.

Есть еще один вопрос - чем отличается HeapAlloc от GlobalAlloc. И что значит сия строчка (я ее выдрал из хелпа по апишкам) "Memory allocated by HeapAlloc is not movable"

VirtualAlloc вроде бы для работы с файлом подкачки - она для строк не идет - там блоки кратны 8Кб кажется.

И вобще для строк какую лучше использовать?


Дата: Авг 1, 2003 21:36:35

Ой - про GlobalAlloc ответ вверху :))


Дата: Авг 1, 2003 21:44:36

profi_r
строки надо вставлять в массив по индексу
Это ещё проще.

и размерность массива должна быть изменяемой
А вот это уже сложнее... Т.е. заведомо большое значение (например, 4Кб) не пойдёт?

чем отличается HeapAlloc от GlobalAlloc
Используйте HeapAlloc. GlobalAlloc и LocalAlloc -- отстойные врапперы.

VirtualAlloc вроде бы для работы с файлом подкачки
VirtalAlloc идеальная API для резервирования большИх кусков памяти. Ещё есть MMF.

ЗЫ: Вот что по этому поводу думает Borland:
LPSTR DupString(LPSTR lpsz) 
{ 
    int cb = lstrlen(lpsz) + 1; 
    LPSTR lpszNew = LocalAlloc(LMEM_FIXED, cb); 
    if (lpszNew != NULL) 
        CopyMemory(lpszNew, lpsz, cb); 
    return lpszNew; 
} 
MSDN не читают...


Дата: Авг 1, 2003 22:25:18

Quantum:
Заведомо большой кусок не подойдет - размер текста будет изменятся от 0 до может быть 5Mb.

Ну все - мой выбор окончательно пал на HeapAlloc. Тока еще вопросик - можно изменять размер блоков памяти, выделенных HeapAlloc-ом? И есть ли у него какая нибудь кратность при установке размера памяти?

PS: А где можно найти MSDN?


Дата: Авг 1, 2003 22:40:43 · Поправил: Quantum

Тока еще вопросик - можно изменять размер блоков памяти, выделенных HeapAlloc-ом?
IMO, нет. Только создавать новый блок, копировать туда старые данные и удалять предыдущий блок. Альтернативный вариант -- мэнеджер управления памятью (это к Edmond'у).

А где можно найти MSDN?
http://msdn.microsoft.com/library/en-us/memory/base/heapalloc.asp

. 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.083