我正试图根据数字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: