【发布时间】:2019-04-18 19:46:27
【问题描述】:
我创建了一个对词向量进行选择排序的过程,但有一个问题:排序完全错误。
我的矢量:VET_2 DW 2, 7, 0, 1, 4, 8, 9, 3, 6, 5
; Selection Sort
SELECTION_SORT PROC
; AX = j & aux CX = i
; BX = offset/min DX = data and others
PUSH 0 ; to initialize i
MOV SI, [OFFSET VET_2]
; ----- start for(int i = 0; i < n-1; i++) -----
SLC_LOOP_FORA: ; outer loop
CALL RESET_REGIST ; reset some AX, BX, CX & DX
CALL RESET_VAR ; used to reset AUX
POP CX ; initialize i
CMP CX, 18 ; check if it's smaller than n-1 (20-2=18)
JGE SLC_FIM ; if bigger, goes to the end
MOV BX, CX ; offset receive i, the position of the smaller
; ----- start j = i+1 -----
MOV AX, CX ; AX = j.
ADD AX, 2 ; j = i+1
; ----- end j = i+1 -----
; ----- start for(int j = i+1; j < n; j++) -----
SLC_LOOP_DENTRO: ; inner loop
MOV DX, [SI+BX] ; move the smaller element to DX
MOV BX, AX ; offset receives j
CMP DX, [SI+BX] ; compare if VET_2[min]<=VET_2[j]
JL SLC_DENTRO_PULAR ; if lesser, ignore the code below
MOV BX, AX ; offset receive j, position of the smaller element
SLC_DENTRO_PULAR:
ADD AX, 2 ; inc 2 in j
CMP AX, 20 ; compare j (ax) with n
JL SLC_LOOP_DENTRO ; if it's smaller, repeat inner loop
; ----- end for(int j = n+1; j < n; j++) -----
CMP CX, BX ; compare i with the position of the smaller element
JE SLC_LOOP_FORA ; if equals, repeat outer loop, otherwise do the swap
PUSH BX ; position of the smaller element
PUSH [SI+BX] ; put vet[min] top of the stack
; ----- start aux = vet[i] -----
MOV BX, CX ; offset (BX) receives i
MOV DX, [SI+BX] ; DX receives vet_2[i]
MOV AUX, DX ; AUX receives DX
; ----- end aux = vet[i] -----
; ----- start vet[i] = vet[min] -----
POP AX ; AX receives the top of the stack (vet_2[min])
MOV [SI+BX], AX ; vet_2[i] receives DX (smaller element)
; ----- end vet[i] = vet[min] -----
; ----- start vet[min] = aux -----
POP BX ; offset (BX) receives the position of the smaller element from the stack
MOV DX, AUX ; DX receives AUX
MOV [SI+BX], DX ; vet_2[min] receives DX
; ----- end vet[min] = aux -----
ADD CX, 2 ; INC 2 on i
PUSH CX ; put in the stack
JMP SLC_LOOP_FORA repeat outer loop
; ----- end for(int i = 0; i < n-1; i++) -----
SLC_FIM: ; end the procedure
RET
SELECTION_SORT ENDP
调用选择排序程序前:2 7 0 1 4 8 9 3 6 5
调用后选择排序过程:5 2 7 0 1 4 8 9 3 6
错误在哪里?有人可以帮帮我吗?
【问题讨论】:
-
POP CX在循环内对我来说看起来很可疑,因为您在循环外push 0,但是有一个JE SLC_LOOP_FORA可以重复此操作而无需推动任何内容。所以你会消耗一些堆栈空间。xor cx,cx或mov cx,0会更明智。如果您的本地寄存器用完了,通常您在制作堆栈帧后将它们存储/重新加载到[bp-4]之类的位置。 (您不能在 16 位代码中使用[SP+4]或其他任何内容)。循环内的 push/pop 更难推理,会导致类似这样的错误。 -
您是否尝试过使用调试器单步执行代码以查看它是否提前离开循环?如果是这样,您可以准确地看到哪个分支出了问题。
标签: assembly x86-16 selection-sort