数组元素的乘积
Product of array elements
在这个练习中,我需要求数组元素的乘积。我写了下面的程序,但它似乎不起作用。正确答案是 -36288,但我一直得到 49.
我想要的结果是:-7 x 8 x -9 x 6 x 6 x -2。数组中的数字 3 被忽略。
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;
循环遍历数组
这就是遍历数组的基本循环的样子。我相信您老师的循环看起来与这个非常相似。
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
而且因为乘法是可交换的,所以您也可以从末尾开始遍历数组,第 8 个元素的偏移量为 +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
使用什么样的乘法?
这些数字是带符号的数字,因此您必须使用带符号的乘法 imul
。
因为数字 -7、8、-9、6、6 和 -2 的乘积是 -36288,所以您必须使用 imul
的字长版本。这意味着您从数组中读取的带符号字节必须先符号扩展为 AX
,然后才能在乘法中使用它们。
跳过包含的数字 3 只是增加了复杂性。
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
打印这个结果很棘手
您正在为此调用 print_num,但这将失败,因为结果超出了带符号字 [-32768, +32767] 的有效范围。屏幕会显示“29248”。
这里的技巧是在我们输出减号并对 AX
:
中的数字取反后使用无符号版本 print_num_uns
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
在这个练习中,我需要求数组元素的乘积。我写了下面的程序,但它似乎不起作用。正确答案是 -36288,但我一直得到 49.
我想要的结果是:-7 x 8 x -9 x 6 x 6 x -2。数组中的数字 3 被忽略。
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;
循环遍历数组
这就是遍历数组的基本循环的样子。我相信您老师的循环看起来与这个非常相似。
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
而且因为乘法是可交换的,所以您也可以从末尾开始遍历数组,第 8 个元素的偏移量为 +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
使用什么样的乘法?
这些数字是带符号的数字,因此您必须使用带符号的乘法 imul
。
因为数字 -7、8、-9、6、6 和 -2 的乘积是 -36288,所以您必须使用 imul
的字长版本。这意味着您从数组中读取的带符号字节必须先符号扩展为 AX
,然后才能在乘法中使用它们。
跳过包含的数字 3 只是增加了复杂性。
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
打印这个结果很棘手
您正在为此调用 print_num,但这将失败,因为结果超出了带符号字 [-32768, +32767] 的有效范围。屏幕会显示“29248”。
这里的技巧是在我们输出减号并对 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