hi guy:
i want to use mams32 to create a linked queue,but there is some question in the program
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include masm32.inc
includelib kernel32.lib
includelib user32.lib
includelib masm32.lib
include \masm32\macros\macros.asm
QNode struct
NextPtr dd ?
UserData dd ?
QNode ends
Queue struct
frontPtr dd ?
rearPtr dd ?
Queue ends
InitQueue proto :DWORD
enQueue proto :DWORD,:DWORD
deQueue proto :DWORD,:DWORD
IsQueueEmpty proto :DWORD
ClearQueue proto :DWORD
.const
.data
.data?
hHeap dd ?
lQueue dd ?
lpBuffer dd ?
.code
start:
invoke InitQueue,addr lQueue
invoke enQueue,addr lQueue,CTXT("abcdefg")
invoke enQueue,addr lQueue,CTXT("ccccccc")
invoke enQueue,addr lQueue,CTXT("dddddddddd")
invoke enQueue,addr lQueue,CTXT("adfasdfasdfasd")
.while TRUE
invoke IsQueueEmpty,lQueue
.break .if(eax==1)
invoke deQueue,addr lQueue,addr lpBuffer
invoke StdOut,lpBuffer
invoke StdOut,CTXT(0DH,0AH)
.endw
invoke StdOut,CTXT("OK!!",0dh,0ah)
invoke ClearQueue,addr lQueue
invoke ExitProcess,0
InitQueue proc lq:DWORD
invoke HeapCreate,0,0,0
; .if eax==NULL
; invoke StdOut,CTXT("Heap Create Failed!!",0dh,0ah)
; mov eax,FALSE
; ret
; .endif
mov hHeap,eax
invoke HeapAlloc,hHeap,0,sizeof Queue
; .if eax==NULL
; invoke StdOut,CTXT("Alloc Mem Failed!!",0dh,0ah)
; mov eax,FALSE
; ret
; .endif
mov (Queue ptr [eax]).frontPtr,NULL
mov (Queue ptr [eax]).rearPtr,NULL
mov edx,lq
mov [edx],eax
ret
InitQueue endp
enQueue proc lq:DWORD,pdata:DWORD
LOCAL tmp:DWORD
invoke HeapAlloc,hHeap,0,sizeof QNode
mov (QNode ptr [eax]).NextPtr,NULL
push pdata
pop (QNode ptr [eax]).UserData
mov tmp,eax
;
mov eax,lq
mov edx,[eax]
mov ecx,(Queue ptr [edx]).rearPtr
.if ecx==NULL
mov eax,tmp
mov (Queue ptr [edx]).frontPtr,eax
mov (Queue ptr [edx]).rearPtr,eax
.else
mov eax,tmp
mov (QNode ptr [ecx]).NextPtr,eax
mov (Queue ptr [edx]).rearPtr,eax
.endif
xor eax,eax
ret
enQueue endp
deQueue proc uses esi edi ebx lq:DWORD,ppdata:DWORD
mov eax,lq
mov eax,[eax]
mov ecx,ppdata
mov esi,(Queue ptr [eax]).frontPtr
mov edx,(QNode ptr [esi]).UserData
mov [ecx],edx
mov edi,(Queue ptr [eax]).rearPtr
.if esi==edi
mov (Queue ptr [eax]).frontPtr,NULL
mov (Queue ptr [eax]).rearPtr,NULL
.else
push (QNode ptr [esi]).NextPtr
pop (Queue ptr [eax]).frontPtr
.endif
invoke HeapFree,hHeap,0,eax
xor eax,eax
ret
deQueue endp
IsQueueEmpty proc uses esi edi lq:DWORD
mov eax,lq
mov esi,(Queue ptr [eax]).frontPtr
mov edi,(Queue ptr [eax]).rearPtr
.if esi==NULL && edi==NULL
mov eax,1
.else
mov eax,0
.endif
ret
IsQueueEmpty endp
ClearQueue proc lq:DWORD
; mov eax,lq
mov ebx,[lq]
mov esi,(Queue ptr [ebx]).frontPtr
mov edi,(Queue ptr [ebx]).rearPtr
.if !(esi==NULL && edi==NULL)
.while esi!=NULL
mov eax,(QNode ptr [esi]).NextPtr
mov (Queue ptr [eax]).frontPtr,eax
invoke HeapFree,hHeap,0,esi
mov esi,(Queue ptr [ebx]).frontPtr
.endw
mov (Queue ptr [ebx]).rearPtr,NULL
.endif
invoke HeapFree,hHeap,0,eax
invoke HeapDestroy,hHeap
xor eax,eax
ret
ClearQueue endp
end start
sorry,my english is poor
One problem is here:
deQueue proc uses esi edi ebx lq:DWORD,ppdata:DWORD
mov eax,lq
; mov eax,[eax] ; <<<< check this
mov ecx,ppdata
mov esi,(Queue ptr [eax]).frontPtr
.if !esi
MsgBox 0, "Esi is zero", "Hi", MB_OK
exit
.endif
a simple way is to access structure members like this
mov eax,[esi].QNode.NextPtr
another way is to use ASSUME to tell the assembler that ESI is a pointer to a structure
it is probably cleaner, but also more likely to cause problems :P
your code is probably close to working :U
you just need a little syntax cleanup
i just got up - first cup of coffee - lol
maybe i will look it over again a little later
Dave, his ...
mov esi, (Queue ptr [eax]).frontPtr
... syntax works fine, but there is a bit too much dereferencing. Commenting out the mov eax, [eax] gets it running for a few loops, then bang again.
Quote from: jj2007 on May 24, 2011, 07:51:48 AM
One problem is here:
deQueue proc uses esi edi ebx lq:DWORD,ppdata:DWORD
mov eax,lq
; mov eax,[eax] ; <<<< check this
mov ecx,ppdata
mov esi,(Queue ptr [eax]).frontPtr
.if !esi
MsgBox 0, "Esi is zero", "Hi", MB_OK
exit
.endif
.thanks
.it does not work normally
the queue is a pointer to Queue struct
the lq is a pointer to the queue except in the function IsQueueEmpty
so can you give a complete code
ENEVIL,
i'm curious,...as you probably are aware, the C++ language has an implementation of a queue template class.
Are you trying to create something similar in assembly language,...or, is this just a simple queue ?
Years ago, I was reading through the book describing the C++ Standard Template Library (http://www.josuttis.com/libbook/) container types, and, the author mentions that each container class has a number of internal routines to order, check the integrity, and maintain a coherent memory structure for the data. The authors said that this was the most difficult part to get correct: the memory allocations, checking, and re-ordering of elements so that memory usage was efficient, and memory fragmentation didn't become cumbersome.
If you are just doing a simple implementation, this won't be an issue,...but, if you plan to add routines that will create a large data structure, memory fragmentation will adversly affect your program.
Here is a link to: Standard Template Library Programmer's Guide (http://www.sgi.com/tech/stl/index.html),...it might give you some ideas (then again, it might just confuse you).
Quoteinclude masm32rt.inc
.686p
NODE struct
pNext PVOID ?
pPrev PVOID ?
pData PVOID ?
NODE ends
PNODE typedef ptr NODE
QUEUE struct
nNodes DWORD ?
pFirst PNODE ?
pLast PNODE ?
dwUserData1 DWORD ?
QUEUE ends
PQUEUE typedef ptr QUEUE
.code
CreateQueue proc ppQueue: ptr PQUEUE , dwUserData:DWORD
mov eax,alloc(SIZEOF QUEUE)
mov edx,ppQueue
mov PQUEUE ptr [edx],eax
m2m [eax].QUEUE.dwUserData1,dwUserData
ret
CreateQueue endp
QueueInsert proc pQueue:PQUEUE,pData:PVOID
mov edx,alloc(SIZEOF NODE)
m2m [edx].NODE.pData,pData
mov eax,pQueue
.if [eax].QUEUE.nNodes
inc [eax].QUEUE.nNodes
mov ecx,[eax].QUEUE.pFirst
mov [eax].QUEUE.pFirst,edx
mov [edx].NODE.pNext,ecx
mov [ecx].NODE.pPrev,edx
m2m [edx].NODE.pData,pData
.else
mov [eax].QUEUE.nNodes,1
mov [eax].QUEUE.pFirst,edx
mov [eax].QUEUE.pLast,edx
m2m [edx].NODE.pData,pData
.endif
ret
QueueInsert endp
QueueGet proc uses ebx edi pQueue:PQUEUE
mov ebx,pQueue
.if [ebx].QUEUE.nNodes
mov edi,[ebx].QUEUE.pLast
m2m [ebx].QUEUE.pLast,[edi].NODE.pPrev
mov edi,[edi].NODE.pData
free edi
.if [ebx].QUEUE.nNodes == 1
mov [ebx].QUEUE.pFirst,0
mov [ebx].QUEUE.pLast,0
.endif
dec [ebx].QUEUE.nNodes
mov eax,edi
ret
.else
xor eax,eax
ret
.endif
ret
QueueGet endp
DestroyQueue proc uses esi edi pQueue:PQUEUE
mov eax,pQueue
mov esi,[eax].QUEUE.nNodes
mov edi,[eax].QUEUE.pFirst
.while esi
mov edx,edi
mov edi,[edi].NODE.pNext
free edx
dec esi
.endw
free pQueue
ret
DestroyQueue endp
main proc
LOCAL pQueue:PVOID
invoke CreateQueue,ADDR pQueue,0
fn QueueInsert,pQueue,"1"
fn QueueInsert,pQueue,"2"
fn QueueInsert,pQueue,"3"
fn QueueInsert,pQueue,"4"
.while 1
.if rv(QueueGet,pQueue)
print eax,13,10
.else
.break
.endif
.endw
invoke DestroyQueue,pQueue
inkey
exit
main endp
end main
qWord
Thank you
But i want to Create it by myself,could you help me to pick up the error
sorry my english is poor
Hi
»»» But i want to Create it by myself,could you help me to pick up the error
1. If you use «invoke InitQueue, addr lQueue»
then you dont need to use
«invoke enQueue, ADDR lQueue, CTXT("abcdefg")»
but only
«invoke enQueue, lQueue, CTXT("abcdefg")»
2. The same for other similar procs
3. there is another error elsewhere, try to find it
See
deQueue procedure. It seems it is not correct
Quote
enQueue proc lq:DWORD, pdata:DWORD
LOCAL tmp:DWORD
invoke HeapAlloc, hHeap, 0, sizeof QNode
mov (QNode ptr [eax]).NextPtr,NULL
push pdata
pop (QNode ptr [eax]).UserData
mov tmp,eax
;
mov edx, lq
mov ecx,(Queue ptr [edx]).rearPtr
.if ecx==NULL
mov eax, tmp
mov (Queue ptr [edx]).frontPtr,eax
mov (Queue ptr [edx]).rearPtr,eax
.else
mov eax,tmp
mov (QNode ptr [ecx]).NextPtr,eax
mov (Queue ptr [edx]).rearPtr,eax
.endif
ret
enQueue endp
enevil,
i read and i run your prog
and i didnt understand what you want to do
When you invoke enQueue... you want to build a structure
like this (you alloc 4 blocks of memory Addr1, Addr2, Addr3, Addr4):
Addr1: "abcdefg" pNext= Addr2
Addr2: "ccccccc" pNext= Addr3
Addr3: "dddddddddd" pNext= Addr4
Addr4: "adfasdfasdfasd" pNext= 0
a) Is this correct ?
If it is correct, after those 4 strings, we have
frontPtr = Addr1
rearPtr = Addr4
b) Is this correct ?
When we want to get the strings from the Queue
we need to do this:
pNext = frontPtr
(If pNext = 0 the Queue is empty)
...
pNext = NextPtr
frontPtr = pNext
If iam wrong, explain your algo, may be we can help you
This works but you need to see ClearQueue
include \masm32\include\masm32rt.inc
;.386
;.model flat,stdcall
;option casemap:none
;include \masm32\include\windows.inc
;include \masm32\include\kernel32.inc
;include \masm32\include\user32.inc
;include \masm32\include\masm32.inc
;includelib \masm32\lib\kernel32.lib
;includelib \masm32\lib\user32.lib
;includelib \masm32\lib\masm32.lib
;include \masm32\macros\macros.asm
QNode struct
NextPtr dd ?
UserData dd ?
QNode ends
Queue struct
frontPtr dd ?
rearPtr dd ?
Queue ends
InitQueue proto :DWORD
enQueue proto :DWORD,:DWORD
deQueue proto :DWORD,:DWORD
IsQueueEmpty proto :DWORD
ClearQueue proto :DWORD
.const
.data
.data?
hHeap dd ?
lQueue dd ?
lpBuffer dd ?
.code
start:
invoke InitQueue, addr lQueue
invoke enQueue, lQueue,CTXT("abcdefg")
invoke enQueue, lQueue,CTXT("ccccccc")
invoke enQueue, lQueue,CTXT("dddddddddd")
invoke enQueue, lQueue,CTXT("adfasdfasdfasd")
.while TRUE
invoke IsQueueEmpty, lQueue
cmp eax, 1
je short _end
invoke deQueue, lQueue, addr lpBuffer
invoke StdOut, lpBuffer
invoke StdOut,CTXT(0DH,0AH)
;inkey
.endw
_end:
invoke StdOut, CTXT("OK!!",0dh,0ah)
invoke ClearQueue, lQueue
inkey
invoke ExitProcess,0
;»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
InitQueue proc lq:DWORD
invoke HeapCreate,0,0,0
.if eax==NULL
invoke StdOut,CTXT("Heap Create Failed!!",0dh,0ah)
mov eax,FALSE
ret
.endif
mov hHeap,eax
invoke HeapAlloc,hHeap,0,sizeof Queue
.if eax==NULL
invoke StdOut,CTXT("Alloc Mem Failed!!",0dh,0ah)
mov eax,FALSE
ret
.endif
mov (Queue ptr [eax]).frontPtr,NULL
mov (Queue ptr [eax]).rearPtr,NULL
mov edx,lq
mov [edx],eax
ret
InitQueue endp
enQueue proc lq:DWORD, pdata:DWORD
invoke HeapAlloc, hHeap, 0, sizeof QNode
mov (QNode ptr [eax]).NextPtr,NULL
push pdata
pop (QNode ptr [eax]).UserData
mov ebx,eax
;
mov edx, lq
mov ecx,(Queue ptr [edx]).rearPtr
.if ecx==NULL
mov (Queue ptr [edx]).frontPtr,ebx
mov (Queue ptr [edx]).rearPtr,ebx
.else
mov (QNode ptr [ecx]).NextPtr,ebx
mov (Queue ptr [edx]).rearPtr,ebx
.endif
ret
enQueue endp
deQueue proc uses esi edi ebx lq:DWORD,ppdata:DWORD
mov eax,lq
mov ecx,ppdata
mov esi,(Queue ptr [eax]).frontPtr
;mov edi,(Queue ptr [eax]).rearPtr
;mov edx,(QNode ptr [esi]).UserData
;mov [ecx],edx
.if esi==0
;mov (Queue ptr [eax]).frontPtr,NULL
mov (Queue ptr [eax]).rearPtr,NULL
.else
mov edx,(QNode ptr [esi]).UserData
mov [ecx],edx
push (QNode ptr [esi]).NextPtr
pop (Queue ptr [eax]).frontPtr
.endif
invoke HeapFree, hHeap, 0, esi
ret
deQueue endp
IsQueueEmpty proc lq:DWORD
mov eax, lq
mov ecx,(Queue ptr [eax]).frontPtr
;mov edx,(Queue ptr [eax]).rearPtr
.if ecx==NULL ;&& edx==NULL
mov eax,1
.else
mov eax,0
.endif
ret
IsQueueEmpty endp
ClearQueue proc lq:DWORD
mov ebx, lq
mov esi,(Queue ptr [ebx]).frontPtr
mov edi,(Queue ptr [ebx]).rearPtr
.if !(esi==NULL && edi==NULL)
.while esi!=NULL
mov eax,(QNode ptr [esi]).NextPtr
mov (Queue ptr [eax]).frontPtr,eax
invoke HeapFree,hHeap,0,esi
mov esi,(Queue ptr [ebx]).frontPtr
.endw
mov (Queue ptr [ebx]).rearPtr,NULL
.endif
invoke HeapFree,hHeap,0,eax
invoke HeapDestroy,hHeap
xor eax,eax
ret
ClearQueue endp
end start
Replace ClearQueue by this:
ClearQueue proc lq:DWORD
mov ebx, lq
mov esi,(Queue ptr [ebx]).frontPtr
mov edi,(Queue ptr [ebx]).rearPtr
.if !(esi==NULL && edi==NULL)
.while esi!=NULL
mov eax, (QNode ptr [esi]).NextPtr
mov (Queue ptr [ebx]).frontPtr, eax
invoke HeapFree,hHeap,0,esi
mov esi,(Queue ptr [ebx]).frontPtr
.endw
.endif
invoke HeapFree, hHeap, 0, ebx
invoke HeapDestroy, hHeap
xor eax,eax
ret
ClearQueue endp