Assembly 从数组中查找最大数和最小数的程序

Assembly 从数组中查找最大数和最小数的程序,assembly,nasm,x86-16,bubble-sort,dosbox,Assembly,Nasm,X86 16,Bubble Sort,Dosbox,我编写了以下程序,从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:

我编写了以下程序,从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,但它给出了第一个内存地址的值,即交换后存储在[数据]中的任何内容。代码将使用8086体系结构进行编译。

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

问题是外部循环从不迭代,因为您未能设置其控制变量交换!无论何时执行交换,都需要将其设置为真:

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:

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

下面是我对它的实现

  • 我首先任意选择数组的最后一个元素作为最小值(在
    AL
    中)和最大值(在
    DL
    中)
  • 然后我迭代数组的其余部分,每次在
    AL
    中找到小于当前最小值的元素时,我都将该元素设置为新的当前最小值
  • 类似地,每次我在
    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
    

    如果您的数组包含有符号的数字,则必须将
    jae
    jbe
    指令分别交换为
    jge
    jle

    顺便说一句,在我看来,为了找到max和min而对数组进行排序是过分的。只需迭代数组并存储迄今为止发现的最小值和最大值。