ich brauchte eine Art Vector-Class in MASM für das Handling von Struct-Arrays usw. ( allgemein ist es dann handlicher meiner Meinung nach ), also hab ich mich entschlossen eine Klasse zu schreiben bzw. eine ASM-Datei.
hier ist erstmal der code von Vector.asm:
Code:
;===================================;
;= Vector Class =;
;= Author: Ten$ion =;
;= Date: 01/30/2014 =;
;= Language: MASM =;
;===================================;
vPushBack proto :DWORD, :DWORD
vPopBack proto :DWORD
vGet proto :DWORD, :DWORD
vSet proto :DWORD, :DWORD, :DWORD
vInsert proto :DWORD, :DWORD, :DWORD
vRemove proto :DWORD, :DWORD
memcpy proto :DWORD, :DWORD, :DWORD
;==================;
;= String Macro =;
;==================;
_str macro x:VARARG
LOCAL txt
.data
txt db x,0
align 4
.code
exitm <addr txt>
endm
;===================;
;= ErrorBox Macro =;
;===================;
_error macro _text
pushad
invoke MessageBox, 0, _text, _str('Error'), MB_ICONERROR
popad
endm
.const
;Main struct
Vector struct
dwElementSize DWORD ? ; Size of the Element Type
dwSize DWORD ? ; Size of the Vector
dwCount DWORD ? ; Element Count of Vector
lpData DWORD ? ; Pointer to the Data from the Vector
Vector ends
;Allocates Memory
_alloc macro _size
invoke GetProcessHeap
invoke HeapAlloc, eax, HEAP_ZERO_MEMORY, _size
endm
;Frees Memory
_free macro _addr
invoke GetProcessHeap
invoke HeapFree, eax, 0, _addr
endm
.code
;Pushes an element into the vector
vPushBack proc lpVector:DWORD, lpData:DWORD
LOCAL oldbuf:DWORD, newbuf:DWORD
pushad
mov esi, lpVector
assume esi:ptr Vector
cmp [esi].dwCount, 0
je @FirstEntry
_alloc [esi].dwSize
mov oldbuf, eax
invoke memcpy, oldbuf, [esi].lpData, [esi].dwSize
mov ebx, [esi].dwSize
add ebx, [esi].dwElementSize
_alloc ebx
mov newbuf, eax
invoke memcpy, newbuf, [esi].lpData, [esi].dwSize
mov edx, [esi].dwSize
add edx, newbuf
invoke memcpy, edx, addr lpData, [esi].dwElementSize
push newbuf
pop [esi].lpData
inc [esi].dwCount
mov ebx, [esi].dwSize
add ebx, [esi].dwElementSize
mov [esi].dwSize, ebx
_free oldbuf
jmp @Done
@FirstEntry:
_alloc [esi].dwElementSize
mov [esi].lpData, eax
push [esi].dwElementSize
pop [esi].dwSize
inc [esi].dwCount
invoke memcpy, [esi].lpData, addr lpData, [esi].dwElementSize
@Done:
assume esi:ptr NOTHING
popad
ret
vPushBack endp
;Pops an element from the vector
vPopBack proc lpVector:DWORD
LOCAL newbuf:DWORD
mov esi, lpVector
assume esi:ptr Vector
mov edi, [esi].lpData
mov ebx, [esi].dwSize
cmp ebx, 0
je @IsZero
sub ebx, [esi].dwElementSize
_alloc ebx
mov newbuf, eax
invoke memcpy, newbuf, [esi].lpData, ebx
_free [esi].lpData
push newbuf
pop [esi].lpData
dec [esi].dwCount
mov ebx, [esi].dwElementSize
sub [esi].dwSize, ebx
jmp @Done
@IsZero:
_error _str('Cannot popback, the vector is empty.')
@Done:
assume esi:ptr NOTHING
ret
vPopBack endp
;Returns an element from the given index
vGet proc lpVector:DWORD, lpPos:DWORD
LOCAL data:DWORD
mov esi, lpVector
assume esi:ptr Vector
mov ebx, lpPos
mov ecx, [esi].dwCount
dec ecx
cmp ebx, ecx
jg @IsBigger
imul ebx, [esi].dwElementSize
lea edx, [esi].lpData
add [edx], ebx
invoke memcpy,addr data, [edx], [esi].dwElementSize
mov eax, data
jmp @Done
@IsBigger:
_error _str('Position out of Range')
@Done:
assume esi:ptr NOTHING
ret
vGet endp
;Sets an element from the given index and data
vSet proc lpVector:DWORD, lpPos:DWORD, lpData:DWORD
mov esi, lpVector
assume esi:ptr Vector
mov ebx, lpPos
mov ecx, [esi].dwCount
dec ecx
cmp ebx, ecx
jg @IsBigger
imul ebx, [esi].dwElementSize
lea edx, [esi].lpData
add [edx], ebx
invoke memcpy,[edx],addr lpData, [esi].dwElementSize
jmp @Done
@IsBigger:
_error _str('Position out of Range')
@Done:
assume esi:ptr NOTHING
ret
vSet endp
;Inserts an element into the Vector
vInsert proc lpVector:DWORD, lpPos:DWORD, lpData:DWORD
LOCAL newbuf:DWORD, firstsize:DWORD
mov esi, lpVector
assume esi:ptr Vector
mov ebx, lpPos
mov ecx, [esi].dwCount
dec ecx
cmp ebx, ecx
jg @IsBigger
cmp lpPos, 0
je @IsZero
mov ebx, [esi].dwSize
add ebx, [esi].dwElementSize
_alloc ebx
mov newbuf, eax
mov ebx, lpPos
imul ebx, [esi].dwElementSize
mov firstsize, ebx
invoke memcpy, newbuf, [esi].lpData, firstsize
mov edi, newbuf
add edi, [esi].dwElementSize
invoke memcpy, edi, addr lpData, [esi].dwElementSize
mov ebx, [esi].dwCount
sub ebx, lpPos
imul ebx, [esi].dwElementSize
mov edi, newbuf
add edi, firstsize
add edi, [esi].dwElementSize
mov edx, [esi].lpData
add edx, firstsize
invoke memcpy, edi, edx, ebx
inc [esi].dwCount
mov ebx, [esi].dwElementSize
add [esi].dwSize, ebx
_free [esi].lpData
push newbuf
pop [esi].lpData
jmp @Done
@IsZero:
mov ebx, [esi].dwSize
add ebx, [esi].dwElementSize
_alloc ebx
mov newbuf, eax
invoke memcpy, newbuf, addr lpData, [esi].dwElementSize
mov ebx, [esi].dwCount
imul ebx, [esi].dwElementSize
mov edi, newbuf
add edi, [esi].dwElementSize
mov edx, [esi].lpData
invoke memcpy, edi, edx, ebx
inc [esi].dwCount
mov ebx, [esi].dwElementSize
add [esi].dwSize, ebx
_free [esi].lpData
push newbuf
pop [esi].lpData
jmp @Done
@IsBigger:
_error _str('Position out of Range')
@Done:
assume esi:ptr NOTHING
ret
vInsert endp
;Removes an element from the Vector
vRemove proc lpVector:DWORD, lpPos:DWORD
LOCAL newbuf:DWORD, firstsize:DWORD
mov esi, lpVector
assume esi:ptr Vector
mov ebx, lpPos
mov ecx, [esi].dwCount
dec ecx
cmp ebx, ecx
jg @IsBigger
mov ebx, [esi].dwSize
sub ebx, [esi].dwElementSize
_alloc ebx
mov newbuf, eax
mov ebx, lpPos
imul ebx, [esi].dwElementSize
mov firstsize, ebx
invoke memcpy, newbuf, [esi].lpData, firstsize
mov ebx, [esi].dwCount
sub ebx, lpPos
dec ebx
imul ebx, [esi].dwElementSize
mov edi, newbuf
add edi, firstsize
mov edx, [esi].lpData
add edx, firstsize
add edx, [esi].dwElementSize
invoke memcpy, edi, edx, ebx
inc [esi].dwCount
mov ebx, [esi].dwElementSize
add [esi].dwSize, ebx
_free [esi].lpData
push newbuf
pop [esi].lpData
jmp @Done
@IsBigger:
_error _str('Position out of Range')
@Done:
assume esi:ptr Nothing
ret
vRemove endp
;Clears the Vector
vClear proc lpVector:DWORD
mov esi, lpVector
assume esi:ptr Vector
mov [esi].dwSize, 0
mov [esi].dwCount, 0
_free [esi].lpData
mov [esi].lpData, 0
assume esi:ptr NOTHING
ret
vClear endp
;Copies memory
memcpy proc output:DWORD, input:DWORD, len:DWORD
pushad
mov esi, input
mov edi, output
mov ecx, len
rep movsb
popad
ret
memcpy endp
Und hier noch ein Beispiel zur Anwendung:
Code:
.386
.model flat,stdcall
option casemap:none
include windows.inc
include msvcrt.inc
include kernel32.inc
include user32.inc
include masm32.inc
includelib msvcrt.lib
includelib kernel32.lib
includelib user32.lib
includelib masm32.lib
include Vector.asm
.const
.data?
.data
szBuffer db MAX_PATH dup(0)
Vec Vector <4,0,0,0>
.code
start:
invoke vPushBack, addr Vec, _str('Hallo wie gets?')
invoke vPushBack, addr Vec, _str('Halloie gehts?')
invoke vPushBack, addr Vec, _str('Hallo wiehts?')
invoke vPushBack, addr Vec, _str('He gehts?')
invoke vPushBack, addr Vec, _str('Hallo wie ts?')
invoke vInsert, addr Vec, 0, _str('123546')
invoke vGet, addr Vec, 0
invoke vClear, addr Vec
invoke vPushBack, addr Vec, _str('123123123123123123123123123')
invoke vGet, addr Vec, 0
mov esi, eax
invoke wsprintf, addr szBuffer, _str('%s'), esi
invoke MessageBox,0, addr szBuffer,0,0
invoke ExitProcess, 0
end start
Wieso man bei Strings die größe 4 benutzt ist einfach: Man pusht die Adresse des Strings in den Vector nicht den String selbst und die Adresse ist immer ein DWORD also 4 Bytes groß.
Vielleicht könnt ihr ja damit auch was anfangen.
MfG,
Ten$ion






