在做一个关于电梯的proteus的课设中遇到的这样一个问题,如果同时按下多个键如何判断运行的次序:所以单独写了一个程序,来仿真:
这里模拟的是比较简单的情况,分为三种情况:
①当前楼层低于所有目标楼层
②当前楼层高于所有目标楼层
③当前楼层在目标楼层之间
其实还有一种情况没有输入目标楼层,这里没有加入这种情况,但是实际仿真时要考虑。
这里分了两级优先级,向上优先于向上,越靠近当前楼层的越优先到达。这里讨论的最简单的情况即在电梯内按键,没有考虑外面的人按键的情况。
分别讨论三种情况:
首先要对输入楼层进行排序,有大到小
比如输入楼层为:
输入楼层 | 目标楼层 | 输出结果 |
---|---|---|
7 3 2 | 1 | 7 3 2 |
7 3 2 | 4 | 2 3 7 |
7 3 1 | 2 | 1 7 3 |
7 3 1 | 8 | 1 3 7 |
将最先到达的楼层放在后面方便在实际运行时到达后消除这个值。
分为两种情况小于目标楼层的部分压栈后再出栈输出到结果中,大于等于目标楼层的部分直接正序放在结果中。
这里还对只有一个输入的情况单独讨论了。
代码中的seq表示目标楼层,num表示目标楼层的数目,current_floor表示当前楼层,ordered存放排序后的结果。
DATAS SEGMENT
;此处输入数据段代码
seq db 01h,02h,05h
num db $-seq
ordered db 3 dup(?)
current_floor db 03h
buf1 db 0ah,'Added array is:',0dh,0ah,'$'
buf2 db 0ah,'The sorted array is:',0dh,0ah,'$'
buf3 db 0ah,'num=',0dh,0ah,'$'
buf4 db 0ah,'ordered',0dh,0ah,'$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
dw 50 dup(?)
top label byte
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
mov ax,stacks
mov ss,ax
mov sp,offset top
MOV AX,DATAS
MOV DS,AX
;显示内存中所有数据
mov cl,num
mov ch,00h
lea bx,seq
cmp cx,01h
je one
jmp Loop_first
One:
lea si,seq
lea di,ordered
mov al,[si]
mov [di],al
jmp ordered_end
Loop_first:
mov al,[bx]
call show_low
call kong_ge
inc bx
loop loop_first
mov dx,offset buf1
mov ah,9h
int 21h
lea bx,seq
mov cl,num
mov ch,00h
LOOP_show1:
mov al,[bx]
call show_low
call kong_ge
inc bx
loop loop_show1
;-----------------------------------
;冒泡排序部分
mov cl,num;cx为比较轮数,大循环次数
mov ch,00h
dec cx
;-----------------------------------------
;显示num中的数据
mov dx,offset buf3
mov ah,9h
int 21h
mov al,num;num为什么会变成了7
call show_low
Loop_sort1:
mov dx,cx;dx表示大循环次数
mov bx,0;地址指针
Loop_sort2:
mov al,seq[bx]
cmp al,seq[bx+1]
jae no_change
xchg al,seq[bx+1]
mov seq[bx],al;在这里相当于溢出多给num了值
no_change:
inc bx
loop loop_sort2
mov cx,dx;一轮比完之后,cx再次赋值比较轮数
loop loop_sort1
;提示语
mov dx,offset buf2
mov ah,9h
int 21h
lea bx,seq
mov cl,num
mov ch,00h
LOOP_show2:
mov al,[bx]
call show_low
call kong_ge
inc bx
loop loop_show2
;-----------------------------------------
;显示num中的数据
mov dx,offset buf3
mov ah,9h
int 21h
mov al,num;num为什么会变成了7
call show_low
Modify:
;先遍历找到当前元素在第几位
;类似于压栈
mov al,current_floor
lea di,seq
lea si,ordered
mov cl,num
mov ch,00h
mov bh,00h
Loop_modify:
cmp al,[di]
ja big;小于al的数压栈,大于al的数不管
modify_back:
inc di
loop loop_modify
jmp move
big:
push [di]
inc bh
jmp modify_back
move:
mov cl,num
sub cl,bh;得到不需要出栈的数的个数
cmp bh,00h;判断是否栈中有数据
ja pop_loop
jmp normal
pop_loop:;首先需要出栈
pop [si]
inc si
dec bh
cmp bh,00h
ja pop_loop
normal:;直接正序赋值
mov bx,00h
cmp cl,00h
ja normal_loop
jmp ordered_end
normal_loop:
mov al,seq[bx]
mov [si],al
inc si
inc bx
loop normal_loop
;--------------------------------
;显示
ordered_end:
mov dx,offset buf4
mov ah,9h
int 21h
lea bx,ordered
mov cl,num
mov ch,00h
LOOP_show3:
mov al,[bx]
call show_low
call kong_ge
inc bx
loop loop_show3
jmp end_pro
show_low proc near
mov dl,'0'
add dl,al
mov ah,02h
int 21h
ret
show_low endp
kong_ge proc near
mov dl,' '
mov ah,02h
int 21h
ret
kong_ge endp
end_pro:
MOV AH,4CH
INT 21H
CODES ENDS
END START
上图的结果为:
最后一行即是结果。
推荐一篇文章比较详细的介绍了电梯调度的算法:https://mp.weixin.qq.com/s/yAcmwIKsCadj5CH_91aWXw