File: dos\mpmath_a.asm
1 TITLE mpmath_a.asm (C) 1989, Mark C. Peterson, CompuServe [70441,3353]
2 SUBTTL All rights reserved.
3 ;
4 ; Code may be used in any program provided the author is credited
5 ; either during program execution or in the documentation. Source
6 ; code may be distributed only in combination with public domain or
7 ; shareware source code. Source code may be modified provided the
8 ; copyright notice and this message is left unchanged and all
9 ; modifications are clearly documented.
10 ;
11 ; I would appreciate a copy of any work which incorporates this code,
12 ; however this is optional.
13 ;
14 ; Mark C. Peterson
15 ; 405-C Queen St., Suite #181
16 ; Southington, CT 06489
17 ; (203) 276-9721
18 ;
19 ; Note: Remark statements following floating point commands generally indicate
20 ; the FPU stack contents after the command is completed.
21 ;
22 ; References:
23 ; 80386/80286 Assembly Language Programming
24 ; by William H. Murray, III and Chris H. Pappas
25 ; Published by Osborne McGraw-Hill, 1986
26 ;
27 ;
28 ;
29
30
31 IFDEF ??version
32 MASM51
33 QUIRKS
34 ENDIF
35
36 .model medium, c
37
38
39 .data
40
41 extrn cpu:WORD
42
43
44 MP STRUC
45 Exp DW 0
46 Mant DD 0
47 MP ENDS
48
49
50 PUBLIC MPOverflow
51 PUBLIC Ans
52 MPOverflow DW 0
53
54 Ans MP >
55 Double DQ ?
56
57
58 .code
59
60 .8086
61
62 fg2MP086 PROC x:DWORD, fg:WORD
63 mov ax, WORD PTR [x]
64 mov dx, WORD PTR [x+2]
65 mov cx, ax
66 or cx, dx
67 jz ExitFg2MP
68
69 mov cx, 1 SHL 14 + 30
70 sub cx, fg
71
72 or dx, dx
73 jns BitScanRight
74
75 or ch, 80h
76 not ax
77 not dx
78 add ax, 1
79 adc dx, 0
80
81 BitScanRight:
82 shl ax, 1
83 rcl dx, 1
84 dec cx
85 or dx, dx
86 jns BitScanRight
87
88 ExitFg2MP:
89 mov Ans.Exp, cx
90 mov WORD PTR Ans.Mant+2, dx
91 mov WORD PTR Ans.Mant, ax
92 lea ax, Ans
93 mov dx, ds
94 ret
95 fg2MP086 ENDP
96
97
98
99 MPcmp086 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, yMant:DWORD
100 LOCAL Rev:WORD, Flag:WORD
101 mov Rev, 0
102 mov Flag, 0
103 mov ax, xExp
104 mov dx, WORD PTR [xMant]
105 mov si, WORD PTR [xMant+2]
106 mov bx, yExp
107 mov cx, WORD PTR [yMant]
108 mov di, WORD PTR [yMant+2]
109 or ax, ax
110 jns AtLeastOnePos
111
112 or bx, bx
113 jns AtLeastOnePos
114
115 mov Rev, 1
116 and ah, 7fh
117 and bh, 7fh
118
119 AtLeastOnePos:
120 cmp ax, bx
121 jle Cmp1
122
123 mov Flag, 1
124 jmp ChkRev
125
126 Cmp1:
127 je Cmp2
128
129 mov Flag, -1
130 jmp ChkRev
131
132 Cmp2:
133 cmp si, di
134 jbe Cmp3
135
136 mov Flag, 1
137 jmp ChkRev
138
139 Cmp3:
140 je Cmp4
141
142 mov Flag, -1
143 jmp ChkRev
144
145 Cmp4:
146 cmp dx, cx
147 jbe Cmp5
148
149 mov Flag, 1
150 jmp ChkRev
151
152 Cmp5:
153 je ChkRev
154
155 mov Flag, -1
156
157 ChkRev:
158 or Rev, 0
159 jz ExitCmp
160
161 neg Flag
162
163 ExitCmp:
164 mov ax, Flag
165 ret
166 MPcmp086 ENDP
167
168
169
170
171
172
173 MPmul086 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, yMant:DWORD
174 mov ax, xExp
175 mov bx, yExp
176 xor ch, ch
177 shl bh, 1
178 rcr ch, 1
179 shr bh, 1
180 xor ah, ch
181
182 sub bx, (1 SHL 14) - 2
183 add ax, bx
184 jno NoOverflow
185
186 Overflow:
187 or WORD PTR [xMant+2], 0
188 jz ZeroAns
189 or WORD PTR [yMant+2], 0
190 jz ZeroAns
191
192 mov MPOverflow, 1
193
194 ZeroAns:
195 xor ax, ax
196 xor dx, dx
197 mov Ans.Exp, ax
198 jmp StoreMant
199
200 NoOverflow:
201 mov Ans.Exp, ax
202
203 mov si, WORD PTR [xMant+2]
204 mov bx, WORD PTR [xMant]
205 mov di, WORD PTR [yMant+2]
206 mov cx, WORD PTR [yMant]
207
208 mov ax, si
209 or ax, bx
210 jz ZeroAns
211
212 mov ax, di
213 or ax, cx
214 jz ZeroAns
215
216 mov ax, cx
217 mul bx
218 push dx
219
220 mov ax, cx
221 mul si
222 push ax
223 push dx
224
225 mov ax, bx
226 mul di
227 push ax
228 push dx
229
230 mov ax, si
231 mul di
232 pop bx
233 pop cx
234 pop si
235 pop di
236
237 add ax, bx
238 adc dx, 0
239 pop bx
240 add di, bx
241 adc ax, 0
242 adc dx, 0
243 add di, cx
244 adc ax, si
245 adc dx, 0
246
247 or dx, dx
248 js StoreMant
249
250 shl di, 1
251 rcl ax, 1
252 rcl dx, 1
253 sub Ans.Exp, 1
254 jo Overflow
255
256 StoreMant:
257 mov WORD PTR Ans.Mant+2, dx
258 mov WORD PTR Ans.Mant, ax
259
260 lea ax, Ans
261 mov dx, ds
262 ret
263 MPmul086 ENDP
264
265
266
267 d2MP086 PROC uses si di, x:QWORD
268 mov dx, WORD PTR [x+6]
269 mov ax, WORD PTR [x+4]
270 mov bx, WORD PTR [x+2]
271 mov cx, WORD PTR [x]
272 mov si, dx
273 shl si, 1
274 or si, bx
275 or si, ax
276 or si, dx
277 or si, cx
278 jnz NonZero
279
280 xor ax, ax
281 xor dx, dx
282 jmp StoreAns
283
284 NonZero:
285 mov si, dx
286 shl si, 1
287 pushf
288 mov cl, 4
289 shr si, cl
290 popf
291 rcr si, 1
292 add si, (1 SHL 14) - (1 SHL 10)
293
294 mov di, ax ; shl dx:ax:bx 12 bits
295 mov cl, 12
296 shl dx, cl
297 shl ax, cl
298 mov cl, 4
299 shr di, cl
300 shr bx, cl
301 or dx, di
302 or ax, bx
303 stc
304 rcr dx, 1
305 rcr ax, 1
306
307 StoreAns:
308 mov Ans.Exp, si
309 mov WORD PTR Ans.Mant+2, dx
310 mov WORD PTR Ans.Mant, ax
311
312 lea ax, Ans
313 mov dx, ds
314 ret
315 d2MP086 ENDP
316
317
318
319 MP2d086 PROC uses si di, xExp:WORD, xMant:DWORD
320 sub xExp, (1 SHL 14) - (1 SHL 10)
321 jo Overflow
322
323 mov bx, xExp
324 and bx, 0111100000000000b
325 jz InRangeOfDouble
326
327 Overflow:
328 mov MPOverflow, 1
329 xor ax, ax
330 xor dx, dx
331 xor bx, bx
332 jmp StoreAns
333
334 InRangeOfDouble:
335 mov si, xExp
336 mov ax, si
337 mov cl, 5
338 shl si, cl
339 shl ax, 1
340 rcr si, 1
341
342 mov dx, WORD PTR [xMant+2]
343 mov ax, WORD PTR [xMant]
344 shl ax, 1
345 rcl dx, 1
346
347 mov bx, ax
348 mov di, dx
349 mov cl, 12
350 shr dx, cl
351 shr ax, cl
352 mov cl, 4
353 shl bx, cl
354 shl di, cl
355 or ax, di
356 or dx, si
357
358 StoreAns:
359 mov WORD PTR Double+6, dx
360 mov WORD PTR Double+4, ax
361 mov WORD PTR Double+2, bx
362 xor bx, bx
363 mov WORD PTR Double, bx
364
365 lea ax, Double
366 mov dx, ds
367 ret
368 MP2d086 ENDP
369
370
371
372
373 MPadd086 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, yMant:DWORD
374 mov si, xExp
375 mov dx, WORD PTR [xMant+2]
376 mov ax, WORD PTR [xMant]
377
378 mov di, yExp
379
380 mov cx, si
381 xor cx, di
382 js Subtract
383 jz SameMag
384
385 cmp si, di
386 jg XisGreater
387
388 xchg si, di
389 xchg dx, WORD PTR [yMant+2]
390 xchg ax, WORD PTR [yMant]
391
392 XisGreater:
393 mov cx, si
394 sub cx, di
395 cmp cx, 32
396 jl ChkSixteen
397 jmp StoreAns
398
399 ChkSixteen:
400 cmp cx, 16
401 jl SixteenBitShift
402
403 sub cx, 16
404 mov bx, WORD PTR [yMant+2]
405 shr bx, cl
406 mov WORD PTR [yMant], bx
407 mov WORD PTR [yMant+2], 0
408 jmp SameMag
409
410 SixteenBitShift:
411 mov bx, WORD PTR [yMant+2]
412 shr WORD PTR [yMant+2], cl
413 shr WORD PTR [yMant], cl
414 neg cl
415 add cl, 16
416 shl bx, cl
417 or WORD PTR [yMant], bx
418
419 SameMag:
420 add ax, WORD PTR [yMant]
421 adc dx, WORD PTR [yMant+2]
422 jc ShiftCarry
423 jmp StoreAns
424
425 ShiftCarry:
426 rcr dx, 1
427 rcr ax, 1
428 add si, 1
429 jo Overflow
430 jmp StoreAns
431
432 Overflow:
433 mov MPOverflow, 1
434
435 ZeroAns:
436 xor si, si
437 xor ax, ax
438 xor dx, dx
439 jmp StoreAns
440
441 Subtract:
442 xor di, 8000h
443 mov cx, si
444 sub cx, di
445 jnz DifferentMag
446
447 cmp dx, WORD PTR [yMant+2]
448 jg SubtractNumbers
449 jne SwapNumbers
450
451 cmp ax, WORD PTR [yMant]
452 jg SubtractNumbers
453 je ZeroAns
454
455 SwapNumbers:
456 xor si, 8000h
457 xchg ax, WORD PTR [yMant]
458 xchg dx, WORD PTR [yMant+2]
459 jmp SubtractNumbers
460
461 DifferentMag:
462 or cx, cx
463 jns NoSwap
464
465 xchg si, di
466 xchg ax, WORD PTR [yMant]
467 xchg dx, WORD PTR [yMant+2]
468 xor si, 8000h
469 neg cx
470
471 NoSwap:
472 cmp cx, 32
473 jge StoreAns
474
475 cmp cx, 16
476 jl SixteenBitShift2
477
478 sub cx, 16
479 mov bx, WORD PTR [yMant+2]
480 shr bx, cl
481 mov WORD PTR [yMant], bx
482 mov WORD PTR [yMant+2], 0
483 jmp SubtractNumbers
484
485 SixteenBitShift2:
486 mov bx, WORD PTR [yMant+2]
487 shr WORD PTR [yMant+2], cl
488 shr WORD PTR [yMant], cl
489 neg cl
490 add cl, 16
491 shl bx, cl
492 or WORD PTR [yMant], bx
493
494 SubtractNumbers:
495 sub ax, WORD PTR [yMant]
496 sbb dx, WORD PTR [yMant+2]
497
498 BitScanRight:
499 or dx, dx
500 js StoreAns
501
502 shl ax, 1
503 rcl dx, 1
504 sub si, 1
505 jno BitScanRight
506 jmp Overflow
507
508 StoreAns:
509 mov Ans.Exp, si
510 mov WORD PTR Ans.Mant+2, dx
511 mov WORD PTR Ans.Mant, ax
512
513 lea ax, Ans
514 mov dx, ds
515 ret
516 MPadd086 ENDP
517
518
519
520 MPdiv086 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, \
521 yMant:DWORD
522 mov ax, xExp
523 mov bx, yExp
524 xor ch, ch
525 shl bh, 1
526 rcr ch, 1
527 shr bh, 1
528 xor ah, ch
529
530 sub bx, (1 SHL 14) - 2
531 sub ax, bx
532 jno NoOverflow
533
534 Overflow:
535 mov MPOverflow, 1
536
537 ZeroAns:
538 xor ax, ax
539 xor dx, dx
540 mov Ans.Exp, dx
541 jmp StoreMant
542
543 NoOverflow:
544 mov Ans.Exp, ax
545
546 mov dx, WORD PTR [xMant+2]
547 mov ax, WORD PTR [xMant]
548 or dx, dx
549 jz ZeroAns
550
551 mov cx, WORD PTR [yMant+2]
552 mov bx, WORD PTR [yMant]
553 or cx, cx
554 jz Overflow
555
556 cmp dx, cx
557 jl Divide
558
559 shr dx, 1
560 rcr ax, 1
561 add Ans.Exp, 1
562 jo Overflow
563
564 Divide:
565 div cx
566 mov si, dx
567 mov dx, bx
568 mov bx, ax
569 mul dx
570 xor di, di
571 cmp dx, si
572 jnc RemReallyNeg
573
574 xchg ax, di
575 xchg dx, si
576 sub ax, di
577 sbb dx, si
578
579 shr dx, 1
580 rcr ax, 1
581 div cx
582 mov dx, bx
583 shl ax, 1
584 adc dx, 0
585 jmp StoreMant
586
587 RemReallyNeg:
588 sub ax, di
589 sbb dx, si
590
591 shr dx, 1
592 rcr ax, 1
593 div cx
594 mov dx, bx
595 mov bx, ax
596 xor ax, ax
597 xor cx, cx
598 shl bx, 1
599 rcl cx, 1
600 sub ax, bx
601 sbb dx, cx
602 jno StoreMant
603
604 shl ax, 1
605 rcl dx, 1
606 dec Ans.Exp
607
608 StoreMant:
609 mov WORD PTR Ans.Mant, ax
610 mov WORD PTR Ans.Mant+2, dx
611 lea ax, Ans
612 mov dx, ds
613 ret
614 MPdiv086 ENDP
615
616
617 MPcmp386 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, yMant:DWORD
618 mov si, 0
619 mov di, si
620 .386
621 mov ax, xExp
622 mov edx, xMant
623 mov bx, yExp
624 mov ecx, yMant
625 or ax, ax
626 jns AtLeastOnePos
627
628 or bx, bx
629 jns AtLeastOnePos
630
631 mov si, 1
632 and ah, 7fh
633 and bh, 7fh
634
635 AtLeastOnePos:
636 cmp ax, bx
637 jle Cmp1
638
639 mov di, 1
640 jmp ChkRev
641
642 Cmp1:
643 je Cmp2
644
645 mov di, -1
646 jmp ChkRev
647
648 Cmp2:
649 cmp edx, ecx
650 jbe Cmp3
651
652 mov di, 1
653 jmp ChkRev
654
655 Cmp3:
656 je ChkRev
657
658 mov di, -1
659
660 ChkRev:
661 or si, si
662 jz ExitCmp
663
664 neg di
665
666 ExitCmp:
667 mov ax, di
668 .8086
669 ret
670 MPcmp386 ENDP
671
672
673
674 d2MP386 PROC uses si di, x:QWORD
675 mov si, WORD PTR [x+6]
676 .386
677 mov edx, DWORD PTR [x+4]
678 mov eax, DWORD PTR [x]
679
680 mov ebx, edx
681 shl ebx, 1
682 or ebx, eax
683 jnz NonZero
684
685 xor si, si
686 xor edx, edx
687 jmp StoreAns
688
689 NonZero:
690 shl si, 1
691 pushf
692 shr si, 4
693 popf
694 rcr si, 1
695 add si, (1 SHL 14) - (1 SHL 10)
696
697 shld edx, eax, 12
698 stc
699 rcr edx, 1
700
701 StoreAns:
702 mov Ans.Exp, si
703 mov Ans.Mant, edx
704
705 lea ax, Ans
706 mov dx, ds
707 .8086
708 ret
709 d2MP386 ENDP
710
711
712
713
714 MP2d386 PROC uses si di, xExp:WORD, xMant:DWORD
715 sub xExp, (1 SHL 14) - (1 SHL 10)
716 .386
717 jo Overflow
718
719 mov bx, xExp
720 and bx, 0111100000000000b
721 jz InRangeOfDouble
722
723 Overflow:
724 mov MPOverflow, 1
725 xor eax, eax
726 xor edx, edx
727 jmp StoreAns
728
729 InRangeOfDouble:
730 mov bx, xExp
731 mov ax, bx
732 shl bx, 5
733 shl ax, 1
734 rcr bx, 1
735 shr bx, 4
736
737 mov edx, xMant
738 shl edx, 1
739 xor eax, eax
740 shrd eax, edx, 12
741 shrd edx, ebx, 12
742
743 StoreAns:
744 mov DWORD PTR Double+4, edx
745 mov DWORD PTR Double, eax
746
747 lea ax, Double
748 mov dx, ds
749 .8086
750 ret
751 MP2d386 ENDP
752
753
754
755 MPmul386 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, \
756 yMant:DWORD
757 mov ax, xExp
758 mov bx, yExp
759 .386
760 xor ch, ch
761 shl bh, 1
762 rcr ch, 1
763 shr bh, 1
764 xor ah, ch
765
766 sub bx, (1 SHL 14) - 2
767 add ax, bx
768 jno NoOverflow
769
770 Overflow:
771 or WORD PTR [xMant+2], 0
772 jz ZeroAns
773 or WORD PTR [yMant+2], 0
774 jz ZeroAns
775
776 mov MPOverflow, 1
777
778 ZeroAns:
779 xor edx, edx
780 mov Ans.Exp, dx
781 jmp StoreMant
782
783 NoOverflow:
784 mov Ans.Exp, ax
785
786 mov eax, xMant
787 mov edx, yMant
788 or eax, eax
789 jz ZeroAns
790
791 or edx, edx
792 jz ZeroAns
793
794 mul edx
795
796 or edx, edx
797 js StoreMant
798
799 shld edx, eax, 1
800 sub Ans.Exp, 1
801 jo Overflow
802
803 StoreMant:
804 mov Ans.Mant, edx
805 lea ax, Ans
806 mov dx, ds
807 .8086
808 ret
809 MPmul386 ENDP
810
811
812
813 MPadd386 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, \
814 yMant:DWORD
815 mov si, xExp
816 .386
817 mov eax, xMant
818
819 mov di, yExp
820 mov edx, yMant
821
822 mov cx, si
823 xor cx, di
824 js Subtract
825 jz SameMag
826
827 cmp si, di
828 jg XisGreater
829
830 xchg si, di
831 xchg eax, edx
832
833 XisGreater:
834 mov cx, si
835 sub cx, di
836 cmp cx, 32
837 jge StoreAns
838
839 shr edx, cl
840
841 SameMag:
842 add eax, edx
843 jnc StoreAns
844
845 rcr eax, 1
846 add si, 1
847 jno StoreAns
848
849 Overflow:
850 mov MPOverflow, 1
851
852 ZeroAns:
853 xor si, si
854 xor edx, edx
855 jmp StoreAns
856
857 Subtract:
858 xor di, 8000h
859 mov cx, si
860 sub cx, di
861 jnz DifferentMag
862
863 cmp eax, edx
864 jg SubtractNumbers
865 je ZeroAns
866
867 xor si, 8000h
868 xchg eax, edx
869 jmp SubtractNumbers
870
871 DifferentMag:
872 or cx, cx
873 jns NoSwap
874
875 xchg si, di
876 xchg eax, edx
877 xor si, 8000h
878 neg cx
879
880 NoSwap:
881 cmp cx, 32
882 jge StoreAns
883
884 shr edx, cl
885
886 SubtractNumbers:
887 sub eax, edx
888 bsr ecx, eax
889 neg cx
890 add cx, 31
891 shl eax, cl
892 sub si, cx
893 jo Overflow
894
895 StoreAns:
896 mov Ans.Exp, si
897 mov Ans.Mant, eax
898
899 lea ax, Ans
900 mov dx, ds
901 .8086
902 ret
903 MPadd386 ENDP
904
905
906
907
908
909 MPdiv386 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, \
910 yMant:DWORD
911 mov ax, xExp
912 mov bx, yExp
913 .386
914 xor ch, ch
915 shl bh, 1
916 rcr ch, 1
917 shr bh, 1
918 xor ah, ch
919
920 sub bx, (1 SHL 14) - 2
921 sub ax, bx
922 jno NoOverflow
923
924 Overflow:
925 mov MPOverflow, 1
926
927 ZeroAns:
928 xor eax, eax
929 mov Ans.Exp, ax
930 jmp StoreMant
931
932 NoOverflow:
933 mov Ans.Exp, ax
934
935 xor eax, eax
936 mov edx, xMant
937 mov ecx, yMant
938 or edx, edx
939 jz ZeroAns
940
941 or ecx, ecx
942 jz Overflow
943
944 cmp edx, ecx
945 jl Divide
946
947 shr edx, 1
948 rcr eax, 1
949 add Ans.Exp, 1
950 jo Overflow
951
952 Divide:
953 div ecx
954
955 StoreMant:
956 mov Ans.Mant, eax
957 lea ax, Ans
958 mov dx, ds
959 .8086
960 ret
961 MPdiv386 ENDP
962
963
964 fg2MP386 PROC x:DWORD, fg:WORD
965 mov bx, 1 SHL 14 + 30
966 sub bx, fg
967 .386
968 mov edx, x
969
970 or edx, edx
971 jnz ChkNegMP
972
973 mov bx, dx
974 jmp StoreAns
975
976 ChkNegMP:
977 jns BitScanRight
978
979 or bh, 80h
980 neg edx
981
982 BitScanRight:
983 bsr ecx, edx
984 neg cx
985 add cx, 31
986 sub bx, cx
987 shl edx, cl
988
989 StoreAns:
990 mov Ans.Exp, bx
991 mov Ans.Mant, edx
992 .8086
993 lea ax, Ans
994 mov dx, ds
995 ret
996 fg2MP386 ENDP
997
998
999
1000 PUBLIC MPcmp, MPmul, MPadd, MPdiv, MP2d, d2MP, fg2MP
1001
1002 fg2MP:
1003 cmp cpu, 386
1004 jae Use386fg2MP
1005 jmp fg2MP086
1006
1007 Use386fg2MP:
1008 jmp fg2MP386
1009
1010 MPcmp:
1011 cmp cpu, 386
1012 jae Use386cmp
1013 jmp MPcmp086
1014
1015 Use386cmp:
1016 jmp MPcmp386
1017
1018 MPmul:
1019 cmp cpu, 386
1020 jae Use386mul
1021 jmp MPmul086
1022
1023 Use386mul:
1024 jmp MPmul386
1025
1026 d2MP:
1027 cmp cpu, 386
1028 jae Use386d2MP
1029 jmp d2MP086
1030
1031 Use386d2MP:
1032 jmp d2MP386
1033
1034 MPadd:
1035 cmp cpu, 386
1036 jae Use386add
1037 jmp MPadd086
1038
1039 Use386add:
1040 jmp MPadd386
1041
1042 MPdiv:
1043 cmp cpu, 386
1044 jae Use386div
1045 jmp MPdiv086
1046
1047 Use386div:
1048 jmp MPdiv386
1049
1050 MP2d:
1051 cmp cpu, 386
1052 jae Use386MP2d
1053 jmp MP2d086
1054
1055 Use386MP2d:
1056 jmp MP2d386
1057
1058
1059 END
1060
1061