Reputation: 124
In this exercise, I need to find the product of the array elements. I wrote the following program but it doesn't seem to work. The correct answer is -36288, but I keep getting 49.
The result I'm after is : -7 x 8 x -9 x 6 x 6 x -2. The number 3 in the array is be ignored.
include 'emu8086.inc'
ORG 100h
mov bx, 0
MOV di, 0
cmp b [di+bx], 3
je skip
skip: add di,1
cmp di, 7
jle qemer
qemer: mov Al, b [di + bx]
inc di
imul b [di+bx]
CALL pthis
DB 13, 10, 'Result:', 0
CALL print_num; print number in AX.
RET; return to operating system.
b DB 3,-7,8,-9,6,3,6,-2
DEFINE_SCAN_NUM
DEFINE_PRINT_STRING
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS; required for print_num.
DEFINE_PTHIS
DEFINE_CLEAR_SCREEN
END;
Upvotes: 0
Views: 435
Reputation: 39166
This is how your basic loop that traverses the array looks like. I'm sure your teacher's loop will look very similar to this one.
xor si, si ; Clears offset into the array
More:
mov al, array [si] ; Reads an element
; act on the value
inc si ; Next byte-sized element
cmp si, 8 ; Array has 8 bytes
jb More ; Repeat for all value less than 8
And because multiplication is commutative, you could just as well traverse the array starting at the end, with the 8th element being at offset +7:
mov si, 7 ; Offset into the array to the last element
More:
mov al, array [si] ; Reads an element
; act on the value
dec si ; Next byte-sized element
jns More ; Repeat for all positive values
The numbers are signed numbers, so you'll have to use the signed multiplication imul
.
Because the product of the numbers -7, 8, -9, 6, 6, and -2 is -36288, you'll have to use the word-sized version of imul
. This means that the signed bytes that you read from the array must be sign-extended into AX
before using them in the multiplication.
And skipping the included numbers 3 is just an added complexity.
mov bx, 1 ; Initialize the result with the product-neutral value
xor si, si
More:
mov al, array [si]
cmp al, 3 ; Don't use the number 3
je Skip
cbw ; Sign-extend AL into AX
imul bx ; AX * BX -> DX:AX = {-7, -56, 504, 3024, 18144, -36288}
mov bx, ax ; Update the result in BX
Skip:
inc si
cmp si, 8
jb More
You are calling print_num for this, but this will fail because the result is outside the valid range for a signed word [-32768, +32767]. The screen would show you "29248".
The trick here is to use the unsigned version print_num_uns after we have outputted a minus sign and have negated the number in AX
:
call pthis
db 13, 10, 'Result:', 0
putc '-'
mov ax, bx
neg ax
call print_num_uns
ret
array db 3, -7, 8, -9, 6, 3, 6, -2
DEFINE_SCAN_NUM
DEFINE_PRINT_STRING
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS
DEFINE_PTHIS
DEFINE_CLEAR_SCREEN
END
Upvotes: 2