3

アセンブリ言語でのループに問題があります。

ネストされたループのループにカウンター レジスタを使用する場合、最初に行うことは、カウンター レジスタの値を外側のループのスタックに移動し、内側のループが完了したらそれをフェッチすることです。 1 つのカウンター レジスタを使用して、ループごとに異なる反復回数でネストされたループにループすることができます。

しかし、ネストされたループ内のネストされたループはどうでしょうか?

文字で作られたピラミッドを印刷したいS。私が得ているのは、

SSSSSSSSSS
SSSSSSSSS
SSSSSSSS
SSSSSSS
SSSSSS
SSSSS
SSSS
SSS
SS
S

私が実際に欲しいのは、

 SSSSSSSSSS
  SSSSSSSS
   SSSSSS
    SSSS
     SS
     S

ここにプログラムの私のコードがあります

MOV BX,10           ; HOLD 10 IN BX FOR INNER LOOP
     MOV AX,0           ; START ITERATIONS FROM 0
     MOV CX,10          ; MAX NUMBER OF ITERATIONS

    L2:

        PUSH CX         ;PUSH CX IN A STACK
        MOV CX,BX       ;STORE NEW VALUE IN CX FOR INNER LOOP ITERATION

            L1:

                MOV DX, [SI]               ; MOVE THE STRING INTO DX
                MOV AH,02H                 ; DISPLAY EVERYTHING FROM DX
                INT 21H

            LOOP L1

        MOV DX,0AH     ;PRINT LINE FEED AFTER PRINTING EACH LINE OF ASTERIKS
        MOV AH,02H
        INT 21H

        SUB BX,01     ;DECREASE THE VALUE OF BX BY 1

        POP CX        ;RESTORE ORIGINAL VALUE OF CX FOR OUTER LOOP
        ADD AX,01     ;INCREMENT VALUE OF AX BY 1

    LOOP L2


     MOV AH, 4CH                  ;RETURN CONTROL TO DOS
     INT 21H

私が望むものを達成するために、スペース文字 (つまり 020H) を出力するネストされたループ内に別のループを追加する必要があります。しかし、これには別のカウンターレジスターが必要ですが、それができません。どうすればこの問題を解決できますか?

4

2 に答える 2

4

指定された ASM で実行する必要があることは既に実行しています。CX の現在の値をスタックにプッシュ (保存) し、後でポップして復元することができます。追加のネストが必要な場合は、これを行う必要があります。

JohnB が提供したコードでは、アスタリスクを出力する前にスペースを出力するループを追加しただけです。追加のネストは必要ありません。つまり、かなり簡単です。

それはこのようなものです:

For each line
    Print an incrementing number of spaces
    Print a decrementing number of asterisks
Repeat

これはまさに JohnB が示したものです。

于 2012-09-08T08:07:25.477 に答える
3

そのくらい?

L2:

    PUSH CX         ;PUSH CX IN A STACK

    ; insert this
    MOV CX, 10      ; width of your tree = 10
    SUB CX, BX      ; subtract length of "s" string
    SHR CX, 1       ; divide CX by 2 => number of spaces at the beginning
    JCXZ endL3      ; no spaces? don't do anything

       L3:
            MOV DX, 20H ; space character
            MOV AH,02H                 ; print space
            INT 21H

        LOOP L3

    endL3:

    MOV CX,BX       ;STORE NEW VALUE IN CX FOR INNER LOOP ITERATION

        L1:

            MOV DX, [SI]               ; MOVE THE STRING INTO DX
            MOV AH,02H                 ; DISPLAY EVERYTHING FROM DX
            INT 21H

        LOOP L1

    MOV DX,0AH     ;PRINT LINE FEED AFTER PRINTING EACH LINE OF ASTERIKS
    MOV AH,02H
    INT 21H

    SUB BX,01     ;DECREASE THE VALUE OF BX BY 1

    POP CX        ;RESTORE ORIGINAL VALUE OF CX FOR OUTER LOOP
    ADD AX,01     ;INCREMENT VALUE OF AX BY 1

LOOP L2

ところで、どのような目的で AX を初期化およびインクリメントしていますか? とにかくデータを AH/AL に移動するときに上書きします。

于 2012-09-08T07:56:19.443 に答える