whebz
whebz

Reputation: 121

Multiplication in assembly with negative number and result

I am fairly new in Assembly, and I am having a hardtime dealing with negative number

#include <stdio.h>
void main() {
    short int mat1[] = {-1,-2, 4,5, 4,-2}; // first array
    short int mat2[] = {2,0,0,0, 0,2,0,0}; // second array
    int mat3[1024]; // result array

    __asm {
        MOV AX, mat1[0] ; mat1[0]:= -1
        MOV BX, mat2[0] ; mat2[0]:= 2
        ; my problem is how i can do this
        ; mat3[0] = mat1[0] * mat2[0] ;
        ; (operation result -> mat3[0] = -2)
    }
}

p.s. This is for my homework thanks in advance


New Question:

After try some assembly operation:

MOV AX, mat1[ECX]   ; eax is 0 and mat1[ecx] is -1

but after this operation how come AX is set to 65535 and not to -1? How can I do proper multiplication then if AX register is not correct? I am quite confuse how to handle complement of 2.


I got another question. currently I have this code where I move IMUL result to array.

    MOV WORD PTR mat3[ECX*4]+0, AX 
    MOV WORD PTR mat3[ECX*4]+2, DX

My Question is how can I add the IMUL result to the current Array[idx] value?

with this where mat3[current index] = 0, the operation is correct. but when for example mat3[current index] = -2, I a different number to what I expect to get.

    ADD WORD PTR mat3[ECX*4]+0, AX 
    ADD WORD PTR mat3[ECX*4]+2, DX

I thank you in advance for your help

Upvotes: 0

Views: 5257

Answers (1)

John Burger
John Burger

Reputation: 3672

With the 8086 architecture, there are two instructions to multiply two numbers, but different arguments can be used:

Val8   DB  12      ; 8-bit variable
Val16  DW  12345   ; 16-bt variable

MUL    BL         ; Unsigned multiply of 8-bit register
MUL    [Val8]     ; Unsigned multiply of 8-bit memory location
MUL    BX         ; Unsigned multiply of 16-bit register
MUL    [Val16]    ; Unsigned multiply of 16-bit memory location

IMUL   BL         ; Signed multiply of 8-bit register
IMUL   [Val8]     ; Signed multiply of 8-bit memory location
IMUL   BX         ; Signed multiply of 16-bit register
IMUL   [Val16]    ; Signed multiply of 16-bit memory location

But... if it multiplies two variables, where's the second variable? The answer is that the second variable is always AL for 8-bit multiplies, and always AX for 16-bit multiplies.

  • The result of an 8-bit multiply can be up to 16 bits, so it is always stored in AX.
  • The result of a 16-bit multiply can be up to 32 bits! Uh oh! The 8086 doesn't have 32-bit registers! Where does it store the result? In DX:AX. That is, it stores the high 16 bits in DX, and the low 16 bits in AX.

For your code, instead of moving mat2[0] into BX, you could simply IMUL it directly from memory - and yes, you should use IMUL since you want an signed multiply.

Once you have the result of the IMUL, you need to store the result in mat3[0]. Since you cannot move DX:AX with one instruction, you need two. I don't know which assembler you're using, but usually the syntax would be something like this:

MOV WORD PTR mat3[0]+0, AX
MOV WORD PTR mat3[0]+2, DX

Look at the above carefully! mat3[0] is a 32-bit int, so you cannot move a 16-bit register into it. You need to tell the assembler to treat it as WORD (16 bits) first. And to store the high 16 bits that are in DX, you need to put them after AX in memory, thus the +2. (The +0 in the line before is just for symmetry).

Don't forget: the 8086 stores its multi-byte values with the least significant bytes first. That means that you need to store the two parts of the result as I have shown above.

Upvotes: 5

Related Questions