我是汇编的新手,我正在尝试编写一个程序,它获取五个用户输入的数字,将它们存储在变量num1-num5中,对它们进行排序(不使用数组),其中num5具有最大值,num1具有最低值,然后显示已排序的数字。我无法弄清楚如何处理这个问题。我得到了5个数字并将它们存储在变量中,但我对如何开始排序感到困惑。我尝试了一些东西,但我一直在收到错误。这是我的代码,我实际上可以运行,但它没有按照我想要的方式工作。
TITLE MASM Template (main.asm)
INCLUDE Irvine32.inc
.data
getnumber byte "Please enter a number between 0 and 20",0ah,0dh,0
num1 byte 0
num2 byte 0
num3 byte 0
num4 byte 0
num5 byte 0
.code
main PROC
call Clrscr
;************* get the information from the user*******************
mov edx, offset getnumber ;ask to input number
call writestring
call readint
mov bl, al
mov num1, bl ;get the number and move to num1 variable
mov edx, offset getnumber ;ask to input number
call writestring
call readint
mov bl, al
mov num2, bl ;get the number and move to num2 variable
mov edx, offset getnumber ;ask to input number
call writestring
call readint
mov bl, al
mov num3, bl ;get the number and move to num3 variable
mov edx, offset getnumber ;ask to input number
call writestring
call readint
mov bl,al
mov num4, bl ;get the number and move to num4 variable
mov edx, offset getnumber ;ask to input number
call writestring
call readint
mov bl, al
mov num5, bl ;get the number and move to num5 variable
;***show the user inputed numbers****
mov al, num1
call writeint
mov al, num2
call writeint
mov al,num3
call writeint
mov al, num4
call writeint
mov al,num5
call writeint
;*****start comparing***
cmp bl,num5
jl jumptoisless
jg jumptoisgreater
jumptoisless:
call writeint
jumptoisgreater:
mov bl, num5
mov dl, num4
mov num5, dl
mov num4, bl
call writeint
jmp imdone
imdone:
call dumpregs
exit
main ENDP
END main
答案 0 :(得分:2)
您的代码的一些注释:
call readint
mov bl, al
mov num2, bl
为什么不直接将al
存储到内存中,如:mov [num2],al
?无论如何,你都不会使用bl
。
除此之外:
;*****start comparing***
cmp bl,num5
jl jumptoisless
jg jumptoisgreater
我担心call writeint
ebx
对call writeint
做了什么(或者你做了功课,并且从头部知道ebx
保留ebx
内容?)。< / p>
如果bl
被保留,那么num5
仍然包含来自输入的jumptoisless:
,所以它将是相等的。
有趣的是,如果相同,您将继续al
部分代码,这将在jumptoisgreater:
中输出一些剩余部分,然后它将继续jl
部分代码,因此有效地执行所有这些。
您可以在调试器中观看CPU一段时间,同时单步执行指令,以更好地了解它的工作原理吗?它是一台状态机,即。根据寄存器中的当前值和内存的内容,它将以确定的方式改变寄存器和存储器的状态。
因此,除非您跳开,否则在当前指令之后执行下一条指令,jg
+ cmp
不会覆盖&#34;等于&#34;状态(至少你只做jcc
一次,所以希望你理解cmp
指令不会改变标志,并且jl / jg都会在标志中cmp
的相同结果上运行)。汇编程序并不关心你的标签名称,它也不会警告你#34; isgreater&#34;代码即使在&#34;无法执行时也会被执行。先被执行了。
关于如何解决您的任务:
除非你开始使用num1-num5内存作为数组,否则不能想到任何合理的短路,所以你可以用索引的通用指针方式来解决它。所以我很乐意让你自己尝试,只需提醒你至少需要n * log_n比较排序n值,所以如果你要编写非常有效的排序代码,你需要至少5 * 3 = 15 {{1指令(log 2 (5)= 3,因为2 3 = 8)。
另一方面,在两个循环中使用单个cmp
可以在数组上进行无效(但易于编写和理解)冒泡排序。
rcgldr让我很好奇,所以我一直在尝试一些事情......
使用插入排序,它只能使用8x(最多)cmp
(我希望伪语法对他来说是可以理解的):
Insert(0, num1)
// ^ no cmp
Insert((num2 <= [0] ? 0 : 1), num2)
// ^ 1x cmp executed
Insert((num3 <= [0] ? 0 : (num3 <= [1] ? 1 : 2)), num3)
// ^ at most 2 cmp executed
Insert((num4 <= [1] ? (num4 <= [0] ? 0 : 1) : (num4 <= [2] ? 2 : 3)), num4)
// ^ always 2 of 3 cmp executed
Insert((num5 <= [1] ? (num5 <= [0] ? 0 : 1) : (num5 <= [2] ? 2 : (num5 <= [3] ? 3 : 4))), num5)
// ^ at most 3 of 4 cmp executed
=> total at most 8 cmp executed.
当然要做&#34;插入&#34;与&#34;位置&#34;固定变量将是总PITA ...;)所以这是半开玩笑的提议,只是为了看看8x cmp是否足够。
(&#34; 6比较&#34;原来是我的脑屁,不可能是AFAIK)