首页
社区
课程
招聘
[旧帖] [原创]汇编语言实现队列 0.00雪花
发表于: 2010-11-5 13:55 1481

[旧帖] [原创]汇编语言实现队列 0.00雪花

2010-11-5 13:55
1481
队列是一种遵循先进先出(FIFO,First In ,First Out)原则的线性表。该线性表的末尾,叫做队列的队尾(Rear),允许插入元素;该线性表的头端,叫做队列的队头(Front)。对队列的基本操作只有入队(enqueue)和出队(dequeue)两种。
        在队尾插入一个元素,叫做入队。在队头删除一个元素并返回该元素,叫做出队。
源代码(编译器MASM10)
源代码Queue.asm:
.
.386
.model         flat,stdcall
option         casemap:none
include         windows.inc
include         user32.inc
includelib         user32.lib
include         kernel32.inc
includelib                 kernel32.lib
.data
QueueA        dword        5        dup(0)        ;初始化队列               
szCaption         db         '消息框!',0
szText         db         100         dup(0)
szCharsFormat         db         '第%d出队:%d',0
front        dword        0        ;队头
rear        dword        0        ;队尾
.code
;-----------------------------------------------------------------
start:
mov                eax,rear
mov                QueueA[eax*4],1                ;入队
inc                rear
mov                eax,rear
mov                QueueA[eax*4],2
inc                rear
mov                eax,rear
mov                QueueA[eax*4],3
inc                rear
mov                eax,rear
mov                QueueA[eax*4],5
inc                rear
mov                eax,rear
mov                QueueA[eax*4],7
inc                rear
;出队
mov                ecx,5
L1:
mov                ebx,front
mov                eax,QueueA[ebx*4]
push         ecx
invoke        wsprintf,addr         szText, addr         szCharsFormat, front,eax
invoke         MessageBox,NULL,offset         szText,offset         szCaption,MB_OK
pop                ecx
inc                 front
loop                L1

invoke         ExitProcess,NULL
end         start

MakeFile:
NAME=Queue
OBJS=$(NAME).obj
LINK_FLAG=/subsystem:windows
ML_FLAG=/c /coff
$(NAME).exe:$(OBJS)
        Link        $(LINK_FLAG) $(OBJS)
.asm.obj:
ml        $(ML_FLAG) $<
clean:
        del        *.obj

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 15
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
在前面的介绍队列的小节中源代码,并不优美,极易上溢或下溢。队尾指针超越了队列空间的上界(即队满)而不能做入队操作,称之为上溢。队头指针小于了队列空间的下界(即队空)而不能做出队操作,称之为下溢。
        为了防止队列的上溢、下溢,统计队列的元素总数以及队列的大小,我们可以定义如下结构:
        Queue                strcut
        front                dword                0
        rear                dword                0
        count                dword                0
        queueSize                dword        5
        element                        dword        5 dup(0)
        Queue                ends
       
源代码
源代码Queue2.asm:
.
.386
.model         flat,stdcall
option         casemap:none
include         windows.inc
include         user32.inc
includelib         user32.lib
include         kernel32.inc
includelib                 kernel32.lib
include                queue.inc
.data
QueueA                queue<>        ;声明队列结构的变量       
szCaption                 db                 '消息框!',0
szText         db         100         dup(0)
szCharsFormat         db         '第%d出队:%d',0
.code
;-----------------------------------------------------------------
;置空队
InitQueue                 proc                 uses         esi        q:ptr                 queue
        mov                esi,q
        mov                (queue         ptr         [esi]).front,0
        mov                (queue         ptr         [esi]).rear,0
        mov                (queue        ptr         [esi]).count,0       
        ret
InitQueue                endp

;判队空,队空返回1,队非空返回0
QueueEmpty  proc                 uses         esi        q:ptr                 queue
        mov                esi,q
        mov                eax,(queue        ptr         [esi]).count
        cmp                eax,0
        jg                LE1
        mov                eax,1
        jmp                LE2
