顺序队列的汇编实现
这是汇编顺序队列的实现,在写这个程序时,可能由于思路的问题,C++版本的翻译过来后,竟然没有任何输出,浪费了我整整一天的时间.也是由于我看的那本书中把顺序队列搞复杂化了,后来再查找了几本书,终于重写了C++版本以及汇编版本,这样一来思路就非常清晰多了.下面就是源代码,一共也只有两个文件:AQueue.inc和AQueue.asm,其中前者用于声明一个结构体,它表示一个队列数据结构,而后者实现了该算法.

AQueue.inc文件:
;////////////////////////////////////////////////////////////
;AQueue.inc文件:用于定义一个结构体,它保存一个顺序队列的内容.
;它有五个成员,其中dwFirst和dwLast是用于指向队列头以及尾的索引
;值,pdwListArray用于保存队列中元素的值,而dwSize是表示内存大小
;,即可以容纳的最多元素个数,另一个dwCount用于表示任何时刻在队
;列中的元素个数.
;////////////////////////////////////////////////////////////
AQueue struct
dwSize dword ? ;最多可以容纳的元素个数.
dwFirst dword ? ;队列头元素索引.
dwLast dword ? ;队列尾元素索引.
dwCount dword ? ;当前队列中的元素个数.
pdwListArray dword NULL ;保存队列的内存空间.
AQueue ends
AQueue.asm文件:
;////////////////////////////////////////////////////////////
;队列数据结构的汇编版本.其思路是:起先使dwFirst和dwLast相等,而且
;dwCount等于0,说明了是一个空表.而且我们保证在插入一个数据之后
;dwLast始终指向刚插入的数据的索引号加一,也就是说dwLast索引表示
;的队列中是没有值的.所以新插入的值要在dwLast位置,而插入完成后
;使dwLast+1,而且也要使dwCount加一.而删除一个元素则要先返回dwFirst
;索引的元素的值,再使dwFirst加一,而且使dwCount减一.那么这样一来,
;dwFirst==dwLast时不仅可以表示队列已满,也可以表示队列已空,那么
;我们怎么区分这两种情况呢?那就使用dwCount的值,如果该值为0,表示
;队列空,而该值为dwSize,那么表示队列已满.而dwCount始终表示当前
;队列中的元素个数.下面是源代码:
;////////////////////////////////////////////////////////////
.386
.model flat,stdcall
option casemap :none
include windows.inc
include irvine32.inc
include AQueue.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.data
stAQueue AQueue <>
.code
;////////////////////////////////////////////////////////////
;用于初始化一个队列.
;////////////////////////////////////////////////////////////
Init proc dwLen:dword
mov stAQueue.dwCount,0
mov stAQueue.dwFirst,0
mov stAQueue.dwLast,0 ;三个值都为0
mov eax,dwLen
mov stAQueue.dwSize,eax ;队列大小.
shl eax,2 ;乘以四.
invoke GlobalAlloc,GPTR,eax ;分配内存.
mov stAQueue.pdwListArray,eax ;初始化队列指针.
ret ;返回内存地址.
Init endp
;////////////////////////////////////////////////////////////
;用于释放队列所占的内存空间.
;////////////////////////////////////////////////////////////
Free proc
mov eax,stAQueue.pdwListArray
or eax,eax
je quit
invoke GlobalFree,eax ;释放内存空间.
mov stAQueue.pdwListArray,NULL
quit:
ret
Free endp
;////////////////////////////////////////////////////////////
;清除队列并重建一个队列.
;////////////////////////////////////////////////////////////
Clear proc
call Free ;释放内存.
invoke Init,20 ;最从可以有20个元素.
ret
Clear endp
;////////////////////////////////////////////////////////////
;从队列尾部插入的一个元素.
;////////////////////////////////////////////////////////////
AddValue proc uses ebx edx dwVal:dword
mov eax,stAQueue.dwCount
cmp eax,stAQueue.dwSize
jne next
xor eax,eax
ret ;如果队列已满,那么返回false.
next:
mov eax,stAQueue.dwLast
shl eax,2
mov ebx,stAQueue.pdwListArray
push dwVal
pop dword ptr[ebx+eax] ;将数值插入到队列中.
shr eax,2
inc eax
xor edx,edx
div stAQueue.dwSize
mov stAQueue.dwLast,edx ;stAQueue.dwLast=(stAQueue.dwLast+1)%stAQueue.dwSize
inc stAQueue.dwCount ;元素个数加一.
or eax,1 ;返回true.
ret
AddValue endp
;////////////////////////////////////////////////////////////
;从队列头部删除一个元素.
;////////////////////////////////////////////////////////////
DelValue proc uses ebx edx pdwVal:ptr dword
mov eax,stAQueue.dwCount
or eax,eax
jne next
ret ;如果队列为空,返回false.
next:
mov edx,pdwVal
mov ebx,stAQueue.pdwListArray
mov eax,stAQueue.dwFirst
shl eax,2
push dword ptr[ebx+eax]
pop dword ptr[edx] ;返回要删除的值.
shr eax,2
inc eax
xor edx,edx
div stAQueue.dwSize
mov stAQueue.dwFirst,edx ;重新修改dwFirst索引.
dec stAQueue.dwCount ;元素个数减一.
ret
DelValue endp
;////////////////////////////////////////////////////////////
;得到头索引位置的元素值.
;////////////////////////////////////////////////////////////
GetValue proc uses ebx edx pdwVal:ptr dword
mov eax,stAQueue.dwCount
or eax,eax
jne next
ret ;如果队列为空,那么返回false.
next:
mov eax,stAQueue.dwFirst
shl eax,2
mov ebx,stAQueue.pdwListArray
mov edx,pdwVal
push dword ptr[ebx+eax]
pop dword ptr[edx] ;返回头索引元素值.
or eax,1 ;返回true.
ret
GetValue endp
;////////////////////////////////////////////////////////////
;得到当前队列中的元素个数.
;////////////////////////////////////////////////////////////
QueueLength proc
mov eax,stAQueue.dwCount ;当前元素个数.
ret
QueueLength endp
;////////////////////////////////////////////////////////////
;测试上面的队列数据结构.
;////////////////////////////////////////////////////////////
main proc
local dwTemp:dword
call Clear ;清除并初始化一个队列.
invoke AddValue,1
invoke AddValue,2
invoke AddValue,3 ;插入三个数值.
call QueueLength
mov ecx,eax ;返回元素个数.
temp1:
push ecx
invoke DelValue,addr dwTemp ;删除一个元素并输出.
mov eax,dwTemp
call WriteDec
mov al,' '
call WriteChar
pop ecx
loop temp1
call Crlf
call Clear ;再一次清除并初始化一个队列.
invoke AddValue,1
invoke AddValue,2
invoke AddValue,3
invoke AddValue,4 ;再次插入四个元素.
call QueueLength
mov ecx,eax
temp2:
push ecx
invoke GetValue,addr dwTemp
mov eax,dwTemp
call WriteDec
mov al,' '
call WriteChar
invoke DelValue,addr dwTemp
mov eax,dwTemp
call WriteDec
mov al,' '
call WriteChar
pop ecx
loop temp2
call Crlf
call Free ;清除一个队列所占用的内存空间.
invoke ExitProcess,NULL
main endp
end main
其实出现错误后,我试图重写了汇编代码,不过也还是没有任何输出,我调试的时候发现我写的那些过程都可以正常工作,而且也得到的最后的答案,但就是不能输出,我简直怀疑库函数因为我的代码中的错误而进入了错误状态而没有任何输出.后来不得不重新修改思路,不过这种算法真的是非常简单.输出结果与C++版的完全相同.
本文来源 我爱IT技术网 http://www.52ij.com/jishu/1743.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
