在程序集中打印星形三角形

问题描述:

我试图打印出如下这样的三角形:in assembly。 查找每行中恒星数量的公式是:2 * x + 1. 这是我的代码。我似乎无限循环。在程序集中打印星形三角形

.data 
prompt BYTE "Please enter the number of rows in the pyramid: ", 0 
numRows DWORD ? 
count DWORD 0 

.code 
main PROC 
    mov edx, OFFSET prompt 
    call WriteString 
    call ReadInt 

    mov numRows,eax       
    mov ecx,numRows + 1     ; Let ecx = numRows + 1 
L1: 
    inc count       ; Increment count 
    mov eax,ecx 

    L2: 
     sub eax,count     ; eax = eax - count 
     mov al, ' '      ; Print spaces 
     call WriteChar 
     loop L2 
    L3: 
     mov ebx,count     ; ebx = count 
     add ebx,count     ; ebx = ebx + count 
     sub ebx,1      ; 2x - 1 
     mov al, '*'      ; Printing the star pattern 
     call WriteChar 
     loop L3 

    call CrLf 
    loop L1 

exit 
main ENDP 
END main 

我在哪里出错了?

虽然这不是完整的答案,它得到的评论太长了,应该极大地帮助你,因为:

http://kipirvine.com/asm/debug/index.htm

这基本上是你要学习的东西第一(和过于宽泛+长时间成为这个答案的一部分)。


后,您将知道如何使用调试器,你可以看看你的代码是干什么的,例如第一个问题,你会打:

mov ecx,numRows + 1不会做你认为它确实,你不能在汇编中使用数学表达式,你必须将它们编写成单个指令。

只有一些指令允许某种非常严格和有限的数学表达式,如mov用于寻址内存模式,这实际上是您在编译时得到的结果:mov ecx,[numRows + 1] =从+1地址获取值。 numRows是DWORD,所以如果用户确实输入10,内存看起来像这样(从numRows开始地址:0A 00 00 00 00 00 00 00 - 前4个字节由mov numRows,eax设置(Irvine在内存引用周围写入时没有[]),这是IMO非常糟糕的风格/味道)第5个字节是count地址,它是由count DWORD 0行定义的,所以有4个归零字节,现在mov ecx,[numRows + 1]将从内存中取出4个0,从0A字节开始,并将一个字节“泄漏”到count

数学表达式在编译时也是允许的,例如add eax,12+13*14是可以的,在汇编期间产生单个常量,但是您应该阅读文档this想知道哪些参数组合是合法的,mov ecx,label + 1既可以是MASM中的立即恒定负载(在NASM中)=“地址+ 1”或存储器负载(地址+1中的值),也不是“值+ 1” 。

做你想做什么,你需要:

mov ecx,[numRows] ; load the VALUE numRows back into ecx 
inc ecx   ; ecx = numRows+1 

但随着EAX已经包含numRows值,就可以避免取内存,所以在这种特殊情况下,这已经足够了:

mov ecx,eax  ; copy the numRows value from eax into ecx 
inc ecx   ; ecx = numRows+1 

但是,由于此数学表达式足够小以适合可能的寻址模式之一,因此您可以利用LEA instruction来认为它正在计算内存地址,而它只会计算您的表达式:

lea ecx,[eax+1] ; ecx = value_numRows + 1 

这工作,即使EAX + 1是非法的地址到内存中,但LEA不会尝试读取的地址,它只是计算并存入目的寄存器。

...等等...这里的要点为您的是:

1)学会调试代码(这是绝对必要的,以取得任何进一步)

2)沟欧文的风格和使用[]严格周围的每一个记忆间接引用,即围绕“变量“,如果你想写mov ecx,[numRows]+1(如果你知道哪个操作数是合法的,你应该觉得这看起来不太好),这可能会让你更快地抓住你的脑袋。

3)试着用“变量”的方式将你的想法转移到更低层次的“内存 - >地址 - >内容(字节)”,“变量”的方式有时会限制你看到机会如何操作你的数据在字节/位级别以更简单的方式达到您所需要的结果。

+1

我希望我可以做另一个upvote,只为评论“沟欧文风格,严格使用[]” – Tommylee2k