【发布时间】:2018-08-26 19:42:00
【问题描述】:
我需要得到以下输出:
*
**
***
****
*****
******
*******
********
*********
**********
所以它有 10 行,我的星星将从 1 开始到 10。
目前我得到:
**********
***********
************
*************
**************
***************
****************
*****************
******************
*******************
********************
我的代码:
section .data
char db ' '
trianglesize db 0; ;stars per line
trianglerows db 10;
section .text
global _start
_start
mov rax, [trianglerows] ;rows
outer_loop:
mov rbx, [trianglerows]
inner_loop:
call star
dec bx
cmp bx,0
jg inner_loop
call newline
call down_triangle
dec ax
cmp ax, 0
jne outer_loop
call newline
call exit
exit:
mov eax,1 ;sys_exit
mov ebx,0 ;return 0
int 80h;
ret
newline:
mov [char],byte 10
push rax;
push rbx;
mov eax,4; ;sys_write
mov ebx,1; ;stdout
mov ecx, char;
mov edx,1; ;size of new line
int 80h
pop rbx;
pop rax;
ret
star:
mov [char], byte '*';
push rax;
push rbx;
mov eax,4; ;sys_write
mov ebx,1; ;stdout
mov ecx, char;
mov edx,1;
int 80h;
pop rbx;
pop rax;
ret
down_triangle:
push rax;
push rbx;
mov rax, [trianglerows]
inc ax
mov [trianglerows],rax
pop rbx
pop rax
ret
我尝试了又尝试了,但我无法得到我需要得到的东西。
由于所有这些push 和pop,我似乎无法找到将行与星行分开的方法。
老实说,我不太了解这些。我被告知执行循环需要它们,但我不确定为什么,例如,在函数star 中我需要调用外部循环。
我找不到任何有效的 push 和 pop 组合。我经常得到很多星或每行一颗星或只有一颗星。
我真的很困惑我正在更改哪些位并保持不变。我能够获得所需的输出,但输出永远不会增加。
我能够获得从 10 星开始下降到 1 星的输出,但不是我想要的。
我做错了什么?这道题怎么做?
【问题讨论】:
-
使用调试器来查看自己更改了哪些位以及更改的位置。使用instruction reference guide 阅读您使用的每条指令,以交叉检查您在调试器中观察到的内容。如果您在第一次尝试时没有完全理解所有内容,请不要担心,请继续重新阅读和重新检查。另外,尝试找到更好的教程/书籍作为开始。您可以从 MASM tutorial 开始,然后 NASM/YASM 在语法上有一些差异,但这在 NASM 文档中有所介绍:nasm.us/doc
-
顺便说一句,如果你是个厚脸皮的混蛋,你可以用定义为
starline: db '**********',10(即10个星和换行符)的单个字符串输出10行三角形,输出(sys_write)从第一行的地址 starline+9 到最后一行的 starline+0,第一行只有 2 个字符,然后是 3 个字符,等等……或者为了更有趣,您可以先将整个多行字符串生成到内存中然后以单写方式输出,等等……有数百万种方法。继续努力。 -
@Ped7g 这真的不是我第一次尝试,我解释过。这周的大部分时间我都在尝试这样做。这就是给我的所有工作和理解。我正在使用 Linux 终端来执行此操作,那里有什么调试器可用..?我也必须使用循环来实现这一点。我在这里寻求实际的帮助,究竟是什么导致我的代码出现故障?
-
另外现在我注意到你在 64b 模式下使用
int 0x80,这是非法滥用 linux 内核仁 stackoverflow.com/q/46087730/4271923 所以你的 "all that were given to me"包含错误信息,或者您没有正确遵循它。另外,在尝试学习汇编代码时,仅遵循您的官方资源是荒谬的。使用你能找到的任何东西(你也会发现很多 BS,所以继续大圈运行并同时检查几件事情,过滤掉没有希望/低质量的东西)。调试器:gdb是基于文本的(需要时间来学习控制) -
将其用于更多的指针和资源:stackoverflow.com/tags/x86/info .... 编辑:顺便说一句,至少有一些帮助,我会告诉你至少第一条指令你有错误执行后你的代码。第一个错误在
mov rax, [trianglerows](将加载 8 字节值而不是定义的单个字节,使用而不是movzx eax,byte [trianglerows]将 8 位值零扩展为 32 位eax,这将自动清除rax的高 32 位,因为这就是 x86_64 的工作方式)。 ……没多久……嗯。