Search code examples
assemblyx86-16fasm

How to get the square of a number in assembly


I am trying to get the square of a number between 0 and 9, and then I will use that number to create the height of the rectangle.

What I've tried is using the sum method Ex: 5*5 = 25 and 5+5+5+5+5 = 25

;Keyboard Input
mov ah, 3Fh
mov bx, 0
mov cx, 1
mov dx, num
int 21h

;Multiplication
sub [num], 48
mov al,[num]
mov bl,[num]
mult:
 add al, [num]
 dec bl
 jnz mult

I am wondering if this correct because when I insert the number 7 (7*7) = 49 I think it exceeds the value of 50 (length of the rectangle);

enter image description here

And when the number 0 is inserted this strange behaviour happens:

enter image description here

Code to create the rectangle:

mov [height], al
mov cx, [pos_x]
mov dx, [pos_y]

loop_y:

 loop_x:
  mov ah, 0ch
  mov al, [cor]
  mov bh, 0
  int 10h
  inc cx
  dec [length]
  jnz loop_x

 inc [pos_y]
 mov dx, [pos_y]
 mov cx, [pos_x]
 mov [length], 50
 dec [height]
 jnz loop_y 

Everything needs to be FASM compatible.


Solution

  •   mov al,[num]
      mov bl,[num]
    mult:
      add al, [num]
      dec bl
      jnz mult
    

    I am wondering if this correct because when I insert the number 7 (7*7) = 49 I think it exceeds the value of 50 (length of the rectangle);

    If you write this multiplication following your addition scheme 7+7+7+7+7+7+7, you will notice that there's 6 additions. Your program performs 7 additions and thus you obtain 56 as your final result!

    You have 2 options.

    • Either you do 1 addition less

        mov al, [num]
        mov bl, [num]
        dec bl
      mult:
        add al, [num]
        dec bl
        jnz mult
      
    • or you start the result (AL) at 0.

        mov al, 0
        mov bl, [num]
      mult:
        add al, [num]
        dec bl
        jnz mult
      

    And when the number 0 is inserted this strange behaviour happens:

    Because the decrement dec bl will wraparound from 0 to 255, this time your program will perform 256 additions of 0, yielding a 0 result.
    Later your drawing routine will use this 0 without checking and also loop 256 times.


    The instruction set has a multiplication instruction. Your code becomes:

    mov al, [num]
    mul al           ; -> AX = AL * AL
    

    Why is the result of the multiplication stored in ax?

    To accomodate the largest possible outcome from a multiplication.
    Consider calculating 255 * 255 whose product is 65025. You need a 16-bit container to store this whole. And it is the AX register because the designer of the CPU chose to use the accumulator exclusively for multiplications via mul. In later generations of the x86 architecture, the imul instruction was enhanced so it could use any of the general purpose registers to hold the result.