程序集 A86 - 冒泡排序
Assembly A86 - Bubble Sort
我正在编写一个汇编程序来接收一串字符,使用冒泡排序对它们进行排序,然后输出排序后的字符串。我无权访问调试器,这就是我不得不寻求帮助的原因。我的程序似乎陷入了 BSORT 子例程的无限循环中,我似乎无法找出是什么原因造成的。这是一项作业,所以我宁愿得到关于我要去哪里的解释 wrong/what 我做错了,而不是仅仅得到解决方案。
这是我的代码:
TITLE BSORT
PAGE 60, 132
; This program gets a string of input
; and sorts it by ASCII value, then outputs
; the sorted string to the monitor
;
; Define constants
;
CR EQU 0DH ;define carriage return
LF EQU 0AH ;define line feed
EOM EQU '$' ;define end of message marker
NULL EQU 00H ;define NULL byte
;
; Define variables
;
JMP START
PROMPT DB CR, LF, "Enter a string of characters (max 100): ", EOM
INBUF DB 100, ?, 100 DUP ?
MESSAGE DB CR, LF, "The sorted string is: ", CR, LF, CR, LF, EOM
;
;
; Program Code
;
;
BSORT:
;|——————————
;| CX holds count
;| SI points to first item
;|____________
MOV BX, CX ;BX will be inner loop variable
DEC BX ;last value will be EOM marker
OUTER: DEC CX
JZ DONE ;when the count is zero, we’re done
XOR DL, DL ;DL (hasSwapped) = false
MOV SI, DI ;reset SI
INNER: MOV AX, [SI] ;load 2 characters
CMP AL, AH ;first char is in AL, second is AH
JBE NOSWAP ;if AL <= AH, no swap needed
MOV DL, 1 ;else, hasSwapped = true
XCHG AL, AH ;swap first and second chars
MOV [SI], AX ;put swapped chars back in string
NOSWAP: INC SI ;next chars
CMP SI, BX
JL INNER
TEST DL, DL ;else, did we swap?
JNZ OUTER ;if yes, loop again
DONE: RET ;if done, return to main program
;End subroutine
READ MACRO
MOV AH, 0AH
LEA DX, #1
INT 21H
#EM
WRITE MACRO
MOV AH, 09H
LEA DX, #1
INT 21H
#EM
;
;main
START: WRITE PROMPT
READ INBUF
LEA SI, INBUF+2 ;point SI to beginning of array
MOV CX, SI ;save SI in the CX register
ADD CL, B[SI-1] ;add the count that the OS records to the CL register
ADC CH, 0 ;if carry, add to upper bits
MOV SI, CX ;move back to SI and see what it points to
MOV B[SI], '$' ;replace carriage return with end of text marker
MOV CX, SI ;put count in CX
LEA SI, INBUF+2 ;point SI to beginning of array
LEA DI, INBUF+2 ;copy of beginning of array
CALL BSORT
WRITE MESSAGE
WRITE [INBUF+2]
MOV AX, 2C00H
INT 21H ;return control to OS
;
; Program End
;
END START
当它是 运行 时,它会打印提示并在没有明显问题的情况下接收字符串,但是它永远不会打印消息或排序后的字符串。以前,我让它打印消息和字符串(不知道我改变了什么让它停止),但它没有完全排序。
非常感谢help/guidance。
编辑 1:好的,好消息是,我在导致无限循环的循环中发现了我的问题(我认为)。但是排序并没有发生,现在我也得到了一些非常有趣的输出。这是 运行:
时的输出
有什么想法吗?
编辑 2:正在排序! :D
但是,它仍然在我的字符串开头插入小写字母 d 和黑桃字符。一旦我找到它的来源,我想它就会被解决!上面的代码已更新。
这是我现在的输出:
编辑 3:发现我的奇怪字符 - 我正在打印所有 [INBUF],而不仅仅是字符串 [INBUF+2]。谢谢你们的帮助! :)
我相信你没有重置 SI 寄存器。完成内循环的第一次迭代后,SI 将永远不会小于或等于 BX。看看是不是这个问题。
MOV BX, CX ;BX will be inner loop variable
OUTER: DEC CX
JZ DONE ;when the count is zero, we’re done
XOR DL, DL ;DL (hasSwapped) = false
;You should see if resetting SI here will solve the infinite loop.
INNER: MOV AX, [SI] ;load 2 characters
;What happens in the second iteration ?
CMP AL, AH ;first char is in AL, second is AH
JBE NOSWAP ;if AL <= AH, no swap needed
MOV DL, 1 ;else, hasSwapped = true
XCHG AL, AH ;swap first and second chars
MOV [SI], AX ;put swapped chars back in string
NOSWAP: INC SI ;next chars
CMP SI, BX ;In the first iteration of the inner loop that should be ok.
JLE INNER
;At this point SI kept its value
TEST DL, DL ;else, did we swap?
JNZ OUTER ;if yes, loop again
我正在编写一个汇编程序来接收一串字符,使用冒泡排序对它们进行排序,然后输出排序后的字符串。我无权访问调试器,这就是我不得不寻求帮助的原因。我的程序似乎陷入了 BSORT 子例程的无限循环中,我似乎无法找出是什么原因造成的。这是一项作业,所以我宁愿得到关于我要去哪里的解释 wrong/what 我做错了,而不是仅仅得到解决方案。
这是我的代码:
TITLE BSORT
PAGE 60, 132
; This program gets a string of input
; and sorts it by ASCII value, then outputs
; the sorted string to the monitor
;
; Define constants
;
CR EQU 0DH ;define carriage return
LF EQU 0AH ;define line feed
EOM EQU '$' ;define end of message marker
NULL EQU 00H ;define NULL byte
;
; Define variables
;
JMP START
PROMPT DB CR, LF, "Enter a string of characters (max 100): ", EOM
INBUF DB 100, ?, 100 DUP ?
MESSAGE DB CR, LF, "The sorted string is: ", CR, LF, CR, LF, EOM
;
;
; Program Code
;
;
BSORT:
;|——————————
;| CX holds count
;| SI points to first item
;|____________
MOV BX, CX ;BX will be inner loop variable
DEC BX ;last value will be EOM marker
OUTER: DEC CX
JZ DONE ;when the count is zero, we’re done
XOR DL, DL ;DL (hasSwapped) = false
MOV SI, DI ;reset SI
INNER: MOV AX, [SI] ;load 2 characters
CMP AL, AH ;first char is in AL, second is AH
JBE NOSWAP ;if AL <= AH, no swap needed
MOV DL, 1 ;else, hasSwapped = true
XCHG AL, AH ;swap first and second chars
MOV [SI], AX ;put swapped chars back in string
NOSWAP: INC SI ;next chars
CMP SI, BX
JL INNER
TEST DL, DL ;else, did we swap?
JNZ OUTER ;if yes, loop again
DONE: RET ;if done, return to main program
;End subroutine
READ MACRO
MOV AH, 0AH
LEA DX, #1
INT 21H
#EM
WRITE MACRO
MOV AH, 09H
LEA DX, #1
INT 21H
#EM
;
;main
START: WRITE PROMPT
READ INBUF
LEA SI, INBUF+2 ;point SI to beginning of array
MOV CX, SI ;save SI in the CX register
ADD CL, B[SI-1] ;add the count that the OS records to the CL register
ADC CH, 0 ;if carry, add to upper bits
MOV SI, CX ;move back to SI and see what it points to
MOV B[SI], '$' ;replace carriage return with end of text marker
MOV CX, SI ;put count in CX
LEA SI, INBUF+2 ;point SI to beginning of array
LEA DI, INBUF+2 ;copy of beginning of array
CALL BSORT
WRITE MESSAGE
WRITE [INBUF+2]
MOV AX, 2C00H
INT 21H ;return control to OS
;
; Program End
;
END START
当它是 运行 时,它会打印提示并在没有明显问题的情况下接收字符串,但是它永远不会打印消息或排序后的字符串。以前,我让它打印消息和字符串(不知道我改变了什么让它停止),但它没有完全排序。
非常感谢help/guidance。
编辑 1:好的,好消息是,我在导致无限循环的循环中发现了我的问题(我认为)。但是排序并没有发生,现在我也得到了一些非常有趣的输出。这是 运行:
时的输出有什么想法吗?
编辑 2:正在排序! :D
但是,它仍然在我的字符串开头插入小写字母 d 和黑桃字符。一旦我找到它的来源,我想它就会被解决!上面的代码已更新。
这是我现在的输出:
编辑 3:发现我的奇怪字符 - 我正在打印所有 [INBUF],而不仅仅是字符串 [INBUF+2]。谢谢你们的帮助! :)
我相信你没有重置 SI 寄存器。完成内循环的第一次迭代后,SI 将永远不会小于或等于 BX。看看是不是这个问题。
MOV BX, CX ;BX will be inner loop variable
OUTER: DEC CX
JZ DONE ;when the count is zero, we’re done
XOR DL, DL ;DL (hasSwapped) = false
;You should see if resetting SI here will solve the infinite loop.
INNER: MOV AX, [SI] ;load 2 characters
;What happens in the second iteration ?
CMP AL, AH ;first char is in AL, second is AH
JBE NOSWAP ;if AL <= AH, no swap needed
MOV DL, 1 ;else, hasSwapped = true
XCHG AL, AH ;swap first and second chars
MOV [SI], AX ;put swapped chars back in string
NOSWAP: INC SI ;next chars
CMP SI, BX ;In the first iteration of the inner loop that should be ok.
JLE INNER
;At this point SI kept its value
TEST DL, DL ;else, did we swap?
JNZ OUTER ;if yes, loop again