|
#1
|
||||
|
||||
Связный список
Подскажите, как на фасме проще забабахать простейший связный список.
В голову кроме извращений с Alloc'ами ничего не приходит. Или как та же виЖуал студия их реализует(ща нет возможности в визуал студию зайти)? — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#2
|
||||
|
||||
Вообще простейший список - да, куча аллоков.
Однако STL вроде бы выделяет блок памяти и размечает в нем список, потом с ним работает. Если становится мало - выделяет еще один и размечает его. По крайней мере так было когда я не заметил, как ревершу список в одной проге. Простейший же список я делал на фасме через постоянный маллок. Структурка вида Код:
struc List { .Next dd 0 .Data dd 0 .size = $ - .Next } jmp $ ; Happy End! The Cake Is A Lie. |
#3
|
||||
|
||||
Набабахал (путем рипа из дельфи) некое подобие связного списка.
Код:
format PE GUI 4.0 entry start use32 include 'win32a.inc' section '.text' code readable executable proc InsertItem Result = -4 AParent = 8 AData = 0Ch push ebp mov ebp, esp sub esp, 4 invoke LocalAlloc, 40h, 0Ch ; 0Ch - size of struct mov [ebp+Result], eax xor edx, edx mov eax, [ebp+Result] mov [eax], edx mov eax, [ebp+Result] mov [eax+4], edx mov eax, [ebp+Result] mov edx, [ebp+AData] mov [eax+8], edx cmp dword [ebp+AParent], 0 ; if1 jz InsertItem_if1end mov eax, [ebp+Result] mov edx, [ebp+AParent] mov [eax], edx mov eax, [ebp+AParent] cmp dword [eax+4], 0 ; if2 jz InsertItem_if2else mov eax, [ebp+Result] mov edx, [ebp+AParent] mov edx, [edx+4] mov [eax+4], edx mov eax, [ebp+AParent] mov eax, [eax+4] mov edx, [ebp+Result] mov [eax], edx jmp InsertItem_if2end InsertItem_if2else: xor edx, edx mov eax, [ebp+Result] mov [eax+4], edx InsertItem_if2end: mov eax, [ebp+Result] mov edx, [ebp+AParent] mov [edx+4], eax InsertItem_if1end: mov eax, [ebp+Result] add esp, 4 pop ebp ret endp proc ClearItems j = -8 i = -4 AFirst = 8 push ebp mov ebp, esp sub esp, 8 cmp dword [ebp+AFirst], 0 ; if1 jz ClearItems_end mov eax, [ebp+AFirst] mov [ebp+i], eax cmp dword [ebp+i], 0 jz ClearItems_end ClearItems_loop_start: mov eax, [ebp+i] mov eax, [eax+8] invoke VirtualFree, eax, 0, MEM_RELEASE mov eax, [ebp+i] mov eax, [eax+4] mov [ebp+j], eax mov eax, [ebp+i] invoke LocalFree, eax mov eax, [ebp+j] mov [ebp+i], eax cmp dword [ebp+i], 0 jnz ClearItems_loop_start ClearItems_end: add esp, 8 pop ebp ret endp proc RemoveByData i = -8 Result = -4 AFirst = 8 AData = 0Ch push ebp mov ebp, esp sub esp, 8 cmp dword [ebp+AFirst], 0 ; if1 jnz RemoveByData_if1end xor eax, eax mov [ebp+Result], eax jmp RemoveByData_end RemoveByData_if1end: mov eax, [ebp+AFirst] mov [ebp+i], eax mov eax, [ebp+AFirst] mov [ebp+Result], eax cmp dword [ebp+i], 0 ; loop condition jz RemoveByData_end RemoveByData_loop: mov eax, [ebp+i] mov eax, [eax+8] cmp eax, [ebp+AData] ; if2 jnz RemoveByData_if2end mov eax, [ebp+i] cmp eax, [ebp+AFirst] ; if3 jnz RemoveByData_if3else mov eax, [ebp+i] mov eax, [eax+4] mov [ebp+Result], eax mov eax, [ebp+Result] xor edx, edx mov [eax], edx jmp RemoveByData_if3end RemoveByData_if3else: mov eax, [ebp+i] cmp dword [eax], 0 ; if4 jz RemoveByData_if4end mov eax, [ebp+i] mov eax, [eax] mov edx, [ebp+i] mov edx, [edx+4] mov [eax+4], edx RemoveByData_if4end: mov eax, [ebp+i] cmp dword [eax+4], 0 ; if5 jz RemoveByData_if3end mov eax, [ebp+i] mov eax, [eax+4] mov edx, [ebp+i] mov edx, [edx] mov [eax], edx RemoveByData_if3end: mov eax, [ebp+i] mov eax, [eax+8] invoke VirtualFree, eax, 0, MEM_RELEASE mov eax, [ebp+i] invoke LocalFree, eax jmp RemoveByData_end RemoveByData_if2end: mov eax, [ebp+i] mov eax, [eax+4] mov [ebp+i], eax cmp dword [ebp+i], 0 jnz RemoveByData_loop RemoveByData_end: mov eax, [ebp+Result] add esp, 8 pop ebp ret endp start: invoke VirtualAlloc, NULL, 1024*1024*10, MEM_COMMIT, PAGE_READONLY mov [aaa1], eax invoke VirtualAlloc, NULL, 1024*1024*10, MEM_COMMIT, PAGE_READONLY mov [bbb1], eax invoke VirtualAlloc, NULL, 1024*1024*10, MEM_COMMIT, PAGE_READONLY mov [ccc1], eax push [ccc1] push NULL call InsertItem add esp, 8 mov [root], eax push [bbb1] push [root] call InsertItem add esp, 8 push [aaa1] push eax call InsertItem add esp, 8 push [bbb1] push [root] call RemoveByData add esp, 8 mov [root], eax push [root] call ClearItems add esp, 4 invoke ExitProcess, 0 section '.data' readable writeable root dd ? aaa1 dd ? bbb1 dd ? ccc1 dd ? section '.idata' import data readable library kernel, 'KERNEL32.DLL' import kernel,\ LocalAlloc, 'LocalAlloc',\ LocalFree, 'LocalFree',\ VirtualAlloc, 'VirtualAlloc',\ VirtualFree, 'VirtualFree',\ ExitProcess , 'ExitProcess' VirtualAlloc/VirtualFree - в качестве примера, ибо в качестве этакого менеджера памяти сделано все это. Смещения в структуре не стал расписывать константами, ибо нафиг не надо, хотя стоило бы. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию Последний раз редактировалось M.A.D.M.A.N., 17.04.2013 в 11:51. |
#4
|
||||
|
||||
Че-то много. У меня было куда меньше. Что-то вроде
Код:
; List базируем на esi mov esi,[ListRoot] @@: cmp[List.Next], 0 jz @f mov esi,[List.Next] jmp @b @@: invoke LocalAlloc, ... mov[List.Next], eax mov esi, eax mov[List.Next], 0 ; добавляем данные и выходим Код:
; на этот раз List базируем на eax mov esi,[ListRoot] invoke LocalAlloc, ... mov[ListRoot], eax mov[List.Next], esi ; добавляем данные и выходим jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 17.04.2013 в 22:07. |
#5
|
||||
|
||||
Спасибо за замечания.
Да я просто чтоб не заморачиваться - в дельфи написал, потом выдергал код (ХЕ3, обратите внимание на цикл while, как она его забавно скомпилировала). Вот эту вот херь: Код:
//type // // двусвязный список // PMemPtrItem = ^TMemPtrItem; // TMemPtrItem = packed record // Left, // Right: PMemPtrItem; // Data: Pointer; // end; // // // // function InsertItem(const AParent: PMemPtrItem; // const AData: Pointer): PMemPtrItem; cdecl; // begin // Result := PMemPtrItem(LocalAlloc($40, SizeOf(TMemPtrItem))); // Result^.Left := nil; // Result^.Right := nil; // Result^.Data := AData; // // if AParent <> nil then // begin // Result^.Left := AParent; // // if AParent^.Right <> nil then // begin // вставка // Result^.Right := AParent^.Right; // AParent^.Right^.Left := Result; // end else // begin // добавление // Result^.Right := nil; // end; // // AParent^.Right := Result; // end; // end; // // // чистка слева направо // procedure ClearItems(const AFirst: PMemPtrItem); cdecl; // var // i, j: PMemPtrItem; // begin // if AFirst = nil then // Exit; // // i := AFirst; // while i <> nil do // begin // VirtualFree(i^.Data, 0, MEM_RELEASE); // // j := i^.Right; // LocalFree(integer(i)); // i := j; // end; // end; // // // считаем, что данные там уникальные // // тоже слева направо ищем // // ф-я возвращает первую запись из всего списка // function RemoveByData(const AFirst: PMemPtrItem; // const AData: Pointer): PMemPtrItem; cdecl; // var // i: PMemPtrItem; // begin // if AFirst = nil then // Exit(nil); // // i := AFirst; // Result := AFirst; // // while i <> nil do // begin // if i^.Data = AData then // begin // if i = AFirst then // begin // Result := i^.Right; // Result^.Left := nil; // end else // begin // if i^.Left <> nil then // i^.Left^.Right := i^.Right; // // if i^.Right <> nil then // i^.Right^.Left := i^.Left; // end; // // удаляем // VirtualFree(i^.Data, 0, MEM_RELEASE); // LocalFree(integer(i)); // // Exit; // end; // // i := i^.Right; // end; // end; — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию Последний раз редактировалось M.A.D.M.A.N., 18.04.2013 в 08:16. |