Question

So as an excercise from my textbook, I'm trying to code a program in assembly for Intel 8080 which will be printing a scalable image of three triangles facing down in the upper row and two facing up in the bottom row. Something like that, to be precise:

*****************************
 *******   *******   *******
  *****     *****     *****
   ***   *   ***   *   ***
    *   ***   *   ***   *
       *****     *****
      *******   *******
     *******************
(when user selects the height variable = 5)

and:

*****************************************  
 ***********   ***********   ***********
  *********     *********     *********  
   *******   *   *******   *   *******
    *****   ***   *****   ***   ***** 
     ***   *****   ***   *****   ***
      *   *******   *   *******   *
         *********     *********
        ***********   ***********
       ****************************
(when user selects the height variable = 7)

As an assembly-novice, though, I'm having a really hard time imagining the implementation of something like this using only six registers and also bearing in mind the unfriendliness of the language itself. The best I could come up with is:

We know that the first row is 6*height-1 so no problem with that. The problem begins later, though: it seems that we have to keep track of (I'll give them some names for simplicity):
- outer_margin - the number of spaces on the left and right of the outer triangles. It increments with each line but then it won't work after drawing the upper triangles so we'd need a new value in the register
- inner_spaces - spaces between the triangles. First, they'd be 3, 5 and then three until we get to the bottom of the lower triangles - the problem is that they'd have to appear more often after the first two lines
- up_star_counter - keeeping track of the stars to print for each of the upper triangles in the line
- down_star_counter - same but for the triangles in the bottom row
- row - keeping track of the row so that I know when to start using a set of labels which will print the bottom triangles as well
- height - the variable which holds the height of each triangle, as inputted by the user

That gives us six values for six registers (and free accumulator) which doesn't look too optimistic. Also the implementation of this seems to be a nightmare. Is there something I'm missing here that would somehow simplify the task or is it just as hard as it looks?

Was it helpful?

Solution

What you are missing here is that there is free memory where you have plenty of space to store variable data.

You can look here for more information, but in short, dw, dd, and db, (define initialized word/double/byte) or resb, resw, resq (define uninitialized byte/word/real) will create a space for a variable in your program. For example, this program will create space for a byte at the beginning that will be referenced with myvar, and it will contain 5. (NASM Syntax)

[BITS 16]                           
[ORG 0x7C00]                        
jmp Start

myvar dw 5                  

Start:
    mov word bx, [myvar]

End:
    jmp $                   

times 510-($-$$) db 0           
dw 0xAA55   

An important thing to note here is that we skip the code that actually has the statement dw in it. This statement is jmp'd over int the code above. So now myvar (referenced with brackets) can be used just like an ordinary word.

The 6 registers are meant to be used for for loops, counting, jumps, etc. Variable space in memory can be used to store a huge amount of data, including the variables that you outlined and more.

About the language unfriendliness, I find it much easier to flesh out assembly code by making a working example in C, and then by creating a similar assembly code example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top