我正在尝试创建一个代码,我会在其中获取用户输入,将其转换为循环并显示三角形。
;; using a nested loop create a triangle
section .data
global _start
prompt db "Enter number of lines you'd like: ",10 ;;declare constant string that points to ’string’ 10 equates to the line character
promptLen equ $-prompt ;; This returns the length of the string
char db ' ' ; declare char to store asterisks and newlines
segment .bss
num1 resb 1
section .text
_start:
mov eax,4 ;; Move the system call 4 to the register eax to say ouput
mov ebx,1 ;; put the value 1 in the register ebx - standard output to the screen
mov ecx, prompt ; Put the offset of string in ecx register so we can access the string and the new line character
mov edx, promptLen ;; put the length of the string into the register
int 80h ; Call the operating system with an interrupt. The operating system checks the registers and performs the operation to write to screen
mov eax,3 ; system call input
mov ebx, 0 ; stand input
mov ecx, num1 ; store inputted value in num1 - note ascii value and should be between 1-9
mov edx, 1 ; size of input value in bytes
int 80h ; call kernel with interrupt to receive value
mov rax, [num1] ; move value in num1 into rax
sub rax, 48; subtract 48 from value so now it is integer and not ascii value
mov [num1], rax ; move value back into num1 use ax for the row counter
mov rax, [num1]; move num1 into rax to set the size of the outer loop - rows of triangle
outer_loop: ; use ax for the row counter
mov rbx, [num1] ; move num1 into rbx to set the size of the inner loop
inner_loop: ;; draw a asterisk
call asterisk ;; subtract from the counter and repeat if we haven't hit 0 for inner loop
dec bx
cmp bx,0
jg inner_loop ;; go on to next line
call linefeed ; subtract from the counter and repeat if we haven't hit 0 for outer loop
dec ax
cmp ax,0
jne outer_loop ;; go to next line
call linefeed ;; exit cleanly
exit:
mov eax,1; system call to exit
mov ebx,0; exit value
int 80h; call kernel with interrupt to exit program
ret;; new line code section
linefeed:
;; move newline character into char
mov [char], byte 10
push rax; push rax on to stack to allow outer loop to
; occur
push rbx; push rbx on to stack to allow inner loop to
; occur
mov eax,4; system call to write out
mov ebx,1; standard out to screen
mov ecx, char; go to next line on screen
mov edx,1; size of new line
int 80h; interrupt to kernel to go to next line by
; looking into registers
pop rbx; push rax on to stack to allow outer loop to
; occur
pop rax; push rbx on to stack to allow inner loop to
; occur
ret
asterisk:
mov [char], byte '*'; put asterisk (*) in char
push rax; push rax on to stack to allow outer loop to occur
push rbx; push rbx on to stack to allow inner loop to occur
mov eax,4; system call to write out
mov ebx,1; standard out to screen
mov ecx, char; put asterisk in register ecx
mov edx,1; size of asterisk in register
int 80h; interrupt to kernel to print asterisk on screen by looking into registers
pop rbx
pop rax
ret
是的,我知道它不干净,但我正在努力学习如何为新行添加角色。
最终结果看起来应该更像这样。
**(在新行中按星号)
***(在另一个新行中按星号然后依此类推)
如何在循环中使用push命令执行此操作?
答案 0 :(得分:0)
同时我会解决这个问题:
break
这是32位x86程序集,要编译+运行,将其保存到 ; NOT using a nested loop create a triangle
; rather using line buffer to buffer the I/O operations to make it faster
section .data
prompt db "Enter number of lines you'd like: ",10
promptLen equ $-prompt ;; This returns the length of the string
section .bss
linebuffer resb 100
section .text
global _start
_start:
mov eax,4
mov ebx,1
mov ecx, prompt
mov edx, promptLen
int 80h ; sys_write(STD_OUT, prompt, promptLen)
mov eax,3
xor ebx,ebx
mov ecx,linebuffer ; reusing future linebuffer also for user input
mov edx,1
int 80h ; sys_read(STD_IN, linebuffer, 1)
; linebuffer now contains single ASCII character from user -> size
movzx esi,byte [linebuffer]
sub esi,'0' ; esi = size of pyramid
; init values for line-loop, first data-like things
mov edi,linebuffer ; address where next asterisk should be written
mov edx,1 ; number of chars to be displayed (line size) (1 = new line)
; init fixed values for outputting lines through "int 80h"
mov ebx,1 ; STD_OUT
mov ecx,linebuffer ; address of linebuffer
pyramid_loop:
cmp edx,esi ; already big enough line printed?
ja pyramid_done
; prepare line buffer by adding another asterisk, and increment line size
mov [edi],word `*\n` ; does also add new <new line> char at end
inc edi ; update address to write next asterisk
inc edx ; increase size of current line (line size)
; display the prepared line buffer
mov eax,4 ; sys_write (has to be set again, sys_write return value modifies it)
int 80h ; sys_write(STD_OUT, linebuffer, "line size")
jmp pyramid_loop
pyramid_done:
mov eax,1 ; system call to exit
xor ebx,ebx ; 0 exit code
int 80h
:
ppp.asm
我留下了一些关于特定指令的注释,但是你应该能够自己解释它的工作原理,或者在循环期间观察调试器中内存内容的变化。