0

文字列を取り込み、バブルソートでソートし、ソートされた文字列を出力するアセンブリプログラムに取り組んでいます。デバッガーにアクセスできないため、助けを求める必要があります。私のプログラムは、BSORT サブルーチンで無限ループに陥っているようで、何が原因なのか突き止められないようです。これは課題のためなので、解決策を手渡されるだけでなく、どこが間違っているのか、何を間違っているのかについて説明を受けたい.

これが私のコードです:

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

実行すると、プロンプトが出力され、明らかな問題なく文字列が取り込まれますが、メッセージやソートされた文字列は出力されません。以前は、メッセージと文字列を出力するようにしましたが (何が変更されて停止したのかわかりません)、完全にソートされていませんでした。

ヘルプ/ガイダンスは大歓迎です。

EDIT 1:さて、良いニュースは、無限ループを引き起こしているループで私の問題を見つけたことです(私は思う)。しかし、ソートは行われておらず、非常に興味深い出力も得られています。実行時の出力は次のとおりです。

何か案は?

何か案は?

編集 2: IT の並べ替えです! :D

しかし、文字列の先頭に小文字の d とスペードの文字がまだ挿入されています。それがどこから来ているかを見つけたら、それは解決されると思います! 上記のコードが更新されました。

ここに私の出力があります:

出力を更新する

編集 3: 奇妙な文字が見つかりました - 文字列 [INBUF+2] だけでなく、[INBUF] のすべてを印刷していました。助けてくれてありがとう!:)

4

1 に答える 1

0

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
于 2015-03-17T17:50:28.740 に答える