简体   繁体   English

组装-(NASM 32位)打印一个三角形的星形不能正常工作

[英]Assembly - (NASM 32-bit) Printing a triangle of stars not working properly

EDIT: This problem is already solved. 编辑:这个问题已经解决。 Many thanks to mbratch. 非常感谢mbratch。

My code outputs: 我的代码输出:

电流输出

But it should display this: 但是它应该显示以下内容:

预期产量

I think problem is in the innerloops but I can't fix it, it works properly on the first loop but not on the succeeding ones. 我认为问题出在内部循环中,但我无法解决,它可以在第一个循环中正常运行,但不能在后续循环中正常运行。

Here's my code: 这是我的代码:

innerloop1: ;;for(j=n-i;j>0;j--)
mov bl, [i]
sub byte [num], bl
mov dl, [num]
mov byte [j], dl
cmp byte [j], 0
jle printStar

mov eax, 4
    mov ebx, 1
    mov ecx, space
    mov edx, spaceLen
    int 80h
dec dl
    jmp innerloop1

printStar:
mov eax, 4
    mov ebx, 1
    mov ecx, star
    mov edx, starLen
    int 80h

innerloop2: ;;for(k=0;k<(2*i)-1;k++)
mov al, [i]
mul byte [two]
dec al
cmp byte [k], al
jge printMe

mov eax, 4
    mov ebx, 1
    mov ecx, space
    mov edx, spaceLen
    int 80h

    inc byte [k]
    jmp innerloop2

printMe:
mov eax, 4
    mov ebx, 1
    mov ecx, star
    mov edx, starLen
    int 80h

    mov eax, 4
    mov ebx, 1
    mov ecx, newLine
    mov edx, newLineLen
    int 80h

    inc byte [i]
    jmp outerloop

    printSpace:
mov eax, 4
    mov ebx, 1
    mov ecx, space
    mov edx, spaceLen
    int 80h

There are lots of inefficiencies in your code and it could be much more clearly and concisely written. 您的代码中有很多低效率的地方,可以更清楚,简洁地编写它。 However, I'll just address the areas that are causing a functional problem. 但是,我将仅解决引起功能问题的区域。

There are a couple of problems with innerloop1 . innerloop1有两个问题。 You are modifying [num] every time through the loop. 您每次通过循环都在修改[num] Instead, you want to do it prior to the loop as an initializer for j . 相反,您想在循环之前作为j的初始化器执行此操作。 Secondly, you are counting on the value of dl being intact through the execution of the loop, but your mov edx, spaceLen clobbers it, as might the call to int 80h . 其次,您希望通过执行循环来保持dl的值不变,但是mov edx, spaceLen破坏它,就像对int 80h的调用一样。 So you can correct it by this: 因此,您可以通过以下方式纠正它:

    mov dl, [num]       ; INITIALIZE j=n-i
    sub dl, byte [i]
innerloop1: ;;for(j=n-i;j>0;j--)
                        ; REMOVED modification of 'num' here
    mov byte [j], dl
    cmp byte [j], 0
    jle printStar

    mov eax, 4
    mov ebx, 1
    mov ecx, space
    push dx             ; SAVE dx
    mov edx, spaceLen
    int 80h
    pop dx              ; RESTORE dx
    dec dl
    jmp innerloop1

In your second inner loop ( innerloop2 ) you are relying on the pre-initialized value of k every time you enter the loop, which is no longer valid after the first time the loop is encountered.. So you must initialize it each time: 在您的第二个内部循环( innerloop2 )中,您每次进入循环时都依赖于k的预初始化值,该值在第一次遇到循环后不再有效。因此,您每次都必须对其进行初始化:

    mov byte [k], 0   ; INITIALIZE k=0
innerloop2: ;;for(k=0;k<(2*i)-1;k++)
    mov al, [i]
    mul byte [two]
    dec al
    cmp byte [k], al
    jge printMe

This all makes the code work. 所有这些使代码正常工作。 Some additional comments: 一些其他评论:

  • You need to be cautious about counting on the values of registers and watch where they may get altered 您在计数寄存器的值时需要谨慎,并注意它们可能在何处被更改
  • You should probably not rely on pre-initialized declarations to initialize loop variables or other data that can vary for that matter. 您可能不应该依赖预初始化的声明来初始化循环变量或其他可能与此相关的数据。 It's generally good practice to explicitly initialize a value in code if you're going to change it regularly 如果要定期更改代码中的值,通常是一个好习惯
  • Think about how to optimize your code (make it more concise and clear) now that it basically works. 既然基本可以正常工作,请考虑如何优化代码(使其更加简洁明了)。
  • Be more consistent in variable usage. 在变量用法上更加一致。 Your asm program used num for what was n but also defined a value n , which was a little confusing. 您的asm程序使用num表示n但还定义了一个值n ,这有点令人困惑。
  • Be consistent in your code indentation and spacing. 代码缩进和间距保持一致。 It will make it much easier to read. 这将使它更容易阅读。
  • When doing constructs, such as for loops, try to maintain a consistent approach to doing them every time. 在进行构造(例如for循环)时,请尝试保持每次执行时的一致方法。 It will reduce the chance of errors. 它将减少出错的机会。 For example, manage the loop variables in the same or similar ways. 例如,以相同或相似的方式管理循环变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM