【问题标题】:A program to find maximum and minimum number from an array从数组中查找最大和最小数字的程序
【发布时间】:2020-01-12 03:31:33
【问题描述】:

我编写了以下程序,它从 10 个数字的数组中找到最大和最小数字,但它没有给我正确的最小值,

[org 0x0100]

start:
    mov byte [swap],0
    mov bx,0
loop1:
    mov al,[data+bx]
    cmp  al,[data+bx+1]
    jbe noswap
hswap:
    mov dl,[data+bx+1]
    mov [data+bx+1],al
    mov [data+bx],dl
noswap:
    add bl,1
    cmp bx,9
    jnz loop1
heckswap:
    cmp byte [swap],0
    jnz start
store:
    mov al,[data]
    mov [min],al
    mov bl,[data+9]
    mov [max],bl

mov ax,0x4c00
int 0x21

data: db 2,10,3,4,7,8,6,5,9,1
swap: db 0
max: db 0
min: db 0

它应该给出最小值 1,但它给出了第一个内存地址的值,即交换后存储在 [data] 中的任何值。代码使用8086架构编译。

【问题讨论】:

  • 顺便说一下,在我看来,对数组进行排序以找到最大值和最小值是多余的。只需遍历数组并存储迄今为止找到的最小和最大的。

标签: assembly nasm x86-16 bubble-sort dosbox


【解决方案1】:

您的代码实际上是 BubbleSort,已经使用了嵌套循环。
内循环是loop1,外循环是start

问题在于外部循环永远不会迭代,因为你没有设置它的控制变量 swap!每当您执行交换时,您都需要将其设为 TRUE:

start:
    mov byte [swap], 0
    mov bx, 0
loop1:
    mov al, [data+bx]
    cmp al, [data+bx+1]
    jbe noswap
hswap:
    mov dl, [data+bx+1]
    mov [data+bx+1], al
    mov [data+bx], dl
    mov byte [swap], -1       ;ADD THIS 
noswap:
    add bl, 1
    cmp bx, 9
    jnz loop1
heckswap:
    cmp byte [swap], 0
    jne start

为了提高 BubbleSort 的效率,您需要减少在外循环的每次迭代中要处理的元素数量。不要将 BX 与固定值 9 进行比较(因为数组中有 10 个元素),您应该将其与寄存器中的递减值进行比较,例如 CX

    mov cx, 9                 ; !!!
start:
    xor bx, bx                ;Just another optimization
    mov [swap], bl            ;Just another optimization
loop1:
    mov al, [data+bx]
    cmp al, [data+bx+1]
    jbe noswap
hswap:
    mov dl, [data+bx+1]
    mov [data+bx+1], al
    mov [data+bx], dl
    mov byte [swap], -1
noswap:
    inc bx                    ;Just another optimization
    cmp bx, cx                ; !!!
    jnz loop1
heckswap:
    dec cx                    ; !!!
    jz  store                 ; !!! Done
    cmp byte [swap], 0
    jne start
store:

虽然找到最小值和最大值是排序的一个很好的副产品,但您应该遵循this comment 中给出的建议。得到结果会快很多!

下面是我的实现。

  1. 我首先任意选择数组的最后一个元素作为最小值(AL)和最大值(DL)。
  2. 然后我遍历数组的其余部分,每次在AL 中找到小于当前最小值的元素时,我将该元素设置为新的当前最小值。
  3. 同样,每次我在DL 中找到一个大于当前最大值的元素时,我都会将该元素设置为新的当前最大值。

您可以遍历从第一个元素到最后一个元素或从最后一个元素到第一个元素的数组。我选择了后者,因为它可以让我免于编写额外的 cmp 指令。

 mov al, [data+9]  ;Min
 mov dl, al        ;Max
 mov bx, 8
Repeat:
 mov cl, [data+bx]
 cmp cl, al
 jae NotSmaller
 mov al, cl
 ;;; jmp NotBigger     ;Better without this
NotSmaller:
 cmp cl, dl
 jbe NotBigger
 mov dl, cl
NotBigger:
 sub bx, 1
 jnb Repeat
 mov [min], al
 mov [max], dl

如果您的数组包含带符号的数字,那么您必须将 jaejbe 指令分别交换为 jgejle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2014-03-05
    • 2019-02-28
    • 2020-07-12
    相关资源
    最近更新 更多