123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- ;; TITLE imul.asm
- ;; imulwat.asm Copyright (C) Codemist Ltd, 1993-2002
- ;;
- ;; This code implements Imultiply and Idivide in 80386 (and up) assembly
- ;; code. The argument passing conventions are as used by Watcom C, so if
- ;; other compilers are used please think about any alterations that are
- ;; thereby needed. Note that I use the register calling convention here.
- ;;
- .386P
- .387
- ;
- ;
- ; unsigned32 Imultiply(unsigned32 *rlow,
- ; unsigned32 a, unsigned32 b, unsigned32 c)
- ; {
- ; /* uns64 is a 64-bit integral type here */
- ; uns64 r = (uns64)a*(uns64)b + (uns64)c;
- ; *rlow = (unsigned32)(r & 0x7fffffff);
- ; return (unsigned32)(r >> 31);
- ; }
- ;
- _TEXT segment dword public 'CODE'
- assume CS:_TEXT
- public Imultiply_
- Imultiply_ proc near
- push EAX
- mov EAX, EBX
- mul EDX
- add EAX, ECX
- adc EDX, 0
- add EAX, EAX
- adc EDX, EDX
- shr EAX, 1
- pop ECX
- mov DWORD PTR [ECX], EAX
- mov EAX, EDX
- ret 0
- Imultiply_ endp
- _TEXT ENDS
- ;
- ; unsigned32 Idiv10_9(unsigned32 *qp, unsigned32 high, unsigned32 low)
- ; {
- ; uns64 p = ((uns64)high << 31) | (uns64)low;
- ; *qp = (unsigned32)(p / (uns64)1000000000U);
- ; return (unsigned32)(p % (uns64)1000000000U);
- ; }
- ;
- _TEXT segment dword public 'CODE'
- assume CS:_TEXT
- public Idiv10_9_
- Idiv10_9_ proc near
- push EAX
- mov EAX, EBX
- shl EAX, 1
- shr EDX, 1
- rcr EAX, 1 ; That glued together 31+31 bits
- mov ECX, 1000000000
- div ECX
- pop ECX
- mov DWORD PTR [ECX], EAX
- mov EAX, EDX
- ret 0
- Idiv10_9_ endp
- _TEXT ENDS
- ;
- ; unsigned32 Idivide(unsigned32 *qp, unsigned32 a, unsigned32 b, unsigned32 c)
- ; {
- ; uns64 p = ((uns64)a << 31) | (uns64)b;
- ; *qp = (unsigned32)(p / (uns64)c);
- ; return (unsigned32)(p % (uns64)c);
- ; }
- ;
- _TEXT segment dword public 'CODE'
- assume CS:_TEXT
- public Idivide_
- _qp$ = 8
- _a$ = 12
- _b$ = 16
- _c$ = 20
- Idivide_ proc near
- push EAX
- mov EAX, EBX
- shl EAX, 1
- shr EDX, 1
- rcr EAX, 1 ; That glued together 31+31 bits
- div ECX
- pop ECX
- mov DWORD PTR [ECX], EAX
- mov EAX, EDX
- ret 0
- Idivide_ endp
- _TEXT ENDS
- END
|