jane
jane

Reputation: 124

Product of array elements

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

Answers (1)

Sep Roland
Sep Roland

Reputation: 39166

Traversing the array with a loop

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

What kind of multiplication to use?

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

Printing this result is tricky

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

Related Questions