imulwat.asm 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. ;; TITLE imul.asm
  2. ;; imulwat.asm Copyright (C) Codemist Ltd, 1993-2002
  3. ;;
  4. ;; This code implements Imultiply and Idivide in 80386 (and up) assembly
  5. ;; code. The argument passing conventions are as used by Watcom C, so if
  6. ;; other compilers are used please think about any alterations that are
  7. ;; thereby needed. Note that I use the register calling convention here.
  8. ;;
  9. .386P
  10. .387
  11. ;
  12. ;
  13. ; unsigned32 Imultiply(unsigned32 *rlow,
  14. ; unsigned32 a, unsigned32 b, unsigned32 c)
  15. ; {
  16. ; /* uns64 is a 64-bit integral type here */
  17. ; uns64 r = (uns64)a*(uns64)b + (uns64)c;
  18. ; *rlow = (unsigned32)(r & 0x7fffffff);
  19. ; return (unsigned32)(r >> 31);
  20. ; }
  21. ;
  22. _TEXT segment dword public 'CODE'
  23. assume CS:_TEXT
  24. public Imultiply_
  25. Imultiply_ proc near
  26. push EAX
  27. mov EAX, EBX
  28. mul EDX
  29. add EAX, ECX
  30. adc EDX, 0
  31. add EAX, EAX
  32. adc EDX, EDX
  33. shr EAX, 1
  34. pop ECX
  35. mov DWORD PTR [ECX], EAX
  36. mov EAX, EDX
  37. ret 0
  38. Imultiply_ endp
  39. _TEXT ENDS
  40. ;
  41. ; unsigned32 Idiv10_9(unsigned32 *qp, unsigned32 high, unsigned32 low)
  42. ; {
  43. ; uns64 p = ((uns64)high << 31) | (uns64)low;
  44. ; *qp = (unsigned32)(p / (uns64)1000000000U);
  45. ; return (unsigned32)(p % (uns64)1000000000U);
  46. ; }
  47. ;
  48. _TEXT segment dword public 'CODE'
  49. assume CS:_TEXT
  50. public Idiv10_9_
  51. Idiv10_9_ proc near
  52. push EAX
  53. mov EAX, EBX
  54. shl EAX, 1
  55. shr EDX, 1
  56. rcr EAX, 1 ; That glued together 31+31 bits
  57. mov ECX, 1000000000
  58. div ECX
  59. pop ECX
  60. mov DWORD PTR [ECX], EAX
  61. mov EAX, EDX
  62. ret 0
  63. Idiv10_9_ endp
  64. _TEXT ENDS
  65. ;
  66. ; unsigned32 Idivide(unsigned32 *qp, unsigned32 a, unsigned32 b, unsigned32 c)
  67. ; {
  68. ; uns64 p = ((uns64)a << 31) | (uns64)b;
  69. ; *qp = (unsigned32)(p / (uns64)c);
  70. ; return (unsigned32)(p % (uns64)c);
  71. ; }
  72. ;
  73. _TEXT segment dword public 'CODE'
  74. assume CS:_TEXT
  75. public Idivide_
  76. _qp$ = 8
  77. _a$ = 12
  78. _b$ = 16
  79. _c$ = 20
  80. Idivide_ proc near
  81. push EAX
  82. mov EAX, EBX
  83. shl EAX, 1
  84. shr EDX, 1
  85. rcr EAX, 1 ; That glued together 31+31 bits
  86. div ECX
  87. pop ECX
  88. mov DWORD PTR [ECX], EAX
  89. mov EAX, EDX
  90. ret 0
  91. Idivide_ endp
  92. _TEXT ENDS
  93. END