如何在NASM中根据用户输入打印等边三角形



我正试图根据数字01到99的用户输入,在NASM中打印一个由*组成的等边三角形。因此,如果用户输入99,三角形的最下面一行将有99颗星,然后上面一行有97颗星,然后在那一行上面有95颗星,等等,但它只是制作了一个宽度和长度相同的矩形。如何更改代码,使其打印等边三角形而不是矩形?谢谢你的帮助。

section .data
star: db '*', 1                    
starLen1:  equ $-star  
;endl
newLineMsg: db 0xA, 0xD
newLineLen: equ $-newLineMsg
section .bss
TriangleSize resb 1               ;Holds width of triangle  
TriangleSize2 resb 1 
spacebewteenvalues resb 1   ;take space bwteen values   
loopcounter1 resb 2           ;hold count for first loop    
loopcounter2 resb 2          ;hold count for 2nd loop    
answer2 resb 2               ;hold first digital after times 10 for second input 
answer3 resb 2               ;hold value after plus 2nd digit
section .text
global _start
_start:
mov eax,3           
mov ebx,0         
mov ecx,TriangleSize        
mov edx,1      
int 80h     
mov eax,3           
mov ebx,0         
mov ecx,TriangleSize2        
mov edx,1      
int 80h     
;sub ascii from each digit
sub [TriangleSize], byte '0'
sub [TriangleSize2], byte '0'
;multiply first digit by 10
mov al, [TriangleSize] 
mov bl, 10
mul bl
;move into variable
mov [answer2], ax
;add 2nd digit
mov al, [answer2]
add al, [TriangleSize2]
;move both digit into variable
mov [answer3], al
;convert to decimal
add [answer3], byte '0'

;reset loop
mov [loopcounter1], byte '0'
mov [loopcounter2], byte '1'

;Start to cout *
jmp TriFunction1

;outputs first row
TriFunction1:
;move counter into reigster
mov al, [loopcounter1]
;compare row length then jump to next row
cmp al, [answer3]
je CoutNewline           ;endl
;cout *
mov eax,4           
mov ebx,1          
mov ecx,star      
mov edx,1     
int 80h 
;inc the loop counter
add [loopcounter1], byte 1
;jump back to beginning
jmp TriFunction1

;goes to next row
TriFunction2:
;move 2nd loop counter into register
mov al, [loopcounter2]
;compare 
cmp al, [answer3]
je end      ;when rectangle has finished drawing go back to main
add [loopcounter2], byte 1
;output the next row of *
jmp TriFunction1

;endl
CoutNewline:
;out n
mov edx, newLineLen
mov ecx, newLineMsg
mov ebx, 1
mov eax, 4
int 0x80
;reset loop
mov [loopcounter1], word '0'
;check for next row
jmp TriFunction2

end:
mov eax,1            ; The system call for exit (sys_exit)
mov ebx,0            ; Exit with return code of 0 (no error)
int 80h;

;takes space between user input
takespacebetweennumbers:
mov eax,3            
mov ebx,0            
mov ecx,spacebewteenvalues      
mov edx,1     
int 80h 
ret            ;return back 

尝试绘制预期的输出,然后分析如何实现结果。把一项复杂的任务分成几个小步骤总是更好的。

我从;move both digit into variable:行替换了您代码的尾部

;move both digit into variable
mov [answer3], al
; AL is now binary size of the triangle side (00..99). Examples:
; AL=07  Spaces Asterixes
;   *       3     1
;  ***      2     3
; *****     1     5
;*******    0     7
; AL=08  Spaces Asterixes
;   **     3      2
;  ****    2      4
; ******   1      6
;********  0      8
SECTION .data
Space     DB ' '
Asterix   DB '*'
NewLine   DB 10
SECTION .bss
Spaces    RESB 1
Asterixes RESB 1
Rows      RESB 1
SECTION .text
; Calculate Spaces and Asterixes from triangle Size in AL.
CMP AL,1
JNA end
DEC AL
SHR AL,1           ; AL=(Size-1)/2, CF=1 if Size was even.
MOV [Spaces],AL
MOV AH,1
ADC AH,0           ; Start the 1st row with 1 or 2 asterixes. 
MOV [Asterixes],AH
INC AL
MOV [Rows],AL
NextLine:
CALL PrintSpaces
CALL PrintAsterixes
CALL PrintNewLine
DEC BYTE [Spaces]
ADD BYTE [Asterixes],2
DEC BYTE [Rows]
JNZ NextLine
end:
mov eax,1            ; The system call for exit (sys_exit)
mov ebx,0            ; Exit with return code of 0 (no error)
int 80h;
PrintSpaces:
LEA ECX,[Space]            ; Address of a character to print.
MOVZX EBP,BYTE [Spaces]    ; How many times.
JMP Print
PrintAsterixes:
LEA ECX,[Asterix]          ; Address of a character to print.
MOVZX EBP,BYTE [Asterixes] ; How many times.
JMP Print
PrintNewLine:
LEA ECX,[NewLine]          ; Address of a character to print.
MOV EBP,1                  ; How many times.
Print:
TEST EBP,EBP               ; How many times to repeat the character.
JZ No
MOV EBX,1                  ; Standard output handle.
MOV EDX,1                  ; Print one character addressed by ECX.
NextChar:
MOV EAX,4                  ; Invoke kernel function sys_write.
INT 80h
DEC EBP
JNZ NextChar               ; Repeat EBP times.
No:RET

将绘制菱形而不是三角形的修改:

; AL is now binary size of the diand width side (00..99). Examples:
; AL=07  Spaces Asterixes
;   *       3     1
;  ***      2     3
; *****     1     5
;*******    0     7
; *****     1     5
;  ***      2     3
;   *       3     1
; AL=08  Spaces Asterixes
;   **     3      2
;  ****    2      4
; ******   1      6
;********  0      8
; ******   1      6
;  ****    2      4
;   **     3      2
SECTION .text
; Calculate Spaces and Asterixes from triangle Size in AL.
CMP AL,1
JNA end
DEC AL
SHR AL,1   ; AL=(Size-1)/2, CF=1 if Size was even.
MOV [Spaces],AL
MOV AH,1
ADC AH,0
MOV [Asterixes],AH
INC AL
MOV [Rows],AL
UpperLines:                 ; The upper half of the diamond.
CALL PrintSpaces
CALL PrintAsterixes
CALL PrintNewLine
DEC BYTE [Spaces]
ADD BYTE [Asterixes],2
DEC BYTE [Rows]
JNZ UpperLines
SUB BYTE [Asterixes],2   ; Rollback the middle line of the diamond.
INC BYTE [Spaces]
LowerLines:                 ; The lower half of the diamond.
SUB BYTE [Asterixes],2
INC BYTE [Spaces]
CALL PrintSpaces
CALL PrintAsterixes
CALL PrintNewLine
CMP BYTE [Asterixes],2
JNB LowerLines
end:

相关内容

  • 没有找到相关文章

最新更新