imuldos.asm 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. TITLE imul.asm
  2. ;; imuldos.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 Zortech C, so if
  6. ;; other compilers are used please think about any alterations that are
  7. ;; thereby needed.
  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. _rlow$ = 8
  26. _a$ = 12
  27. _b$ = 16
  28. _c$ = 20
  29. _Imultiply proc near
  30. mov EAX, DWORD PTR _b$[ESP-4]
  31. mul DWORD PTR _a$[ESP-4]
  32. mov ECX, DWORD PTR _rlow$[ESP-4]
  33. add EAX, DWORD PTR _c$[ESP-4]
  34. adc EDX, 0 ; carry into top half
  35. add EAX, EAX
  36. adc EDX, EDX
  37. shr EAX, 1
  38. mov DWORD PTR [ECX], EAX
  39. mov EAX, EDX
  40. ret 0
  41. nop
  42. nop
  43. _Imultiply endp
  44. _TEXT ENDS
  45. ;
  46. ; unsigned32 Idiv10_9(unsigned32 *qp, unsigned32 high, unsigned32 low)
  47. ; {
  48. ; uns64 p = ((uns64)high << 31) | (uns64)low;
  49. ; *qp = (unsigned32)(p / (uns64)1000000000U);
  50. ; return (unsigned32)(p % (uns64)1000000000U);
  51. ; }
  52. ;
  53. _TEXT segment dword public 'CODE'
  54. assume CS:_TEXT
  55. public _Idiv10_9
  56. _qp$ = 8
  57. _high$ = 12
  58. _low$ = 16
  59. _Idiv10_9 proc near
  60. mov EDX, DWORD PTR _high$[ESP-4]
  61. mov EAX, DWORD PTR _low$[ESP-4]
  62. shl EAX, 1
  63. shr EDX, 1
  64. rcr EAX, 1 ; That glued together 31+31 bits
  65. mov ECX, 1000000000
  66. div ECX
  67. mov ECX, DWORD PTR _qp$[ESP-4]
  68. mov DWORD PTR [ECX], EAX
  69. mov EAX, EDX
  70. ret 0
  71. nop
  72. nop
  73. _Idiv10_9 endp
  74. _TEXT ENDS
  75. ;
  76. ; unsigned32 Idivide(unsigned32 *qp, unsigned32 a, unsigned32 b, unsigned32 c)
  77. ; {
  78. ; uns64 p = ((uns64)a << 31) | (uns64)b;
  79. ; *qp = (unsigned32)(p / (uns64)c);
  80. ; return (unsigned32)(p % (uns64)c);
  81. ; }
  82. ;
  83. _TEXT segment dword public 'CODE'
  84. assume CS:_TEXT
  85. public _Idivide
  86. _qp$ = 8
  87. _a$ = 12
  88. _b$ = 16
  89. _c$ = 20
  90. _Idivide proc near
  91. mov EDX, DWORD PTR _high$[ESP-4]
  92. mov EAX, DWORD PTR _low$[ESP-4]
  93. shl EAX, 1
  94. shr EDX, 1
  95. rcr EAX, 1 ; That glued together 31+31 bits
  96. mov ECX, DWORD PTR _c$[ESP-4]
  97. div ECX
  98. mov ECX, DWORD PTR _qp$[ESP-4]
  99. mov DWORD PTR [ECX], EAX
  100. mov EAX, EDX
  101. ret 0
  102. nop
  103. nop
  104. nop
  105. _Idivide endp
  106. _TEXT ENDS
  107. END