程序集:仅使用条件语句对数字进行排序

时间:2016-10-28 23:41:07

标签: sorting assembly masm irvine32

我是汇编的新手,我正在尝试编写一个程序,它获取五个用户输入的数字,将它们存储在变量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

1 个答案:

答案 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 ebxcall 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)