2012-09-08 58 views
3

我有一个汇编语言循环的问题。嵌套在x86程序集的另一个循环中的两个循环

当我们想要使用计数器寄存器循环嵌套循环时,我们首先做的是将计数器寄存器的值移入外部循环的栈中,然后在我们完成内部循环时取回它,这样我们就可以使用一个计数器寄存器在每个循环中循环迭代次数不同的嵌套循环。

但是,嵌套循环内嵌套循环呢?

我想打印由字符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)。但为此我需要另一个计数器寄存器,我无法做到这一点。我怎么解决这个问题?

+2

@JohnB请注意,[作业标签现在正在逐步淘汰,不能再使用](http://meta.stackexchange.com/q/147100)。 – Gilles

回答

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时,您无论如何都会覆盖它。

+0

我正在递增AX以将循环从0增加到10,我做错了吗? – micheller

+0

是的,你是,因为你的“写”操作会破坏AX的价值。但是,这并不重要,因为无论如何您都不使用存储在AX中的值。 – JohnB

+0

我们已经被告知AX值用于定义循环的初始值,即如果Ax = 0,则循环从0开始,直到CX的值。这不正确吗? PS:请详细说明一下你的代码,我会非常感谢,因为我还是一个新手,没有很强的概念 – micheller

4

您已经在做给ASM需要完成的工作。您可以将CX的当前值压入堆栈(保存)并稍后弹出以将其恢复。当您需要额外的嵌套时,您需要执行此操作。

在JohnB提供的代码中,他只是简单地在循环中添加以在打印星号之前打印出空格。不需要额外的嵌套,这意味着它非常简单。

这是一个有点像这样:

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

这正是JohnB已经显示出你。

+0

亚我看到他的帖子,但我需要它更简单,我试过你的算法,如何循环内两个循环可以相反我的意思是1增加和其他正在减少,我设法让两个循环递减 – micheller

+0

然后添加一个“if “打印空间或S-es。在实现愿望清单方面我看不出多少意义。 – JohnB

+0

您可以为每个字符创建两个单独的寄存器,但最终会耗尽寄存器。如果你看看JohnB在做什么,他正在做这个数学运算来得到空格的数量:'(width - numAsterisks)/ 2'。 –