-3

I need to draw a square in assembly x86. I know how to draw a square but my problem is that I have a lot of variables and I don't want to make a procedure for each 2 variables (x and y). I added an example where I define the x and the y. This is what I tried to do:

proc ChangeColumn4Number4
    inc [FourthColumnArray + 3]
    mov [Player1Drawx], 85h
    mov [Player1Drawy], 27h
    jmp DrawPlayer1Disc
endp ChangeColumn4Number4

DrawPlayer1Loop:
    mov bh,0h
    mov cx,[Player1Drawx]
    mov dx,[Player1Drawy]
    mov al,[player1disccolor]
    mov ah,0ch
    int 10h
    add [Player1Drawx], 1h
    mov ax, dx
    add ax, 14h
    cmp dx, ax
    jl DrawPlayer1Loop

DrawPlayer1Disc: 
    mov bh, 0h
    mov dx, [Player1Drawy]
    add [Player1Drawy], 1h 
    mov ax, dx
    add ax, 14h
    cmp dx, ax
    jl DrawPlayer1Loop

Someone from this site guided to do it this way but it doesn't work. Thanks for help.

KatomPower
  • 119
  • 1
  • 3
  • 14
  • In the first loop, what exactly is the point of moving the y-coordinate to `ax`, adding `14h` and comparing it with the original value? The branch `jl` will never be taken. – Weather Vane Jun 25 '16 at 16:44
  • @WeatherVane Thanks for answering. I thought about it before and I was sure that I didn't understand it correctly because the person that told me to do so had like 4000 reputation. What am I supposed to do instead of it to fix it? I have been sitting all day breaking my head trying to fix it. – KatomPower Jun 25 '16 at 16:49
  • The dimension of the square does not seem to appear in the code. You should iterate the x-coordinate until it reaches (startx + dimension). At the same time you can plot the other parallel edge with the other y-coordinate (starty + dimension). Then you repeat the exercise for the vertical edges. – Weather Vane Jun 25 '16 at 16:54
  • @WeatherVane I didn't add the part where I defined the x and the y because I felt like it is unnecessary. I will add that to my code right now. – KatomPower Jun 25 '16 at 16:56
  • You did not state whether you want a filled square or an outline. I assumed outline, but the answer has it filled. – Weather Vane Jun 25 '16 at 17:09
  • @WeatherVane Yes, the square is filled. Do you have any suggestions or ideas of how to fix my code so it will work? – KatomPower Jun 25 '16 at 17:12
  • A pair of nested loops. Suppose top left is at `p, q`. The outer loop iterates the `y` coordinate, the inner iterates the `x` coordinate. Each inner loop starts at x-coordinate `p` and iterates `side` times. After each inner `x` loop you add `1` to the `q` coordinate, and the outer loop also iterates `side` times. – Weather Vane Jun 25 '16 at 17:24
  • @WeatherVane I understand how it is supposed to work, my problem is that I do not know how to implement it with what I want to do because of the number of variables. – KatomPower Jun 25 '16 at 17:29
  • If you have already 2 variables for drawing a square, why can't you have 4 (p, q, side, colour)? I fail to understand your problem. – Weather Vane Jun 25 '16 at 17:36
  • @WeatherVane I have x, y and color variables (I don't understand what side means). I think you don't understand because I didn't upload all of my code (it is about 1200 lines long). I will try to explain it to you again. The board is 4x4 which means 16 squares. Instead of making a procedure for each square on the board to draw a square (the disc in the game) I want to make x and y variables and for them to each time be placed inside those two loops. – KatomPower Jun 25 '16 at 17:42
  • By `side` I mean the length of the side of the square. Get a pencil and paper and draw a flow chart of what you want to happen. – Weather Vane Jun 25 '16 at 17:46
  • @WeatherVane Again, I know what I want to do, I just don't know why it doesn't work and how to do it. All I am asking from anyone here is to fix my code. I have a project due to tomorrow and this is the only thing that doesn't work and because of it the whole project gets ruined. The length doesn't really matter because I can play with the numbers and see when it forms a square. – KatomPower Jun 25 '16 at 17:58
  • I told you in the very first comment. Your test for ending the x loop is wrong. I can't "fix it" for you, since there is not enough information, for example the side length. How you can be trying to draw a simple square on the last day of the project is beyond me, unless it is also the first day. – Weather Vane Jun 25 '16 at 18:01
  • @WeatherVane I have been working for this project for about a week. Before I thought that what I did is right and so I didn't check it because I didn't want to waste any time. That is really not important right now for me to see why I didn't do this before and why I didn't check it. The side is +14h longer than the original x and y. What more information do you need? I can upload the more code but I doubt that you will want to read it moreover understand it. – KatomPower Jun 25 '16 at 18:08
  • Have you even tried using the solution from @MargaretBloom who invited you try it "as is"? As for not wasting timne by checking code: the way to build it is step by step, checking every step as you go. Otherwise you end up with a tangle of code that does not work, and you have no idea where to begin debugging it. testing does not waste time, it saves it. – Weather Vane Jun 25 '16 at 18:08
  • @WeatherVane I didn't because I have never used stack functions and xor. I'm having an impression that you think that I am dumb as a rock but I am really tired and truly desperate, I just want to finish my code. – KatomPower Jun 25 '16 at 18:12
  • *The side is +14h longer than the original x and y.* I am sorry that is nonsense. And I do not think you are dumb or you would not be asking questions here. I suggest you go for a half hour walk, then have another try. – Weather Vane Jun 25 '16 at 18:16
  • @WeatherVane Thank you for putting up with me. It is currently 21:16 in Israel and the project is due 12:00 AM tomorrow. I have to finish this and make a project book which explains EVERYTHING. I don't understand why that it dumb. Let's say the x and y of the square starts at 20h. I want to make it to 0A0h (I am explaining the board of my project, I am making the game connect four), So instead of putting the value, I am adding 80h. Is that not how it works? – KatomPower Jun 25 '16 at 18:19
  • @WeatherVane IT WORKED I CAN'T BELIEVE IT!!!!! Thank you so much, you just made my day. I think I will be able to make it to change turns by myself. If not I know who to contact, unless you are tired of me :) – KatomPower Jun 25 '16 at 19:00
  • You are welcome, thanks for the upvote. That's how we show appreciation here. However if you have any bitcoins to spare... – Weather Vane Jun 25 '16 at 19:30
  • @WeatherVane I would gladly give it to you but unfortunately I don't have PayPal nor credit card :(. Would you like to help me a bit more or are you exhausted from me? – KatomPower Jun 25 '16 at 19:33

2 Answers2

2

Use this code, either as a template, starting point or as it:

;X          +0ah
;Y          +08h
;Size       +06h
;Color      +04h
drawSquare:
 push bp
 mov bp, sp

 pusha                      ;Push all, can replace with single pushes

 mov ax, WORD [bp+04h]   
 mov ah, 0ch                ;AH = 0ch, AL = Color

 xor bx, bx                 ;Page 0
 mov dx, WORD [bp+08h]      ;DX = Y coord

 mov si, WORD [bp+06h]      
 mov di, si
 add di, dx                 ;DI = Size + Y
 add si, WORD [bp+0ah]      ;SI = Size + X

__ds_drawSquare:
  mov cx, WORD [bp+0ah]     ;CX = X Coord

___ds_drawRow:

   int 10h

   add cx, 01h              ;Increment X coord
   cmp cx, si
  jb ___ds_drawRow          ;Stay in the same row if X < Initial X + Size 

  add dx, 01h               ;Increment Y coord
  cmp dx, di
 jb __ds_drawSquare         ;Keep drawing rows if Y < Initial Y + Size

 popa                       ;See pusha above

 pop bp
 ret 08h

The code is simple enough to require no further explanations.
Parameters are passed on the stack, here an usage case

BITS 16

ORG 100h

mov ax, 0013h
int 10h

push 10
push 30
push 40
push 0ch
call drawSquare

push 20
push 80
push 30
push 06h
call drawSquare

push 200
push 100
push 60
push 09h
call drawSquare

push 270
push 140
push 50
push 07h
call drawSquare

push 10
push 30
push 40
push 0ch
call drawSquare

push 30
push 110
push 40
push 03h
call drawSquare

xor ah, ah
int 16h

mov ax, 4c00h
int 21h

Which produces

Squares on the screen

Code is for NASM, adapt it to whatever assembler you use.


Drawing inside the video buffer range is your responsibility.

Margaret Bloom
  • 41,768
  • 5
  • 78
  • 124
  • Thanks for the help. I am kinda new to assembly x86 and I use TASM so whatever you wrote in NASM is like Chinese to me. Can you by any chance adapt it to TASM? – KatomPower Jun 25 '16 at 17:16
  • 2
    The syntax of Margaret's assembly code is pretty much like yours. Perhaps the difficulty is her label nomenclature, or the register addressing, which show how you can pass the arguments via the stack, instead of having fixed memory locations for them. Notice how she pushes the arguments for each different square onto the stack, which are retrieved by the function using register `BP`. This is quite standard practice, and uses `BP` the way the processor designers intended. – Weather Vane Jun 25 '16 at 17:52
2

Adapting your code. This needs four variables: the top left coordinates, the colour, and the square size. I also show how the square size can be hard coded. I wrote it blind since I don't have any DOSBOX - hope it works so you can use it.

DrawSquare:
    mov dx,[Player1Drawy]       ;top edge
    mov di,[SideLength]         ;control y loop
    ;mov di,14h                  ;or this, if the side length is fixed

SquareYloop:
    mov cx,[Player1Drawx]       ;left edge
    mov si,[SideLength]         ;control x loop
    ;mov si,14h                  ;or this, if the side length is fixed

SquareXloop:
    push cx                     ;I don't know if these 4 pushes are necessary...
    push dx
    push si
    push di

    mov bh,0h                   ;video page
    mov al,[player1disccolor]   ;colour
    mov ah,0ch                  ;draw pixel function
    int 10h                     ;BIOS video interrupt

    pop di                      ;... or these 4 matching pops are necessary
    pop si                      ;depends on whether int 10h func corrupts them
    pop dx
    pop cx

    inc cx                      ;advance X position
    dec si                      ;count side of square to control the loop
    jne SquareXloop             ;next horizontal pixel

    inc dx                      ;advance Y position
    dec di                      ;count side of square to control the loop
    jne SquareYloop             ;next row
Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • 1
    ";I don't know if these 4 pushes are necessary..." Not needed: never have I seen any register corruption from this BIOS function 0Ch. – Sep Roland Jan 29 '23 at 20:39