![]()  | 
	
 
  | 
| 
		 
			 
			#1  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Подскажите, как на фасме проще забабахать простейший связный список. 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	В голову кроме извращений с Alloc'ами ничего не приходит. Или как та же виЖуал студия их реализует(ща нет возможности в визуал студию зайти)?  | 
| 
		 
			 
			#2  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Вообще простейший список - да, куча аллоков. 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	Однако STL вроде бы выделяет блок памяти и размечает в нем список, потом с ним работает. Если становится мало - выделяет еще один и размечает его. По крайней мере так было когда я не заметил, как ревершу список в одной проге. Простейший же список я делал на фасме через постоянный маллок. Структурка вида Код: 
	struc List
{
   .Next dd 0
   .Data dd 0
   .size = $ - .Next
} | 
| 
		 
			 
			#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 - в качестве примера, ибо в качестве этакого менеджера памяти сделано все это. Смещения в структуре не стал расписывать константами, ибо нафиг не надо, хотя стоило бы. Последний раз редактировалось 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 ; добавляем данные и выходим Последний раз редактировалось 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; Последний раз редактировалось M.A.D.M.A.N., 18.04.2013 в 08:16.  |