gpt4 book ai didi

assembly - 将两个无符号 16 位值相乘,不使用乘法或除法指令 [8086 汇编]

转载 作者:行者123 更新时间:2023-12-02 19:43:57 25 4
gpt4 key购买 nike

我目前正在做一项作业,其中我编写了一个子例程,其中两个无符号数字相乘并产生 DX:AX 对中的结果。但我无法使用指令 mul、imul、div 和 idiv。当我运行代码时,下半部分(AX 寄存器)始终正确,但 DX 寄存器不正确。谁能指出我做错了什么的正确方向?

;-----------------------------------------------------------
;
; Program: MULTIPLY
;
; Function: Multiplies two 16 bit unsigned values ...
; .... duplicating the MUL instruction
;
; Input: The two values to be multiplied are passed on the stack
; The code conforms to the C/C++ calling sequence
;
; Output: The 32 bit result is returned in the dx:ax pair
; Registers required by C/C++ need to be saved and restored
;
; Owner: Andrew F.
;
; Changes: Date Reason
; ------------------
; 07/20/2013 Original version
;
;
;---------------------------------------
.model small
.8086
public _multiply

.data
;---------------------------------------
; Multiply data
;---------------------------------------


.code
;---------------------------------------
; Multiply code
;---------------------------------------
_multiply:
push bp ; save bp
mov bp,sp ; anchor bp into the stack
mov ax,[bp+4] ; load multiplicand from the stack
mov dx,[bp+6] ; load multiplier from the stack

push bx
push cx
push di
;---------------------------------------
; copy ax to cx, and dx to bx
;---------------------------------------
mov cx,ax ;using bx and cx as my inputs
mov bx,dx
;---------------------------------------
; Check for zeros, zero out ax and dx
;---------------------------------------
start:
xor ax,ax ; check for multiplication by zero
mov dx,ax ; and zero out ax and dx
mov di,cx ;
or di,bx ;
jz done ;
mov di,ax ; DI used for reg,reg adc
;---------------------------------------
; loop / multiply algorithm
;---------------------------------------
loopp:
shr cx,1 ; divide by two, bottom bit moved to carry flag
jnc skipAddToResult ;no carry -> just add to result
add ax,bx ;add bx to ax
adc dx,di ;add the carry to dx

skipAddToResult:
add bx,bx ;double bx current value
or cx,cx ; zero check
jnz loopp ; if cx isnt zero, loop again


;---------------------------------------
; Restore register values, return
;---------------------------------------
done:
pop di ;restore di
pop cx ;restore cx
pop bx ;restore bx

pop bp ; restore bp
ret ; return with result in dx:ax
;
end ; end source code
;---------------------------------------

最佳答案

在添加 bx 的另一个移位值时,您奇怪地使用了 di。你的算法似乎是这样的:

  1. 收集值,将其放入 BX 和 CX 中。
  2. 当 CX>0 时:
    1. 向右移动 CX。
    2. 如果移位后的位为 1,则将 BX 添加到 AX,并将 DI(DI 中有零?)添加到 DX(带进位)。
    3. 将 BX 添加到 BX。
  3. 返回 DX:AX。

在 CX 的每次右移之后,您会丢失 DI:BX 的左移。您仅移动 BX(我会使用 shl bx,1 而不是 add bx,bx),而 DI 保持为零,因此当 BX 超过 16 位时,您丢失应该发送到 DX 的位。要解决此问题,请对 DI 使用循环进位。

loopp:
shr cx,1 ; divide by two, bottom bit moved to carry flag
jnc skipAddToResult ;no carry -> just add to result
add ax,bx ;add bx to ax
adc dx,di ;add the carry to dx

skipAddToResult:
shl bx,1 ;double bx current value
rcl di,1 ; and put overflow bits to DI
; this together doubles the number in DI:BX
or cx,cx ; zero check
jnz loopp ; if cx isnt zero, loop again

关于assembly - 将两个无符号 16 位值相乘,不使用乘法或除法指令 [8086 汇编],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31541537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com