0

我试图在 MASM x86(我使用 8086)上找到两个用户输入数字的平均值。我似乎无法计算平均值!我可以让这两个数字相乘,但我不知道如何将它们相加,然后将它们除以数字的总数(在我的情况下它只有 2)。这是我到目前为止所拥有的(是的,我意识到我在相乘,但这只是表明我确实尝试了一些东西,我只是不能让他们加和除总和):

.model small
org 100h
.data

num1 db ?
num2 db ?
result db ? 
usermsg db "Enter EVEN numbers only.$"
msg1 db 13, 10, "Enter first number: $"
msg2 db 13, 10, "Enter second number: $"
msg3 db 13, 10, "The average is: $"

.code

main proc
mov ax, @data
mov ds, ax

lea dx, usermsg
mov ah, 09h
int 21h

lea dx, msg1
mov ah, 09h
int 21h

mov ah, 01h
int 21h

sub al, '0'
mov num1, al 
mov dl, al

lea dx, msg2
mov ah, 09h
int 21h

mov ah, 01h
int 21h
sub al, '0'
mov num2, al

mul num1


;add al, num1

mov result, al


idiv result, 2 ;new code
aam

add ah, '0'
add al, '0'
mov bx, ax

lea dx, msg3
mov ah, 09h
int 21h

mov ah, 02h
mov dl, bh
int 21h
mov dl, bl
int 21h

mov ax, 4c00h
int 21h
4

2 回答 2

3

只需将您的号码添加到寄存器中并除以即可。如果它们足够小以使总和不会溢出,那么这很容易。

如果您提前知道您只是平均 2 个数字(或 2 的任何幂),请使用移位除法。

...  your original code that gets two digits from the user
sub   al, '0'
; first number in [num1] in memory, second number in al
; We know they're both single-digit numbers, so their sum will fit in 8bits


add   al, [num1]    ; or whever you put num1: a register like cl would be a good choice, instead of memory
shr   al, 1         ;  al = al/2  (unsigned)

;; al holds the average.  Do whatever else you want.

mov   [result], al  
add   al, '0'       ; convert back to ASCII

您可以在不减去和重新添加的情况下平均两个 ASCII 数字'0',以保存指令。如果asc='0'(即 0x30),则

  (a+asc + b+asc) / 2
= (a+b)/2 + (asc+asc)/2
= (a+b)/2 + asc        i.e. the average as an ASCII digit

因此:

add  al, [asciidigit1]
shr  al, 1

例如'5' + '8' = 0x6d. 0x6d>>1 = 0x36 = '6'


您的问题idiv

没有任何形式idiv需要立即操作数。被除数是隐式的,除数是一个显式操作数。商进入 AL,余数进入 AH。(这与 的相反AAM,它接受立即操作数,但只除 AL,而不是 AX)。

请参阅另一个问题的答案,我在该问题中演示了使用divaam将整数转换为两个 ASCII 数字(并使用 DOS 系统调用打印它们,因为那是该问题的 OP 想要的)。

另请参阅标签 wiki 中的其他链接。

于 2016-05-16T06:07:51.420 回答
-1

不太了解asm,但是您确定可以这样使用idiv吗?

这个:http ://www.electronics.dit.ie/staff/tscarff/8086_instruction_set/8086_instruction_set.html#IDIV 说你会将“结果”加载到 AX 中,然后进入 idiv 2,结果将进入 AL。所以我想你会尝试

;add al, num1

movzx ax, al
mov   dl, 2
idiv  dl

然后 AL 将包含除法的结果(商),而 AH 将包含余数。


或者,因为您要除以 2,所以您应该只右移 1。目标可以是寄存器或内存

shr result,1

将“结果”右移 1 位并将答案存储在“结果”中

于 2016-05-16T05:31:14.210 回答