Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.1k views
in Technique[技术] by (71.8m points)

assembly - 32-bit extended multiplication via stack

This is the code I have been using to implement extended multiplication of two 32-bit numbers. Is there a way to implement the similar logic by making a subroutine and using stack via parameter passing? Either with MUL instruction or without it ? Can anyone help?

[org 0x0100]
jmp start

multiplicand: dd 123122,0
multiplier:   dd 66341
result:       dd 0,0

start:
initialize:   mov cl,32 

              mov bl,1
checkbit:     test bl,[multiplier]
              jz skip

multiply:     mov ax, [multiplicand]
              add [result],ax
              mov ax, [multiplicand+2]
              adc [result+2], ax
              mov ax, [multiplicand+4]
              adc [result+4], ax
              mov ax, [multiplicand+6] 
              adc [result+6], ax      

skip:         shl bl,1               
              shr word [multiplier+2],1 
              rcr word [multiplier],1 

              shl word [multiplicand],1 
              rcl word [multiplicand+2],1 
              rcl word [multiplicand+4],1 
              rcl word [multiplicand+6],1 
              dec cl
              jnz checkbit

              mov ax, 0x4c00
              int 0x21
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
[org 0x0100]
jmp start

multiplicand: dd 123122
multiplier:   dd 66341
result:       dd 0

start:
    push word [multiplier+2]
    push word [multiplier]
    push word [multiplicand+2]
    push word [multiplicand]
    call multiply
    add sp, 8            ; free arguments
    mov [result], ax     ; expect result in dx:ax
    mov [result+2], dx

    mov ax, 0x4c00
    int 0x21

multiply:
    push bp
    mov bp, sp

    mov ax, [bp+4]
    mul word [bp+8]      ; xl * yl
    mov cx, [bp+4]
    imul cx, [bp+10]     ; xl * yh
    add dx, cx
    mov cx, [bp+6]
    imul cx, [bp+8]      ; xh * yl
    add dx, cx

    mov sp, bp
    pop bp
    ret

It's not clear whether you need a 64 bit result, the above code produces 32 bits.

A 64 bit version may look like this:

[org 0x0100]
jmp start

multiplicand: dd 123122
multiplier:   dd 66341
result:       dd 0, 0

start:
    push word [multiplier+2]
    push word [multiplier]
    push word [multiplicand+2]
    push word [multiplicand]
    push result           ; pointer for result
    call multiply
    add sp, 10            ; free arguments

    mov ax, 0x4c00
    int 0x21

multiply:
    push bp
    mov bp, sp
    push bx

    mov bx, [bp+4]       ; result

    mov ax, [bp+6]
    mul word [bp+10]     ; xl * yl
    mov [bx], ax         ; r0
    mov [bx+2], dx       ; r1

    mov ax, [bp+6]
    mul word [bp+12]     ; xl * yh
    add [bx+2], ax       ; r1
    adc dx, 0
    mov [bx+4], dx       ; r2

    mov ax, [bp+8]
    mul word [bp+10]     ; xh * yl
    add [bx+2], ax
    adc [bx+4], dx       ; carry into the highest limb is possible here
    mov dx, 0            ; inefficient but doesn't affect FLAGS
    adc dx, 0            ; setc dl
    mov [bx+6], dx       ; r3

    mov ax, [bp+8]
    mul word [bp+12]     ; xh * yh
    add [bx+4], ax       ; r2
    adc [bx+6], dx       ; r3

    mov ax, bx           ; return result
    pop bx
    mov sp, bp
    pop bp
    ret

(More efficient might be to keep the results of both of the last two multiplies in registers before adding, so we can avoid storing and then doing a memory-destination adc.)

Disclaimer: I have just backported the usual 32 bit convention, whereby an extra hidden argument is used to point to a caller reserved location for the result, which pointer is also returned. This code works, but no idea if 16 bit compilers really used this convention.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...