Reputation: 121
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
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.
AX
.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