|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июн 13, 2004 01:51:36 Здравствуйте, господа. Может надо постить не здесь, но раздела форума для начинающих не нашёл. Помогите разобраться: есть 2 ф-ции, из одной вызываю другую, параметр - указатель на массив: ExecuteArr proc LOCAL ArrPtr :DWORD LOCAL Cntr :DWORD LOCAL Tmr :DWORD LOCAL Sigma :DWORD invoke GetTickCount mov Tmr, eax invoke FillArr, ArrPtr, 20000000 ret ExecuteArr endp ; ############################################# FillArr proc ArrPtr :DWORD, ElemNumber :DWORD mov ecx, ElemNumber jecxz endFill mov edx, ArrPtr startFill: mov dword ptr [edx + ecx*4],2 ; здесь программа вылетает invoke MessageBox,0,ADDR szMsg,ADDR szDlgTitle,MB_OK ; до этого дело не доходит dec ecx jnz startFill endFill: ;ret FillArr endp Насколько понимаю - наехал на чужой кусок памяти, а где ошибка - не найду. Помогите разобраться, пожалуйста. P.S. Алгоритм работает в другом языке в виде ассемблерной вставки, а в asm - не хочет... |
|
|
Дата: Июн 13, 2004 02:13:57 Ну нехрена себе!!! в ecx 20000000 а ты делаешь mov dword ptr [edx + ecx*4] :)))) |
|
|
Дата: Июн 13, 2004 02:31:41 если тебе нужно обработать этот массив с учетом того, что заранее не известно сколько в нем элементов, - сделай последним элементом ноль и процедура бут выглядить приблизительно так: startFill: xor ebx,ebx next_step: cmp dword ptr [edx + ebx*4],0 je endFill mov dword ptr [edx + ebx*4],2 invoke MessageBox,0,ADDR szMsg,ADDR szDlgTitle,MB_OK inc ebx jmp short next_step endFill: |
|
|
Дата: Июн 13, 2004 03:05:21 Попробовал эту процедуру - теперь вылетает на cmp dword ptr [edx + ebx*4],0 Уменьшаю до 20 элементов - результат тот же. Возможно, надо запросить предварительно памяти на свой массив, а вот как это сделать - не знаю |
|
|
Дата: Июн 13, 2004 03:38:10 Гм, а то что вызов MessageBox() будет изменять содержимое регистров ecx/edx вас не смущает? |
|
|
Дата: Июн 13, 2004 03:44:12 MessageBox вставлен чтобы определить, доходит ли дело до той или иной строки. Если не выскочил - роем до него. Выскочил - передвигаем его дальше. Закат солнца вручную. |
|
|
Дата: Июн 13, 2004 03:46:17 надо запросить предварительно памяти на свой массив Верно мыслишь. |
|
|
Дата: Июн 13, 2004 04:30:14 cresta Поскольку у вас MASM, пользуйте HeapAlloc, если блок небольшой. Иначе - VirtualAlloc - поищите по форуму примеры. |
|
|
Дата: Июн 13, 2004 04:34:58 LOCAL Arr[20] :DWORD не помогло... S_T_A_S_ Спасибо, буду искать |
|
|
Дата: Июн 13, 2004 08:15:59 Дык описания функций - MSDN, если нет, то Win32 API Reference (win32.hlp) - идёт с дельфи, если я не ошибаюсь. Так же есть на сайте Privalov'а Ещё на сайте есть Win32 API. Урок 12. Память и файлы [Iczelion, пер. Aquila] Там правда устаревшая GlobalAlloc используется..
К тому же, большие массивы создавать на стеке не так просто - по-хорошему, без VirtualAlloc при этом не обойтись. |
|
|
Дата: Июн 13, 2004 10:44:00 cresta MessageBox вставлен чтобы определить, доходит ли дело до той или иной строки. Если не выскочил - роем до него. Выскочил - передвигаем его дальше. может лучше использовать PrintText, PrintHex... и т.п. из :\MASM32\VKDEBUG ? |
|
|
Дата: Июн 13, 2004 17:28:42 Funbit спасибо за \MASM32\VKDEBUG При вызове VirtualAlloc возвращает указатель на кусок памяти, передаю в ф-цию его, но опять на mov dword ptr [edx],2 вылетаю. Может до вызова что-то не в порядке, или с моим masm-ом проблема? Вот весь код: ; #################################### .386 .model flat, stdcall option casemap :none ; case sensitive ; #################################### include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\macros\macros.asm includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib include \masm32\include\debug.inc includelib \masm32\lib\debug.lib ; #################################### szText MACRO Name, Text:VARARG LOCAL lbl jmp lbl Name db Text,0 lbl: ENDM return MACRO arg mov eax, arg ret ENDM ;================= ; Local prototypes ;================= ExecuteArr PROTO FillArr PROTO :DWORD,:DWORD ; ##################################### .data szDlgTitle db "Fill Array",0 szMsg db "Done",0 szMsg1 db "Fail",0 .code start: invoke ExecuteArr push 0 call ExitProcess ; ##################################### ExecuteArr proc invoke VirtualAlloc, NULL, 128, MEM_RESERVE, PAGE_GUARD + PAGE_READWRITE PrintDec eax invoke FillArr, eax, 32 ret label1: ret ExecuteArr endp ; ##################################### FillArr proc ArrPtr :DWORD, ElemNumber :DWORD mov ecx, ElemNumber mov edx, ArrPtr PrintDec ecx PrintDec edx jecxz endFill startFill: mov dword ptr[edx],2 ; здесь программа вылетает на первом же проходе цикла inc edx inc edx inc edx inc edx dec ecx jnz startFill endFill: invoke MessageBox,0,ADDR szMsg,ADDR szDlgTitle,MB_OK ret FillArr endp end start В окне VKDEDUG получаю следующее: eax = 8585216 (F.asm, 54) ecx = 32 (F.asm, 68) edx = 8585216 (F.asm, 69), причем указатель возвращаемый всегда равен 8585216 независимо от того как распределена память на данный момент. |
|
|
Дата: Июн 13, 2004 18:22:32 Ну MEM_RESERVE ты сделал, а MEM_COMMIT кто делать будет? Ес-сно оно вылетает :)) |
|
|
Дата: Июн 13, 2004 19:50:05 Действительно помогло, только плюс ещё надо было убрать PAGE_GUARD invoke VirtualAlloc, NULL, 128000000, MEM_COMMIT, PAGE_READWRITE Всё заполнилось и считываются значения правильно. Спасибо всем :) И ещё один момент: при первом запуске на заполнение 20000000 элементов уходит ~800мс, а при последующих время уменьшается до ~200мс. Какова причина этого явления, ведь после заполнения я вставил invoke VirtualFree, Arr, 20000000, MEM_DECOMMIT и вроде система должна была забыть про мой массив и каждое последующее создание занимало бы столько же времени? |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.126 |