· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Указатель на массив

Посл.отвђт Сообщен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 используется..
    LOCAL Arr[20] :DWORD не помогло...
В вашем случае массив создавать в стеке любой из 2 ф-ций нельзя - при выходе из них он будет затёрт (со временем).
К тому же, большие массивы создавать на стеке не так просто - по-хорошему, без 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