I have a project where I want to enter a number and say I enter 3, it gives you an output of,
ZYX**XYZ
ZY****YZ
Z******Z
And a 5 will give you
ZYXWV**VWXYZ
ZYXW****WXYZ
ZYX******XYZ
ZY********YZ
Z**********Z
In my project I don't think my instructor will allow me to use an array, or at least not yet but here is my idea.
I was thinking of making a string for the number so say I get a 3. I would produce ZYX* and simply reverse it to get the other half of the triangle. Only thing is, I don't know how to change the letters one at a time to the stars. I'm thinking of using loops to do it but not sure how to do it. I just know that the next string would be ZY** and then simply reverse it.
Don't get me wrong, I'm not asking you all to do it for me but maybe give me some pointers or tips on how to approach it. thank you.
So far, thanks to you all, I have been able to come up with this.
TITLE MASM Template (main.asm)
; Description:
;
; Revision date:
INCLUDE Irvine32.inc
.data
x DWORD ?
msg BYTE "Please input a number: " ,0dh,0ah,0
.code
;crlf
main PROC
call Clrscr
MOV edx, OFFSET msg ; Moves message to input number into register
call WriteString ; Displays message on screen to prompt user to input number
call readInt ; Take the number that the user inputs
MOV x,eax ; Store it into x
MOV ecx, eax ; For the loop counter
MOV al, 'Z' ; Move Z to the register
L2:
MOV al, 'Z' ; Resets al to z for loop
L1: ; Start of the loop with label L1
call WriteChar ; To write the letters
;call crlf ; To put in 'enter'
SUB al, 1 ; To Move the next char going downward
LOOP L1
MOV al, ' '
call WriteChar
MOV ecx, x ; Resets ecx for outside loop
SUB x, 1 ; Decrements x for counter
call crlf ; To be tidy
LOOP L2
exit
main ENDP
END main
Now I just need the other side.
Welcome to the blackest of the black computer arts - Assembler!
Let's look at this problem from an Assembler programmer's point of view.
You have a number, let's say BL ('cause that's a good Assemblerish name) and what you want to do is produce BL lines of output. Let's say BL=5
Now, CX is really good as a counter register, so if we copy BL to CL and clear CH by XORing it with itself, we have CX=#lines too.
The number of characters we have to print before reversing is conveniently one more than this, so we could increment CX - and that's an important number, so save it in say, BP
Each line consists of the letters 'Z' down to ('Z' - BH + 1) and one asterisk, then the same in reverse, and a new line. And every new line, you reduce the number of letters printed by one and add one to the number of asterisks.
To produce one line, we'd
We want to print a count of letters, so if we copy BP into CX, that should be useful.
Here's something we want to do CX times:
Then we need to output another BP bytes, so sopy BP to CX again
Here's something we want to do CX times:
Then send CR and LF
So - what's the twist?
Well, if the character in DL is LESS THAN or EQUAL TO the character in BH, we want to substitute an asterisk, so
Done that line - decrement the count of lines in BL; if the result is non-zero, produce another line
Note here that by decrementing the count of lines in BL, the number subtracted from DL at the start of the produce-a-line routine decrements, so the 'change to aster' value becomes 'V', 'W'...
Now let's get downright kinky.
You'll note that the only difference between the two write-CX-characters routines is that one DECREMENTS and the other INCREMENTS DL...
Let's set SI to 0FFFFH and DI to 1 before we start, just for laughs.
Now - DH is sitting on the bench for this entire game.
Suppose we write the routine to print CX characters such that it ADDs SI to DX. That will give us the decrement we need in the loop the first time.
Useful, huh?
Oh, and while we're twisting, we can get DH involved by using it to store DL rather than pushing DX and popping it back. Move DL to DH, test for substituting the aster, write out and restore DL from DH.
So - the point with this routine is that it doesn't rely on a string in storage...