LE1:
        mov                 eax,0
        jmp                LE2
LE2:
        ret
       
QueueEmpty        endp

;判队满,队满返回1,队未满返回0
QueueFull         proc                 uses         esi        q:ptr                 queue
        mov                esi,q
        mov                eax,(queue         ptr         [esi]).count
        cmp                eax,(queue         ptr                 [esi]).queueSize
        jl                LF1
        mov                eax,1
        jmp                LF2
LF1:
        mov                 eax,0
        jmp                LF2
LF2:
        ret
QueueFull                endp

;入队 ,队满返回-1,入队成功返回1
EnQueue         proc                 uses                 esi ebx        q:ptr                 queue,newElement:dword
        mov                esi,q
        ;队满上溢
        invoke                QueueFull,esi
        cmp                eax,1
        je                L1
        ;队列元素个数加1
        inc                 (queue                 ptr                 [esi]).count
        ;新元素插入到队尾
        mov                eax,newElement
        mov                ebx,(queue         ptr                 [esi]).rear
        mov                (queue         ptr                 [esi]).element[ebx*4],eax
        ;将队尾指针加1
        inc                (queue         ptr         [esi]).rear
        mov                eax,1
        jmp                L2
       
L1:
        mov                eax,-1
        jmp                L2
L2:
        ret
EnQueue                endp

;出队,队空则返回-1,出队成功返回元素
DeQueue                 proc                 uses         esi         ebx        q:ptr                 queue
        mov                esi,q
        invoke                QueueEmpty,q
        ;队空下溢
        cmp                eax,1
        je                LD1       
        ;取队头元素
        mov                ebx,(queue         ptr         [esi]).front
        mov                eax,(queue         ptr         [esi]).element[ebx*4]       
        ;队列元素个数减1
        dec                 (queue         ptr         [esi]).count
        ;将队头指针加1
        inc                (queue         ptr         [esi]).front
        jmp                LD2
       
LD1:
        mov                eax,-1
        jmp                LD2
LD2:
        ret
       
DeQueue                endp
start:
;入队
invoke                 EnQueue,addr                 QueueA,1
cmp                eax,-1
je                LM2
invoke                EnQueue,addr                 QueueA,2
invoke                EnQueue,addr                 QueueA,3
invoke                EnQueue,addr                 QueueA,5
invoke                EnQueue,addr                 QueueA,7

;出队
mov                ecx,5
LM1:
invoke                DeQueue,addr                 QueueA
push         ecx
invoke        wsprintf,addr                 szText, addr                 szCharsFormat, QueueA.front,eax
invoke         MessageBox,NULL,offset         szText,offset         szCaption,MB_OK
pop                ecx
loop                LM1

invoke                 ExitProcess,NULL
LM2:
end                 start

MakeFile:
NAME=Queue2
OBJS=$(NAME).obj
LINK_FLAG=/subsystem:windows
ML_FLAG=/c /coff
$(NAME).exe:$(OBJS)
        Link        $(LINK_FLAG) $(OBJS)
.asm.obj:
ml        $(ML_FLAG) $<
clean:
        del        *.obj
       
定义队列结构的文件如下:
queue.inc
queue                struct
        front                dword                0
        rear                dword                0
        count                dword                0
        queueSize                dword        5
        element                        dword        5         dup(0)
queue                ends

笔者实测发现,过程EnQueue内部声明了标号L1,L2,则过程QueueFull内部不能声明一样的L1,L2,因为EnQueue调用了QueueFull。对于没有嵌用关系的过程,则其标号可以一样。此处的标号指的是标号名加冒号的格式。
2010-11-5 13:58
0
雪    币: 109
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
好文啊,顶上去
2010-11-5 20:36
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
数据结构还没看熟。。。
2010-11-5 21:51
0
雪    币: 32
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
等我学会了我在发表我的意见先收藏
2010-11-8 23:41
0
雪    币: 28
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习一下了 这个不错
2010-11-9 03:14
0
游客
登录 | 注册 方可回帖
返回
//