汇编语言中的数组冒泡排序

3
我需要对一个包含7个整数的无序数组进行冒泡排序,从大到小排列,使其看起来像9,6,5,4,3,2,1。
我将代码输入编译器后,它显示出错误信息:

Compiler Error

我不明白这段代码的问题所在:

code segment
assume ds:code,cs:code
start:
 mov ax,code
 mov ds,ax    ;code start
ARR:   dw 1,2,4,3,6,5,9
 mov ch,0h
 mov cl,1h
 mov bh 7h
 jmp assign_nums
restart:
 mov ch,0h
 mov cl,1h
 dec bh
 jmp assign_nums
swap:
 mov ch,dl
 mov cl,dh
 jmp next
next:
 cmp bh,cl
 je restart
 add ch,1h
 add cl,1h
 jmp assign_nums
assign_nums:
 cmp bh,0h
 je done
 mov dh,[ARR+ch]
 mov dl,[ARR+cl]
 cmp dh,dl
 jl swap
 jnl next
done:
 nop
code ends
end start
4个回答

2

对于第一个错误,您忘记在寄存器和立即数之间输入逗号。

对于第二个和第三个错误,CH和CL寄存器不能用于寻址内存。请改用SI、DI或BX。

由于您的数组被定义为单词,因此必须按照这样处理!
更改

mov dh,[ARR+ch]
mov dl,[ARR+cl]

转换成类似于某些东西(取决于您做出的其他选择)

mov ax,[ARR+si]
mov dx,[ARR+di]

请注意,您把数组放在了指令中间。这会导致程序在编译后立即崩溃。请将数组放在程序的单独数据段中,或跳过此行。
start:
 mov ax,code
 mov ds,ax
 jmp start2
ARR:   dw 1,2,4,3,6,5,9
start2:
 mov ch,0h

这是一堆很乱的代码?有更好的编码方式吗?对于这个汇编代码,我毫无头绪。 - Puloko
1
用户3144770的答案非常好。我唯一要做的改变是不给跳过数组的选项。只把你的ARR放在.data段或.fardata DSEG中。 .DATA或.FARDATA DSEG ARR: dw 1,2,4,3,6,5,9 - BKCOHEN

2

这是一个简单的冒泡排序代码

iclude'emu8086.inc'

org 100h 
.data

array  db 9,6,5,4,3,2,1
count  dw 7

.code

    mov cx,count      
    dec cx               ; outer loop iteration count

nextscan:                ; do {    // outer loop
    mov bx,cx
    mov si,0 

nextcomp:

    mov al,array[si]
    mov dl,array[si+1]
    cmp al,dl

    jnc noswap 

    mov array[si],dl
    mov array[si+1],al

noswap: 
    inc si
    dec bx
    jnz nextcomp

    loop nextscan       ; } while(--cx);



;;; this  loop to display  elements on the screen

    mov cx,7
    mov si,0

print:

    Mov al,array[si]  
    Add al,30h
    Mov ah,0eh
    Int  10h 
    MOV AH,2
    Mov DL , ' '
    INT 21H
    inc si
    Loop print

    ret 

更高效的方法是将si设置为一个指针而不是一个索引,即 mov si, OFFSET array。否则,这是一个相当不错的简单冒泡排序算法,通过不对外部循环迭代后无交换进行提前检查来保持简单性。 - Peter Cordes

1

使用冒泡排序算法对数组进行排序

.MODEL SMALL  
.STACK 100H  
.DATA  
    N DB 44H,22H,11H,55H,33H     ; N is an array      
    LEN DW 5 ; LENGTH OF ARRAY N   
.CODE   
 MAIN PROC  
 MOV AX,@DATA  
    MOV DS,AX  

 MOV CX,LEN ;Cx is counter for OUTERLOOP CX=5    
 DEC CX     ; CX = 4   

 OUTERLOOP:  
    MOV SI,0         ;    SI is the index of array N   
    MOV DX,CX  ; Dx is counter for INNERLOOP   
 INNERLOOP:    
    MOV AH,N[SI]    ; assign the number N[SI] into reg.AH  
    MOV AL,N[SI+1]  ; assign the next number N[SI+1] into reg.AL   
    CMP AH,AL       ; Compare between N[SI] and N[SI+1] <BR> 
    JC CARRY        ; if AL > AH => Carry Flag =1 ,THEN jump to carry   
    MOV N[SI] , AL  ; else , Do Switching bteween  N[SI] and N[SI+1]   
    MOV N[SI+1] ,AH   
 CARRY:   
    INC SI   
    DEC DX   
    JNZ INNERLOOP   
    LOOP OUTERLOOP   
 ;exit   
 MOV AH,4CH   ;service number     
 INT 21H      ; interrupt   
 MAIN  ENDP   
END 

请在您的答案中包含一些解释,并使用正确的语法高亮显示。 - bastelflp
这对存储器可以使用mov n[si], AX来进行,以便将AL和AH与16位存储一起存储。(但是,在现代Intel CPU上,您将会遇到部分寄存器合并的减速。尽管如此,您正在使用缓慢的loop指令,所以显然您并没有为现代CPU的性能进行优化。) - Peter Cordes

-1
.model small
.data

arr1 db 6, 5, 8, 3, 9
len1 equ $-arr1

.code


mov ax, @data
mov ds, ax
mov ch, len1-1


a1:
mov cl, ch
lea si, arr1


rept1:
mov al, [si]
inc si
cmp al, [si]
jbe next1
xchg al, [si]
mov [si-1], al


next1:
dec cl
jnz rept1
dec ch
jnz a1


mov ah, 4ch
int 21h

end

请格式化代码。您可以通过在每行前面添加4个空格来实现此操作。同时删除所有空白行。 - Sep Roland
1
你知道吗,像你这样的“只有代码”的帖子不算作答案吗? 除了在本页面顶部提出原始问题的人之外,您还需要详细解释您的程序是做什么的以及如何帮助他们。 如果未能这样做,将会受到其他用户的负面评价! - Sep Roland
感谢@SepRoland的反馈。我是这个社区的新手,你的反馈无疑非常有帮助! - AbinVarghese

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接