Loops 两个循环嵌套在x86程序集中的另一个循环中
我在汇编语言中遇到了一个循环问题 当我们想在嵌套循环中使用计数器寄存器进行循环时, 我们首先要做的是将计数器寄存器的值移动到外部循环的堆栈中,然后在处理内部循环时将其取回,这样我们就能够使用一个计数器寄存器循环到嵌套循环中,每个循环的迭代次数不同 但是嵌套循环中的嵌套循环呢 我想打印一个由字符Loops 两个循环嵌套在x86程序集中的另一个循环中,loops,assembly,nested-loops,tasm,Loops,Assembly,Nested Loops,Tasm,我在汇编语言中遇到了一个循环问题 当我们想在嵌套循环中使用计数器寄存器进行循环时, 我们首先要做的是将计数器寄存器的值移动到外部循环的堆栈中,然后在处理内部循环时将其取回,这样我们就能够使用一个计数器寄存器循环到嵌套循环中,每个循环的迭代次数不同 但是嵌套循环中的嵌套循环呢 我想打印一个由字符S组成的金字塔。我得到的是 SSSSSSSSSS SSSSSSSSS SSSSSSSS SSSSSSS SSSSSS SSSSS SSSS SSS SS S 我真正想要的是 SSSSSSSSSS S
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)。但为此,我需要另一个计数器寄存器,但我不能这样做。我怎样才能解决这个问题呢?像那样吗
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时,您仍然会覆盖它。您已经在执行给定ASM中需要执行的操作。您可以将CX的当前值推送到堆栈(保存)中,稍后再弹出以恢复它。当需要额外嵌套时,需要执行此操作 在JohnB提供的代码中,他只是在打印星号之前添加了一个循环以打印出空格。不需要额外的嵌套,这意味着它相当直接 有点像这样:
For each line
Print an incrementing number of spaces
Print a decrementing number of asterisks
Repeat
这正是JohnB向你展示的。ya我看到了他的帖子,但我需要更简单的,我尝试了你的算法,一个循环中的两个循环是如何相反的,我的意思是1在增加,另一个在减少,我设法使两个循环都递减,然后添加一个“如果”打印空格或S-E。我认为实现愿望清单没有多大意义。你可以为每个字符创建两个单独的寄存器,但最终你会用光所有的寄存器。如果你看看JohnB在做什么,他在做一些数学运算来得到空格数:
(width-numAsterisks)/2
。他可以使用DX:如果(要打印的空格){MOV-DX,space}或者{MOV-DX,s};写入DX代码>我正在递增AX以将循环从0递增到10,我做错了吗?是的,你做错了,因为你的“写”操作破坏了AX的值。但是,这并不重要,因为您无论如何都不使用AX中存储的值。我们被告知,AX值用于定义循环的初始值,即如果AX=0,则循环从0开始,一直到CX的值。这不是真的吗?附言:请您对您的代码添加详细的注释,我非常感谢,因为我还是一个新手,没有很强的概念。不,循环递减CX,如果CX不为零,则跳转,请参见此处:它不必与AX做任何事。@JohnB请注意。