【问题标题】:Why is my code not showing the largest number?为什么我的代码没有显示最大的数字?
【发布时间】:2021-12-03 16:43:54
【问题描述】:
include 'emu8086.inc'
org 100h

.model small
.data
     arr db 8,5,3,6,2
.code 
main proc

        mov ax,@data
        mov ds,ax

        mov si,offset arr
        mov cx,5
        mov bl,[si]

        loopA:
        cmp [si],bl ; 2,3
          
        
        
        jge large 
        jle small
        compare:  
        
        inc si
        loop loopA 
        
        

        print "Largest value in array is :" 
        print "Smallest value in array is :"
        add bl,48
        mov dl,bl
        mov ah,2
        int 21h

        large: 
        
        mov bl,[si]
        jmp compare   
        
        small:
        mov bl,[si]
        jmp compare 

main endp

输出:

数组中的最大值是:数组中的最小值是:2

【问题讨论】:

  • 您希望它如何工作?说真的,你的期望是什么?代码中只有一个打印字符,所以当然它只打印一个数字。它正在做的正是编程要做的事情,所以如果你想要不同的结果,那就改变程序吧。

标签: arrays assembly x86-16 emu8086


【解决方案1】:
  jge large 
  jle small
large: 
  mov bl,[si]
  jmp compare  
small:
  mov bl,[si]
  jmp compare

无论你发现一个元素更大或更小,你总是认为它是下一个参考。这将始终导致显示最后一个数组元素。

在您的循环中,您应该只在一个条件下设置一个新的BL,而在另一个条件下跳过修改BL

loopA:
 cmp  [si], bl
 jng  NotLarger    ; Skip on condition "Not larger"
 mov  bl, [si]     ; Set on condition "Larger"
NotLarger:
 inc  si
 loop loopA
print "Largest value in array is :" 
print "Smallest value in array is :"

同时显示两条消息令人困惑!
首先使用我上面显示的代码专注于“最大”任务,然后为“最小”添加一个单独但非常相似的代码。你会使用jnl (JumpOnNotLess)。


结合max和min的代码

还在学习汇编编程的基础知识时,最好远离 DOS .EXE 格式,开始使用更简单的 DOS .COM 程序格式。您所需要的只是在程序顶部使用指令ORG 100h。您不必自己设置任何段寄存器,但您需要将变量(数据)放在代码下方。执行将简单地从顶部开始。

由于您想在单独的行中显示消息,因此您需要将光标移动到下一行的开头,其中包含换行符 (10) 和回车符 (13) 代码。

所有程序都需要在某个时候退出。您需要编写特殊代码来执行此操作。请参阅下面的程序在哪里写这个。

include 'emu8086.inc'
org 100h

  mov  si, offset arr
  mov  cx, 5
  mov  bl, [si]
MaxLoop:
  cmp  [si], bl
  jng  NotLarger    ; Skip on condition "Not larger"
  mov  bl, [si]     ; Set on condition "Larger"
NotLarger:
  inc  si
  loop MaxLoop
  PRINT "Largest value in array is : "
  add  bl, 48
  mov  dl, bl
  mov  ah, 02h      ; DOS.PrintCharacter
  int  21h

  PUTC 10           ; Linefeed
  PUTC 13           ; Carriage return

  mov  si, offset arr
  mov  cx, 5
  mov  bl, [si]
MinLoop:
  cmp  [si], bl
  jnl  NotSmaller   ; Skip on condition "Not smaller"
  mov  bl, [si]     ; Set on condition "Smaller"
NotSmaller:
  inc  si
  loop MinLoop
  PRINT "Smallest value in array is : "
  add  bl, 48
  mov  dl, bl
  mov  ah, 02h      ; DOS.PrintCharacter
  int  21h

  mov  ax, 4C00h    ; DOS.TerminateProgram
  int  21h

; ------------------
arr db 8, 5, 3, 6, 2

将最大值和最小值的代码组合在一个循环中

我已经包含了这个变体,因为在编程中,在一个循环中做不止一件事通常是有效的。这将最大限度地减少循环开销对执行时间的影响(通常)。

include 'emu8086.inc'
org 100h

  mov  si, offset arr
  mov  cx, 5
  mov  bh, [si]
  mov  bl, bh
MaxMinLoop:
  cmp  [si], bh
  jng  NotLarger    ; Skip on condition "Not larger"
  mov  bh, [si]     ; Set on condition "Larger"
NotLarger:
  cmp  [si], bl
  jnl  NotSmaller   ; Skip on condition "Not smaller"
  mov  bl, [si]     ; Set on condition "Smaller"
NotSmaller:
  inc  si
  loop MaxMinLoop
  add  bx, 3030h

  PRINT "Largest value in array is : "
  mov  dl, bh
  mov  ah, 02h      ; DOS.PrintCharacter
  int  21h

  PUTC 10           ; Linefeed
  PUTC 13           ; Carriage return

  PRINT "Smallest value in array is : "
  mov  dl, bl
  mov  ah, 02h      ; DOS.PrintCharacter
  int  21h

  mov  ax, 4C00h    ; DOS.TerminateProgram
  int  21h

; ------------------
arr db 8, 5, 3, 6, 2

【讨论】:

  • 感谢您的澄清。我对汇编语言一无所知,我从谷歌复制了这些代码,并尝试了很多合并这两个,只是好奇地看到屏幕上的输出,它在不同的行上显示最大值和最小值。从字面上看,我不知道在哪里使用你给我的这些代码行,这就是为什么我再次发布它,期待有人分享整个代码。
  • 首先我会学习这门语言,然后使用它。我认为这是最好的学习方式,而不是复制粘贴,然后尝试理解代码。
  • @SumedhMalik 感谢您的回复。我已经在我的答案中包含了整个代码。我相信可以从中学到很多东西。祝你好运。如果你发现这对你有帮助,那么也许点击接受箭头...
  • 非常感谢,这对我帮助很大。
猜你喜欢
  • 2021-01-03
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
  • 2016-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多