Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  nodelist  faq  login

Simulations are like miniskirts, they show a lot and hide the essentials. -- Hubert Kirrman


programming / comp.lang.asm.x86 / Re: 8086 32-bit multiply

SubjectAuthor
* 8086 32-bit multiplyPaul Edwards
+* Re: 8086 32-bit multiplyDJ Delorie
|`- Re: 8086 32-bit multiplyPaul Edwards
+* Re: 8086 32-bit multiplywolfgang kern
|`* Re: 8086 32-bit multiplyPaul Edwards
| +- Re: 8086 32-bit multiplywolfgang kern
| `- Re: 8086 32-bit multiplyAnton Ertl
`* Re: 8086 32-bit multiplyTerje Mathisen
 `- Re: 8086 32-bit multiplyPaul Edwards

1
Subject: 8086 32-bit multiply
From: Paul Edwards
Newsgroups: comp.lang.asm.x86
Organization: A noiseless patient Spider
Date: Fri, 23 Apr 2021 11:42 UTC
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: mutazi...@nospicedham.gmail.com (Paul Edwards)
Newsgroups: comp.lang.asm.x86
Subject: 8086 32-bit multiply
Date: Fri, 23 Apr 2021 04:42:29 -0700 (PDT)
Organization: A noiseless patient Spider
Lines: 56
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <f4c3a346-40ff-47e1-bbc1-8d4b113396d8n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Injection-Date: Fri, 23 Apr 2021 11:42:30 +0000
Injection-Info: reader02.eternal-september.org; posting-host="8b75a9af29a3cc21c9afdf919ee6df2e";
logging-data="14974"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/ybysvhjzVKlACLuUcynjWrQ524u2ieE4="
User-Agent: G2/1.0
Cancel-Lock: sha1:SQgwBwMKd5+tsc+4e4JPwlxJW4Q=
View all headers
Hi.

Since 1994 I have been working on a project to
create a public domain version of MSDOS, called
PDOS. There is an 8086 version and an 80386
version which can be found here:

http://pdos.sourceforge.net/

I took some shortcuts along the way to get it to
work at all, and one of those has finally bitten me.

I'm getting incorrect results from this:

https://sourceforge.net/p/pdos/gitcode/ci/master/tree/pdpclib/dossupa.asm

; multiply cx:bx by dx:ax, result in dx:ax

public __I4M
__I4M:
public __U4M
__U4M:
public f_lxmul@
f_lxmul@ proc
push bp
mov bp,sp
push cx

push ax
mul cx
mov cx, ax
pop ax
mul bx
add dx, cx

pop cx
pop bp
ret
f_lxmul@ endp


Does anyone have some public domain (explicit notice)
8086 (not 80386) code they are willing to share to do
this? Not LGPL. Not BSD. Public domain. The entire
codebase of tens of thousands of lines of code is
public domain.

Also let me know if you wish to be acknowledged in
the source code and/or code check-in. Some people
prefer to remain anonymous.

There are other routines in there that may not work
properly either, but I haven't come across them yet.

Thanks. Paul.



Subject: Re: 8086 32-bit multiply
From: DJ Delorie
Newsgroups: comp.lang.asm.x86
Organization: A noiseless patient Spider
Date: Fri, 23 Apr 2021 23:24 UTC
References: 1
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: dj...@nospicedham.delorie.com (DJ Delorie)
Newsgroups: comp.lang.asm.x86
Subject: Re: 8086 32-bit multiply
Date: Fri, 23 Apr 2021 19:24:37 -0400
Organization: A noiseless patient Spider
Lines: 9
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <xnh7jwy47e.fsf@delorie.com>
References: <f4c3a346-40ff-47e1-bbc1-8d4b113396d8n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: reader02.eternal-september.org; posting-host="6eb5ac35669f02e00548620180d9ecac";
logging-data="27854"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/7Tm3Tb9g9PuHnl18bopoNqtagp5V14MM="
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux)
Cancel-Lock: sha1:GPdjXGQmcVTjVhzyQRBhMIzEbOE=
View all headers
Paul Edwards <mutazilah@nospicedham.gmail.com> writes:
; multiply cx:bx by dx:ax, result in dx:ax

Such would have three multiplies and a few adds:

LSW = bx * ax (lower 16, save upper 16 in XX)

MSW = bx * dx + cx * ax + XX (from lsw)



Subject: Re: 8086 32-bit multiply
From: wolfgang kern
Newsgroups: comp.lang.asm.x86
Organization: Aioe.org NNTP Server
Date: Sat, 24 Apr 2021 00:46 UTC
References: 1
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: nowh...@nospicedham.never.at (wolfgang kern)
Newsgroups: comp.lang.asm.x86
Subject: Re: 8086 32-bit multiply
Date: Sat, 24 Apr 2021 02:46:36 +0200
Organization: Aioe.org NNTP Server
Lines: 13
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <s5vprm$hkg$1@gioia.aioe.org>
References: <f4c3a346-40ff-47e1-bbc1-8d4b113396d8n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="6eb5ac35669f02e00548620180d9ecac";
logging-data="19422"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/VJ307HgjgthMdKdTgrb/osHPKkfUxFNI="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:88.0) Gecko/20100101
Thunderbird/88.0
Cancel-Lock: sha1:n9mN5meMwhsSmlTiYjgqrYNB28o=
View all headers
On 23.04.2021 13:42, Paul Edwards wrote:

[x8086 only]

; multiply cx:bx by dx:ax, result in dx:ax

the result of 32*32 bit doesn't fit into 32 bit.
either go with the given limits (16*16 bit) or
build a cascade with intermediate variables aka
MUL-ADD chains.
__
wolfgang



Subject: Re: 8086 32-bit multiply
From: Paul Edwards
Newsgroups: comp.lang.asm.x86
Organization: A noiseless patient Spider
Date: Sat, 24 Apr 2021 03:16 UTC
References: 1 2
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: mutazi...@nospicedham.gmail.com (Paul Edwards)
Newsgroups: comp.lang.asm.x86
Subject: Re: 8086 32-bit multiply
Date: Fri, 23 Apr 2021 20:16:04 -0700 (PDT)
Organization: A noiseless patient Spider
Lines: 100
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <4bf58eaf-4689-449a-a28b-285c89c49daan@googlegroups.com>
References: <f4c3a346-40ff-47e1-bbc1-8d4b113396d8n@googlegroups.com> <xnh7jwy47e.fsf@delorie.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Injection-Date: Sat, 24 Apr 2021 03:16:05 +0000
Injection-Info: reader02.eternal-september.org; posting-host="6eb5ac35669f02e00548620180d9ecac";
logging-data="6194"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+yiy21t5pcowyAIOlxIZvRQRzuash55Xo="
User-Agent: G2/1.0
Cancel-Lock: sha1:vthMH29oaS+nAl/p3YqtGcg8SR0=
View all headers
On Saturday, April 24, 2021 at 9:36:28 AM UTC+10, DJ Delorie wrote:
Paul Edwards <muta...@nospicedham.gmail.com> writes:
; multiply cx:bx by dx:ax, result in dx:ax
Such would have three multiplies and a few adds:

LSW = bx * ax (lower 16, save upper 16 in XX)

MSW = bx * dx + cx * ax + XX (from lsw)

Thanks for the algorithm! I thought I might be able to do that,
but my brain started to melt down. Here's what I came up with,
which causes a hang, but at least it happened after I got the
results of some calculations. I'll see if I can figure out what
is happening.


; multiply cx:bx by dx:ax, result in dx:ax

public __I4M
__I4M:
public __U4M
__U4M:
public f_lxmul@
f_lxmul@ proc
push bp
mov bp,sp
push bx
push cx
push si
push di

push ax
push bx

; I think this multiples bx * ax and puts the upper 16 bits in ax
; and lower 16 bits in bx
mul bx

; Save upper 16 in si and lower 16 in di
mov si, ax
mov di, bx

; This does the equivalent of bx * dx
pop bx
mov ax, dx
mul bx
mov dx, ax

; Now we do cx * ax with upper 16 bits in ax and lower in cx
pop ax
mul cx

; Now we need to add the results of those two multiplies together
; lower 16 bits first, so we can get the carry
push bp ; ran out of registers!
mov bp, bx
mov bx, ax
mov ax, 1
add dx, cx
jc noone
mov ax, 1
noone:

push ax

; Now the other lower 16 bits we saved
mov ax, 1
add dx, di
jc noone2
mov ax, 1
noone2:

push ax

; Upper 16 bits
mov ax, bx
add bx, ax
pop ax
add bx, ax ; one carry
pop ax
add bx, ax ; the other carry
mov ax, bp
add bx, ax

; store in proper output register
mov dx, bx

pop bp

pop di
pop si
pop cx
pop bx
pop bp
ret
f_lxmul@ endp


BFN. Paul.



Subject: Re: 8086 32-bit multiply
From: Paul Edwards
Newsgroups: comp.lang.asm.x86
Organization: A noiseless patient Spider
Date: Sat, 24 Apr 2021 03:17 UTC
References: 1 2
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: mutazi...@nospicedham.gmail.com (Paul Edwards)
Newsgroups: comp.lang.asm.x86
Subject: Re: 8086 32-bit multiply
Date: Fri, 23 Apr 2021 20:17:33 -0700 (PDT)
Organization: A noiseless patient Spider
Lines: 19
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <ed585f42-3233-4a0c-b236-39189c0811a4n@googlegroups.com>
References: <f4c3a346-40ff-47e1-bbc1-8d4b113396d8n@googlegroups.com> <s5vprm$hkg$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Injection-Date: Sat, 24 Apr 2021 03:17:34 +0000
Injection-Info: reader02.eternal-september.org; posting-host="6eb5ac35669f02e00548620180d9ecac";
logging-data="6218"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+JNgH2P37PejpII2AfIfLfXZlbGyTN7Q4="
User-Agent: G2/1.0
Cancel-Lock: sha1:lqdPmXU86SZgyPMMSBRqNMUQ1RQ=
View all headers
On Saturday, April 24, 2021 at 10:51:35 AM UTC+10, wolfgang kern wrote:

[x8086 only]
; multiply cx:bx by dx:ax, result in dx:ax
the result of 32*32 bit doesn't fit into 32 bit.

Good point. I didn't think of that. I can't multiply
17 bits by 17 bits, one of the registers needs to
be 0. But I assume I need to at least overflow in
a predictable manner.

either go with the given limits (16*16 bit) or
build a cascade with intermediate variables aka
MUL-ADD chains.

See my most recent post. :-)

BFN. Paul.



Subject: Re: 8086 32-bit multiply
From: wolfgang kern
Newsgroups: comp.lang.asm.x86
Organization: Aioe.org NNTP Server
Date: Sat, 24 Apr 2021 08:36 UTC
References: 1 2 3
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: nowh...@nospicedham.never.at (wolfgang kern)
Newsgroups: comp.lang.asm.x86
Subject: Re: 8086 32-bit multiply
Date: Sat, 24 Apr 2021 10:36:46 +0200
Organization: Aioe.org NNTP Server
Lines: 22
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <s60ldb$1otf$1@gioia.aioe.org>
References: <f4c3a346-40ff-47e1-bbc1-8d4b113396d8n@googlegroups.com>
<s5vprm$hkg$1@gioia.aioe.org>
<ed585f42-3233-4a0c-b236-39189c0811a4n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="6eb5ac35669f02e00548620180d9ecac";
logging-data="15180"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+dhgV0xjn60QRc//JON0W0zXFs7vgYpBs="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:88.0) Gecko/20100101
Thunderbird/88.0
Cancel-Lock: sha1:LGVSiLqXgAhOY+Q70yxvOC5tY08=
View all headers
On 24.04.2021 05:17, Paul Edwards wrote:

[x8086 only]
; multiply cx:bx by dx:ax, result in dx:ax
the result of 32*32 bit doesn't fit into 32 bit.

Good point. I didn't think of that. I can't multiply
17 bits by 17 bits, one of the registers needs to
be 0. But I assume I need to at least overflow in
a predictable manner.

either go with the given limits (16*16 bit) or
build a cascade with intermediate variables aka
MUL-ADD chains.

See my most recent post. :-)

you create a stack frame but use not a single variable there.
and it may hang because your stack isn't balanced.
__
wolfgang



Subject: Re: 8086 32-bit multiply
From: Terje Mathisen
Newsgroups: comp.lang.asm.x86
Organization: Aioe.org NNTP Server
Date: Sat, 24 Apr 2021 10:17 UTC
References: 1
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: terje.ma...@nospicedham.tmsw.no (Terje Mathisen)
Newsgroups: comp.lang.asm.x86
Subject: Re: 8086 32-bit multiply
Date: Sat, 24 Apr 2021 12:17:08 +0200
Organization: Aioe.org NNTP Server
Lines: 66
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <s60r6o$9e9$1@gioia.aioe.org>
References: <f4c3a346-40ff-47e1-bbc1-8d4b113396d8n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="6eb5ac35669f02e00548620180d9ecac";
logging-data="19004"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/Ec2b455paouHbHKsZpoaP8vfguqK3xtY="
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101
Firefox/60.0 SeaMonkey/2.53.7
Cancel-Lock: sha1:6BX5W74i0/EK8ZVQOpZQvxY7oH0=
View all headers
Paul Edwards wrote:
Hi.

Since 1994 I have been working on a project to
create a public domain version of MSDOS, called
PDOS. There is an 8086 version and an 80386
version which can be found here:

http://pdos.sourceforge.net/

I took some shortcuts along the way to get it to
work at all, and one of those has finally bitten me.

I'm getting incorrect results from this:

https://sourceforge.net/p/pdos/gitcode/ci/master/tree/pdpclib/dossupa.asm

; multiply cx:bx by dx:ax, result in dx:ax

public __I4M
__I4M:
public __U4M
__U4M:
public f_lxmul@
f_lxmul@ proc
push bp
mov bp,sp
push cx

push ax
mul cx
mov cx, ax
pop ax
mul bx
add dx, cx

pop cx
pop bp
ret
f_lxmul@ endp


As several have noted, the code above is missing at least one MUL!

Please test it, then feel free to use (with or without attribution) this totally untested but reasonably efficent/short code:

mov si,ax
mov di,dx
mul cx ;; hi * lo
xchg ax,di ;; First mul saved, grab org dx
mul bx ;; lo * hi
add di,ax ;; top word of result

mov ax,si ;; retrieve original AX
mul bx ;; lo * lo
add dx,di

At this point DX:AX has the low 32 bits of the multiplication result.

Terje

--
- <Terje.Mathisen at tmsw.no>
"almost all programming can be viewed as an exercise in caching"



Subject: Re: 8086 32-bit multiply
From: Anton Ertl
Newsgroups: comp.lang.asm.x86
Organization: Institut fuer Computersprachen, Technische Universitaet Wien
Date: Sat, 24 Apr 2021 14:01 UTC
References: 1 2 3
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: ant...@nospicedham.mips.complang.tuwien.ac.at (Anton Ertl)
Newsgroups: comp.lang.asm.x86
Subject: Re: 8086 32-bit multiply
Date: Sat, 24 Apr 2021 14:01:21 GMT
Organization: Institut fuer Computersprachen, Technische Universitaet Wien
Lines: 24
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <2021Apr24.160121@mips.complang.tuwien.ac.at>
References: <f4c3a346-40ff-47e1-bbc1-8d4b113396d8n@googlegroups.com> <s5vprm$hkg$1@gioia.aioe.org> <ed585f42-3233-4a0c-b236-39189c0811a4n@googlegroups.com>
Injection-Info: reader02.eternal-september.org; posting-host="6eb5ac35669f02e00548620180d9ecac";
logging-data="20963"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+6spuNU4FCJdGM8n0XRh2FB2sL3SziUlA="
Cancel-Lock: sha1:PUhUZcCCVnh1LhoTEADUaO0053M=
View all headers
Paul Edwards <mutazilah@nospicedham.gmail.com> writes:
On Saturday, April 24, 2021 at 10:51:35 AM UTC+10, wolfgang kern wrote:

[x8086 only]
; multiply cx:bx by dx:ax, result in dx:ax
the result of 32*32 bit doesn't fit into 32 bit.

Good point. I didn't think of that. I can't multiply
17 bits by 17 bits, one of the registers needs to
be 0. But I assume I need to at least overflow in
a predictable manner.

The usual way is to produce the lower 32 bits of the result, i.e.,
produce a*b mod 2^32.  And thanks to the magic of 2s-complement
arithmetic, the result is the same for unsigned multiplication and for
signed multiplication (the results for the high 32 bits would differ,
but you are not interested in that).

- anton
--
M. Anton Ertl                    Some things have to be seen to be believed
anton@mips.complang.tuwien.ac.at Most things have to be believed to be seen
http://www.complang.tuwien.ac.at/anton/home.html



Subject: Re: 8086 32-bit multiply
From: Paul Edwards
Newsgroups: comp.lang.asm.x86
Organization: A noiseless patient Spider
Date: Sat, 24 Apr 2021 21:00 UTC
References: 1 2
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: mutazi...@nospicedham.gmail.com (Paul Edwards)
Newsgroups: comp.lang.asm.x86
Subject: Re: 8086 32-bit multiply
Date: Sat, 24 Apr 2021 14:00:07 -0700 (PDT)
Organization: A noiseless patient Spider
Lines: 69
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <7b8b8132-4e3c-4dc7-95ad-fd6b1e2f4c50n@googlegroups.com>
References: <f4c3a346-40ff-47e1-bbc1-8d4b113396d8n@googlegroups.com> <s60r6o$9e9$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Injection-Date: Sat, 24 Apr 2021 21:00:08 +0000
Injection-Info: reader02.eternal-september.org; posting-host="6eb5ac35669f02e00548620180d9ecac";
logging-data="10318"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/AMu7bZC/s8/Z+VBsdbspEtjwcVH55ehY="
User-Agent: G2/1.0
Cancel-Lock: sha1:ev4f2oh64KZrZVx6dfLhHgtHUDU=
View all headers
On Saturday, April 24, 2021 at 8:22:39 PM UTC+10, Terje Mathisen wrote:
Paul Edwards wrote:
Hi.

Since 1994 I have been working on a project to
create a public domain version of MSDOS, called
PDOS. There is an 8086 version and an 80386
version which can be found here:

http://pdos.sourceforge.net/

I took some shortcuts along the way to get it to
work at all, and one of those has finally bitten me.

I'm getting incorrect results from this:

https://sourceforge.net/p/pdos/gitcode/ci/master/tree/pdpclib/dossupa.asm

; multiply cx:bx by dx:ax, result in dx:ax

public __I4M
__I4M:
public __U4M
__U4M:
public f_lxmul@
f_lxmul@ proc
push bp
mov bp,sp
push cx

push ax
mul cx
mov cx, ax
pop ax
mul bx
add dx, cx

pop cx
pop bp
ret
f_lxmul@ endp

As several have noted, the code above is missing at least one MUL!

Please test it, then feel free to use (with or without attribution) this
totally untested but reasonably efficent/short code:

mov si,ax
mov di,dx
mul cx ;; hi * lo
xchg ax,di ;; First mul saved, grab org dx
mul bx ;; lo * hi
add di,ax ;; top word of result

mov ax,si ;; retrieve original AX
mul bx ;; lo * lo
add dx,di

At this point DX:AX has the low 32 bits of the multiplication result.

Thanks so much!!!

I have tested it and it works fine. I have committed the
change, with attribution:

https://sourceforge.net/p/pdos/gitcode/ci/master/tree/pdpclib/dossupa.asm

BFN. Paul.



1
rocksolid light 0.7.2
clearneti2ptor