【问题标题】:How do I perform bitwise multiplication/division in MASM x86 assembly? [closed]如何在 MASM x86 程序集中执行按位乘法/除法? [关闭]
【发布时间】:2014-10-10 17:39:18
【问题描述】:

我的任务是编写一个 MASM x86 汇编程序,该程序通过位移来乘/除两个 16 位数字。到目前为止我所拥有的是:

INCLUDE Irvine32.inc

.data
count BYTE -1
val1  SDWORD  ?  
val2  SDWORD  ?
str1  BYTE "Enter Integer 1 here: ",0 ; 
str2  BYTE "Enter Integer 2 here: ",0
str3  BYTE "The product is: ",0
mval WORD ?
mval2 WORD ?
pval WORD ?

.code
call clrscr
main PROC
    mov dh,10
    mov dl,20
    call Gotoxy
    mov edx, OFFSET str1
    call WriteString
    call ReadInt
    mov mval,ax

    mov dh,12
    mov dl,20
    call Gotoxy
    mov edx, OFFSET str2
    call WriteString
    call ReadInt
    mov mval2,ax

    mov dh, 14
    mov dl, 20
    call Gotoxy
    mov edx, OFFSET str3
    call WriteString
    mov ax,pval
    call WriteInt
    call crlf
    call waitmsg

    mov eax,0
    mov ax,mval2
    mov ecx, 16

    L1:
    shr bx,1
    INC count
    JNC DontAdd

    push ecx
    mov ax,mval
    mov cl,count
    shl dx,cl
    add ax,dx
    pop ecx

    DontAdd:
    LOOP L1
    call waitmsg
    exit
main ENDP
END main

如何正确实现按位乘法/除法?

【问题讨论】:

标签: assembly bit-manipulation masm irvine32


【解决方案1】:

您现在应该使用过程来跟踪代码。看看这个 32 位的例子,把它转换成 16 位:

INCLUDE Irvine32.inc

.data

    First       DWORD ?
    Second      DWORD ?
    Result      DWORD ?
    GetFirst    BYTE "1st number: ",0
    GetSecond   BYTE "2nd number: ",0
    Linefeed    BYTE 13, 10, 0
    MulSign     BYTE " * ",0
    DivSign     BYTE " / ",0
    EquSign     BYTE " = ",0

.code
main PROC

    mov edx, OFFSET GetFirst
    call WriteString
    call ReadDec
    mov First, eax

    mov edx, OFFSET GetSecond
    call WriteString
    call ReadDec
    mov Second, eax

    mov ebx, First
    mov eax, Second
    call BitwiseMultiply
    mov Result, eax

    mov eax, First
    call WriteDec
    mov edx, OFFSET MulSign
    call WriteString
    mov eax, Second
    call WriteDec
    mov edx, OFFSET EquSign
    call WriteString
    mov eax, Result
    call WriteDec
    mov edx, OFFSET Linefeed
    call WriteString

    mov eax, First
    mov ebx, Second
    call BitwiseDivide
    mov Result, eax

    mov eax, First
    call WriteDec
    mov edx, OFFSET DivSign
    call WriteString
    mov eax, Second
    call WriteDec
    mov edx, OFFSET EquSign
    call WriteString
    mov eax, Result
    call WriteDec
    mov edx, OFFSET Linefeed
    call WriteString

    exit
main ENDP

; Multiply EBX by EAX
BitwiseMultiply PROC USES EBX ECX EDX
    mov edx, eax            ; EDX: multiplier (EBX: multiplicand)
    xor eax, eax            ; Result will be in EAX - clear it
    bsr ecx, edx            ; ECX = position of the most significant bit
    jz R1                   ; Return with EAX=0 if EDX == 0

    L1:
    shr edx, 1              ; Look at the rightmost bit of the multiplier
    jnc @F                  ; Skip addition if this bit == 0
    add eax, ebx            ; Add multiplikand to result
    @@:
    shl ebx, 1              ; Increase multipland for the next round
    sub ecx, 1              ; Decrease loop variable
    jnc L1                  ; Loop if ECX >= 0

    R1:
    ret                     ; Result in EAX
BitwiseMultiply ENDP

; Divide EAX by EBX
BitwiseDivide PROC USES ECX EDX ESI
    mov esi, eax            ; ESI: dividend (EBX: divisor)
    xor eax, eax            ; Result (quotient) = 0
    xor edx, edx            ; EDX = 0 (start value)
    mov cl, 32              ; 32 loops

    L1:
    shl esi, 1              ; Bit 31 from EAX ...
    rcl edx, 1              ;     ... to Bit 1 of EDX
    cmp ebx, edx            ; Carry, if EDX > Divisor
    ja @F                   ; Skip subtraction if carry==0 and zero==0 (result not zero)
    sub edx, ebx            ; Subtract ...
    stc                     ;     ... and set carry
    @@:
    rcl eax, 1              ; Append carry (0 or 1) to quotient.
    sub cl, 1
    jnz L1                  ; loop while CL > 0

    ret                     ; Result in EAX
BitwiseDivide ENDP

END main

【讨论】:

  • 你会为除法做同样的事情吗?
  • 等待我需要做什么?我尝试投票;它没有工作。不过我确实接受了。
  • 好酷酷谢谢你帮助我。这是我的第一堂编程课,所以我学到了很多东西。
  • 您的乘法并不适用于所有情况。例如,在 eax 中传递 2 和在 ebx 中传递 7 会得到 14,但在 eax 中传递 7 和在 ebx 中传递 2 会得到 6。
猜你喜欢
  • 2010-12-23
  • 1970-01-01
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多