Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Прочие языки программирования > Assembler
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 15.04.2013, 13:11
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию Связный список

Подскажите, как на фасме проще забабахать простейший связный список.
В голову кроме извращений с Alloc'ами ничего не приходит.

Или как та же виЖуал студия их реализует(ща нет возможности в визуал студию зайти)?
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #2  
Старый 15.04.2013, 13:28
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Вообще простейший список - да, куча аллоков.
Однако STL вроде бы выделяет блок памяти и размечает в нем список, потом с ним работает. Если становится мало - выделяет еще один и размечает его. По крайней мере так было когда я не заметил, как ревершу список в одной проге.

Простейший же список я делал на фасме через постоянный маллок. Структурка вида
Код:
1
2
3
4
5
6
7
struc List
{
   .Next dd 0
   .Data dd 0
 
   .size = $ - .Next
}
сильно упрощает дело.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #3  
Старый 17.04.2013, 11:39
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Набабахал (путем рипа из дельфи) некое подобие связного списка.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
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  
Старый 17.04.2013, 22:04
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Че-то много. У меня было куда меньше. Что-то вроде
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
; 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
; добавляем данные и выходим
А если дозволено добавлять элементы в начало - так вообще
Код:
1
2
3
4
5
6
7
; на этот раз 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  
Старый 18.04.2013, 08:13
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Спасибо за замечания.
Да я просто чтоб не заморачиваться - в дельфи написал, потом выдергал код (ХЕ3, обратите внимание на цикл while, как она его забавно скомпилировала).
Вот эту вот херь:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//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.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 00:16.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025