123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- TITLE imul.asm
- ;; imuldos.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 Zortech C, so if
- ;; other compilers are used please think about any alterations that are
- ;; thereby needed.
- ;;
- .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
- _rlow$ = 8
- _a$ = 12
- _b$ = 16
- _c$ = 20
- _Imultiply proc near
- mov EAX, DWORD PTR _b$[ESP-4]
- mul DWORD PTR _a$[ESP-4]
- mov ECX, DWORD PTR _rlow$[ESP-4]
- add EAX, DWORD PTR _c$[ESP-4]
- adc EDX, 0 ; carry into top half
- add EAX, EAX
- adc EDX, EDX
- shr EAX, 1
- mov DWORD PTR [ECX], EAX
- mov EAX, EDX
- ret 0
- nop
- nop
- _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
- _qp$ = 8
- _high$ = 12
- _low$ = 16
- _Idiv10_9 proc near
- mov EDX, DWORD PTR _high$[ESP-4]
- mov EAX, DWORD PTR _low$[ESP-4]
- shl EAX, 1
- shr EDX, 1
- rcr EAX, 1 ; That glued together 31+31 bits
- mov ECX, 1000000000
- div ECX
- mov ECX, DWORD PTR _qp$[ESP-4]
- mov DWORD PTR [ECX], EAX
- mov EAX, EDX
- ret 0
- nop
- nop
- _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
- mov EDX, DWORD PTR _high$[ESP-4]
- mov EAX, DWORD PTR _low$[ESP-4]
- shl EAX, 1
- shr EDX, 1
- rcr EAX, 1 ; That glued together 31+31 bits
- mov ECX, DWORD PTR _c$[ESP-4]
- div ECX
- mov ECX, DWORD PTR _qp$[ESP-4]
- mov DWORD PTR [ECX], EAX
- mov EAX, EDX
- ret 0
- nop
- nop
- nop
- _Idivide endp
- _TEXT ENDS
- END
|