Search code examples
assemblyx86nasmmultiplicationbigint

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

Solution

  • I guess, your issue is the lack of arithmetic functions for SP, e.g. [sp + 4]. You can use BP instead. In your own assembly function you are free how to pass arguments and result. I'll show you a way to pass arguments by stack and get the result on stack:

    BITS 16
    ORG 0x0100
    
    jmp start
    
    multiplicand: dd 123122,0                   ; 0102 0x0001E0F2 -> 0x00000000
                                                ; 0106 0x00000000 -> 0x0001E0F2
    multiplier:   dd 66341                      ; 010A 0x00010325 -> 0x00000000
    result:       dd 0,0                        ; 010E 0x00000000 -> 0x0023B1F6
                                                ; 0112 0x00000000 -> 0x00000000
    
    start:
                push word [multiplicand + 6]    ; bp + 22
                push word [multiplicand + 4]    ; bp + 20
                push word [multiplicand + 2]    ; bp + 18
                push word [multiplicand + 0]    ; bp + 16
    
                push word [multiplier + 2]      ; bp + 14
                push word [multiplier + 0]      ; bp + 12
    
                push word [result + 6]          ; bp + 10
                push word [result + 4]          ; bp + 8
                push word [result + 2]          ; bp + 6
                push word [result + 0]          ; bp + 4
    
                call sub_mul
    
                pop word [result + 0]           ; Pop stack into `result`
                pop word [result + 2]
                pop word [result + 4]
                pop word [result + 6]
                add sp, 12                      ; Clean up the rest of the stack                        ;
    
                mov ax, 0x4c00
                int 0x21
    
    sub_mul:
                push bp                         ; Prolog
                mov bp, sp
    
    initialize:   mov cl,32
    
                  mov bl,1
    checkbit:     test bl,[bp + 12]
                  jz skip
    
    multiply:     mov ax, [bp + 16]
                  add [bp + 4],ax
                  mov ax, [bp + 18]
                  adc [bp + 6], ax
                  mov ax, [bp + 20]
                  adc [bp + 8], ax
                  mov ax, [bp + 22]
                  adc [bp + 10], ax
    
    skip:         shl bl,1
                  shr word [bp + 14],1
                  rcr word [bp + 12],1
    
                  shl word [bp + 16],1
                  rcl word [bp + 18],1
                  rcl word [bp + 20],1
                  rcl word [bp + 22],1
                  dec cl
                  jnz checkbit
    
            leave                           ; Epilog
            ret