assembly 我试图为字和字节大小的数组编写单个子例程,但代码没有终止

clj7thdc  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(132)

**我应该如何为字节大小和字大小的数组编写一个代码?***下面的代码不会在一个数组为字节大小而另一个为字大小时终止 *

在这段代码中,气泡排序算法被用来对两个名为data和data2的数组进行排序,但是当我运行代码时,它并没有终止,而是继续运行。我写的代码是正确的还是应该有变化?

[org 0x0100]

jmp start

data: dw 60,40,50,22,5

data2: db 3,4,1,9,6

swapflag: db 0

swap:

mov ax, [bx+si]               
xchg ax, [bx+si+2]            
mov [bx+si], ax               
ret                           

bubblesort: 

dec cx                        
shl cx, 1                     

mainloop: 

mov si, 0                     
mov byte [swapflag], 0        

innerloop: 

mov ax, [bx+si]              
cmp ax, [bx+si+2]            
jbe noswap                    
call swap                     
mov byte [swapflag], 1        

noswap: 

add si, 2                     
cmp si, cx                   
jne innerloop                
cmp byte [swapflag], 1      
je mainloop                 
ret                           

start: 

mov bx, data                 
mov cx, 10                  
call bubblesort              
mov bx, data2              
mov cx, 20                    
call bubblesort              

mov ax, 0x4c00 
             
int 0x21
tuwxkamq

tuwxkamq1#

mov bx, data
mov cx, 10           <<< 5 elements !!!
call bubblesort
mov bx, data2
mov cx, 20           <<< 5 elements !!!
call bubblesort

您正在调用 bubblesort 子例程,但所用的计数对于您所拥有的5元素数组来说太高了。此错误将处理垃圾数据,但不会解释为什么“它不会终止”。

死循环问题的存在是因为,在 innerloop 结束时,您忘记了降低CX寄存器中的限制。正是通过降低限制,我们表明最后一个元素位于其最终位置,我们不再需要考虑它,从而减少了任务,并朝着结束工作。

接下来是一个更正版本的代码。我没有优化它,所以你仍然可以认识到问题和它是如何解决的。

; IN (bx,cx)
bubblesort16: 
  dec  cx                        
  shl  cx, 1               *      
mainloop: 
  mov  si, 0                     
  mov  byte [swapflag], 0        
innerloop: 
  mov  ax, [bx+si]         *    
  cmp  ax, [bx+si+2]       *    
  jbe  noswap                    
swap:                                ;
  xchg ax, [bx+si+2]       *         ; better have this inlined
  mov  [bx+si], ax         *         ;
  mov  byte [swapflag], 1
noswap: 
  add  si, 2               *      
  cmp  si, cx                   
  jne  innerloop                
  cmp  byte [swapflag], 0            ; 
  je   done                          ;
  sub  cx, 2               *         ;  new (solution)
  jnz  mainloop                      ;
done:                                ;
  ret

我已经用星号标记了需要为字节大小的版本更改的行。
我应该如何为字节和字大小的数组写一个代码?
我的第一React是,如果有一个代码可以处理字节数组和字数组,那么由于内部循环中有额外的分支,代码运行速度会更慢。事实证明,情况并非如此。我设法编写了一个满足要求的双 Bubblesort 代码,其性能与(甚至比它快一点)对应的 * BubbleSort 16 * 和 * BubbleSort 8 * 版本,@PeterCordes在评论中给出的建议对得出这个结果很有帮助。
双重解决方案的一个小缺点是,除了计数和地址之外,它还需要CX = {1=字节,2=字}中的第三个不同参数。

; --------------------------------------
; IN (ax,bx,cx) OUT () MOD (ax,dx,si,di,bp)
BubbleSort:
        sub  ax, 1          ; Number of elements
        jbe  .Done
        mul  cx
        add  ax, bx         ; -> Address of the last element
        xor  bp, bp         ; SwapFlag [0,1]
.Outer: mov  si, bx
.Inner: mov  dx, [si]
        cmp  cx, 2
        jb   .Byte
.Word:  mov  di, [si+2]
        cmp  dx, di
        jle  .Skip
        mov  [si+2], dx
        mov  [si], di
        mov  bp, 1
.Skip:  add  si, cx         ; CX=[1,2]
        cmp  si, ax
        jb   .Inner
.Both:  dec  bp
        jnz  .Done
        sub  ax, cx         ; CX=[1,2]
        cmp  bx, ax
        jb   .Outer
.Done:  ret

.Byte:  cmp  dl, dh
        jle  .Skip
        rol  dx, 8
        mov  [si], dx
        mov  bp, cx         ; CX=1
        inc  si
        cmp  si, ax
        jb   .Inner
        jmp  .Both
; --------------------------------------
; IN (ax,bx) OUT () MOD (ax,dx,si,bp)
BubbleSort8:
        nop
        nop
        sub  ax, 1          ; Number of elements
        jbe  .Done
        add  ax, bx         ; -> Address of the last element
        xor  bp, bp         ; SwapFlag [0,1]
.Outer: mov  si, bx
.Inner: mov  dx, [si]
        cmp  dl, dh
        jle  .Skip
        rol  dx, 8
        mov  [si], dx
        mov  bp, 1
.Skip:  inc  si
        cmp  si, ax
        jb   .Inner
        dec  bp
        jnz  .Done
        dec  ax
        cmp  bx, ax
        jb   .Outer
.Done:  ret
; --------------------------------------
; IN (ax,bx) OUT () MOD (ax,dx,si,di,bp)
BubbleSort16:
        sub  ax, 1          ; Number of elements
        jbe  .Done
        shl  ax, 1
        add  ax, bx         ; -> Address of the last element
        xor  bp, bp         ; SwapFlag [0,1]
.Outer: mov  si, bx
.Inner: mov  dx, [si]
        mov  di, [si+2]
        cmp  dx, di
        jle  .Skip
        mov  [si+2], dx
        mov  [si], di
        mov  bp, 1
.Skip:  add  si, 2
        cmp  si, ax
        jb   .Inner
        dec  bp
        jnz  .Done
        sub  ax, 2
        cmp  bx, ax
        jb   .Outer
.Done:  ret
; --------------------------------------

在Intel Pentium双核心T2080上测量的时间:

Sorting an array with 46 bytes
------------------------------
BubbleSort    17.2 µsec - 17.3 µsec
BubbleSort8   17.2 µsec - 18.5 µsec

Sorting an array with 23 words
------------------------------
BubbleSort     3.8 µsec -  3.9 µsec
BubbleSort16   4.1 µsec -  4.3 µsec

相关问题