Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

855 lines
21 KiB

  1. TITLE "Large Integer Arithmetic"
  2. ;++
  3. ;
  4. ; Copyright (c) 1989 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; largeint.s
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements routines for performing extended integer
  13. ; arithmtic.
  14. ;
  15. ; Author:
  16. ;
  17. ; David N. Cutler (davec) 24-Aug-1989
  18. ;
  19. ; Environment:
  20. ;
  21. ; Any mode.
  22. ;
  23. ; Revision History:
  24. ;
  25. ;--
  26. .386p
  27. .xlist
  28. include ks386.inc
  29. include callconv.inc ; calling convention macros
  30. .list
  31. IFNDEF BLDR_KERNEL_RUNTIME
  32. EXTRNP _RtlRaiseStatus, 1
  33. ENDIF
  34. _TEXT$00 SEGMENT DWORD PUBLIC 'CODE'
  35. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  36. page ,132
  37. subttl "RtlLargeIntegerAdd"
  38. ;++
  39. ;
  40. ; LARGE_INTEGER
  41. ; RtlLargeIntegerAdd (
  42. ; IN LARGE_INTEGER Addend1,
  43. ; IN LARGE_INTEGER Addend2
  44. ; )
  45. ;
  46. ; Routine Description:
  47. ;
  48. ; This function adds a signed large integer to a signed large integer and
  49. ; returns the signed large integer result.
  50. ;
  51. ; Arguments:
  52. ;
  53. ; (TOS+4) = Addend1 - first addend value
  54. ; (TOS+12) = Addend2 - second addend value
  55. ;
  56. ; Return Value:
  57. ;
  58. ; The large integer result is stored in (edx:eax)
  59. ;
  60. ;--
  61. cPublicProc _RtlLargeIntegerAdd ,4
  62. cPublicFpo 4,0
  63. mov eax,[esp]+4 ; (eax)=add1.low
  64. add eax,[esp]+12 ; (eax)=sum.low
  65. mov edx,[esp]+8 ; (edx)=add1.hi
  66. adc edx,[esp]+16 ; (edx)=sum.hi
  67. stdRET _RtlLargeIntegerAdd
  68. stdENDP _RtlLargeIntegerAdd
  69. page
  70. subttl "Enlarged Integer Multiply"
  71. ;++
  72. ;
  73. ; LARGE_INTEGER
  74. ; RtlEnlargedIntegerMultiply (
  75. ; IN LONG Multiplicand,
  76. ; IN LONG Multiplier
  77. ; )
  78. ;
  79. ; Routine Description:
  80. ;
  81. ; This function multiplies a signed integer by an signed integer and
  82. ; returns a signed large integer result.
  83. ;
  84. ; Arguments:
  85. ;
  86. ; (TOS+4) = Factor1
  87. ; (TOS+8) = Factor2
  88. ;
  89. ; Return Value:
  90. ;
  91. ; The large integer result is stored in (edx:eax)
  92. ;
  93. ;--
  94. cPublicProc __RtlEnlargedIntegerMultiply ,2
  95. cPublicFpo 2,0
  96. mov eax,[esp]+4 ; (eax) = factor1
  97. imul dword ptr [esp]+8 ; (edx:eax) = signed result
  98. stdRET __RtlEnlargedIntegerMultiply
  99. stdENDP __RtlEnlargedIntegerMultiply
  100. page
  101. subttl "Enlarged Unsigned Integer Multiply"
  102. ;++
  103. ;
  104. ; LARGE_INTEGER
  105. ; RtlEnlargedUnsignedMultiply (
  106. ; IN ULONG Multiplicand,
  107. ; IN ULONG Multiplier
  108. ; )
  109. ;
  110. ; Routine Description:
  111. ;
  112. ; This function multiplies an un signed integer by an unsigned integer and
  113. ; returns a signed large integer result.
  114. ;
  115. ; Arguments:
  116. ;
  117. ; (TOS+4) = Factor1
  118. ; (TOS+8) = Factor2
  119. ;
  120. ; Return Value:
  121. ;
  122. ; The large integer result is stored in (edx:eax)
  123. ;
  124. ;--
  125. cPublicProc __RtlEnlargedUnsignedMultiply ,2
  126. cPublicFpo 2,0
  127. mov eax,[esp]+4 ; (eax) = factor1
  128. mul dword ptr [esp]+8 ; (edx:eax) = unsigned result
  129. stdRET __RtlEnlargedUnsignedMultiply
  130. stdENDP __RtlEnlargedUnsignedMultiply
  131. page
  132. subttl "Enlarged Unsigned Integer Divide"
  133. ;++
  134. ;
  135. ; ULONG
  136. ; RtlEnlargedUnsignedDivide (
  137. ; IN ULARGE_INTEGER Dividend,
  138. ; IN ULONG Divisor,
  139. ; IN PULONG Remainder
  140. ; )
  141. ;
  142. ;
  143. ; Routine Description:
  144. ;
  145. ; This function divides an unsigned large integer by an unsigned long
  146. ; and returns the resultant quotient and optionally the remainder.
  147. ;
  148. ; Arguments:
  149. ;
  150. ; Dividend - Supplies the dividend value.
  151. ;
  152. ; Divisor - Supplies the divisor value.
  153. ;
  154. ; Remainder - Supplies an optional pointer to a variable that
  155. ; receives the remainder.
  156. ;
  157. ; Return Value:
  158. ;
  159. ; The unsigned long integer quotient is returned as the function value.
  160. ;
  161. ;--
  162. cPublicProc __RtlEnlargedUnsignedDivide,4
  163. cPublicFpo 4,0
  164. mov eax, [esp+4] ; (eax) = Dividend.LowPart
  165. mov edx, [esp+8] ; (edx) = Dividend.HighPart
  166. mov ecx, [esp+16] ; (ecx) = pRemainder
  167. div dword ptr [esp+12] ; divide by Divisor
  168. or ecx, ecx ; return remainder?
  169. jnz short @f
  170. stdRET __RtlEnlargedUnsignedDivide ; (eax) = Quotient
  171. align 4
  172. @@: mov [ecx], edx ; save remainder
  173. stdRET __RtlEnlargedUnsignedDivide ; (eax) = Quotient
  174. stdENDP __RtlEnlargedUnsignedDivide
  175. page
  176. subttl "Extended Large Integer Divide"
  177. ;++
  178. ;
  179. ; LARGE_INTEGER
  180. ; RtlExtendedLargeIntegerDivide (
  181. ; IN LARGE_INTEGER Dividend,
  182. ; IN ULONG Divisor,
  183. ; OUT PULONG Remainder OPTIONAL
  184. ; )
  185. ;
  186. ; Routine Description:
  187. ;
  188. ; This routine divides an unsigned 64 bit dividend by a 32 bit divisor
  189. ; and returns a 64-bit quotient, and optionally the 32-bit remainder.
  190. ;
  191. ;
  192. ; Arguments:
  193. ;
  194. ; Dividend - Supplies the 64 bit dividend for the divide operation.
  195. ;
  196. ; Divisor - Supplies the 32 bit divisor for the divide operation.
  197. ;
  198. ; Remainder - Supplies an optional pointer to a variable which receives
  199. ; the remainder
  200. ;
  201. ; Return Value:
  202. ;
  203. ; The 64-bit quotient is returned as the function value.
  204. ;
  205. ;--
  206. cPublicProc _RtlExtendedLargeIntegerDivide, 4
  207. cPublicFpo 4,3
  208. push esi
  209. push edi
  210. push ebx
  211. mov eax, [esp+16] ; (eax) = Dividend.LowPart
  212. mov edx, [esp+20] ; (edx) = Dividend.HighPart
  213. lid00: mov ebx, [esp+24] ; (ebx) = Divisor
  214. or ebx, ebx
  215. jz short lid_zero ; Attempted a divide by zero
  216. push ebp
  217. mov ecx, 64 ; Loop count
  218. xor esi, esi ; Clear partial remainder
  219. ; (edx:eax) = Dividend
  220. ; (ebx) = Divisor
  221. ; (ecx) = Loop count
  222. ; (esi) = partial remainder
  223. align 4
  224. lid10: shl eax, 1 ; (LowPart << 1) | 0
  225. rcl edx, 1 ; (HighPart << 1) | CF
  226. rcl esi, 1 ; (Partial << 1) | CF
  227. sbb edi, edi ; clone CF into edi (0 or -1)
  228. cmp esi, ebx ; check if partial remainder less then divisor
  229. cmc
  230. sbb ebp, ebp ; clone CF intp ebp
  231. or edi, ebp ; merge with remainder of high bit
  232. sub eax, edi ; merge quotient bit
  233. and edi, ebx ; Select divisor or 0
  234. sub esi, edi
  235. dec ecx ; dec interration count
  236. jnz short lid10 ; go around again
  237. pop ebp
  238. pop ebx
  239. pop edi
  240. mov ecx, [esp+20] ; (ecx) = Remainder
  241. or ecx, ecx
  242. jnz short lid20
  243. pop esi
  244. stdRET _RtlExtendedLargeIntegerDivide
  245. align 4
  246. lid20:
  247. mov [ecx], esi ; store remainder
  248. pop esi
  249. stdRET _RtlExtendedLargeIntegerDivide
  250. lid_zero:
  251. IFNDEF BLDR_KERNEL_RUNTIME
  252. stdCall _RtlRaiseStatus, <STATUS_INTEGER_DIVIDE_BY_ZERO>
  253. ENDIF
  254. pop ebx
  255. pop edi
  256. pop esi
  257. stdRET _RtlExtendedLargeIntegerDivide
  258. stdENDP _RtlExtendedLargeIntegerDivide
  259. page
  260. subttl "Extended Magic Divide"
  261. ;++
  262. ;
  263. ; LARGE_INTEGER
  264. ; RtlExtendedMagicDivide (
  265. ; IN LARGE_INTEGER Dividend,
  266. ; IN LARGE_INTEGER MagicDivisor,
  267. ; IN CCHAR ShiftCount
  268. ; )
  269. ;
  270. ; Routine Description:
  271. ;
  272. ; This function divides a signed large integer by an unsigned large integer
  273. ; and returns the signed large integer result. The division is performed
  274. ; using reciprocal multiplication of a signed large integer value by an
  275. ; unsigned large integer fraction which represents the most significant
  276. ; 64-bits of the reciprocal divisor rounded up in its least significant bit
  277. ; and normalized with respect to bit 63. A shift count is also provided
  278. ; which is used to truncate the fractional bits from the result value.
  279. ;
  280. ; Arguments:
  281. ;
  282. ; (ebp+8) = Dividend
  283. ; (ebp+16) = MagicDivisor value is a 64-bit multiplicative reciprocal
  284. ; (ebp+24) = ShiftCount - Right shift adjustment value.
  285. ;
  286. ; Return Value:
  287. ;
  288. ; The large integer result is stored in (edx:eax)
  289. ;
  290. ;--
  291. RemdDiv equ [ebp+8] ; Dividend
  292. RemdRec equ [ebp+16] ; Reciprocal (magic divisor)
  293. RemdShift equ [ebp+24]
  294. RemdTmp1 equ [ebp-4]
  295. RemdTmp2 equ [ebp-8]
  296. RemdTmp3 equ [ebp-12]
  297. cPublicProc _RtlExtendedMagicDivide ,5
  298. push ebp
  299. mov ebp,esp
  300. sub esp,12
  301. push esi
  302. mov esi, RemdDiv+4
  303. test esi,80000000h
  304. jz remd10 ; no sign, no need to negate
  305. neg dword ptr RemdDiv+4
  306. neg dword ptr RemdDiv
  307. sbb dword ptr RemdDiv+4,0 ; negate
  308. remd10: mov eax,RemdRec
  309. mul dword ptr RemdDiv ; (edx:eax) = Div.lo * Rec.lo
  310. mov RemdTmp1,edx
  311. mov eax,RemdRec
  312. mul dword ptr RemdDiv+4 ; (edx:eax) = Div.hi * Rec.lo
  313. mov RemdTmp2,eax
  314. mov RemdTmp3,edx
  315. mov eax,RemdRec+4
  316. mul dword ptr RemdDiv ; (edx:eax) = Div.lo * Rec.hi
  317. ;
  318. ; Col 0 doesn't matter
  319. ; Col 1 = Hi(Div.lo * Rec.lo) + Low(Div.Hi * Rec.lo) + Low(Div.lo * Rec.hi)
  320. ; = RemdTmp1 + RemdTmp2 + eax
  321. ; -> Only want carry from Col 1
  322. ;
  323. xor ecx,ecx ; (ecx) = 0
  324. add eax,RemdTmp1
  325. adc ecx, 0 ; save carry in ecx
  326. add eax,RemdTmp2
  327. adc ecx, 0 ; Save Carry, all we want from Col2
  328. mov RemdTmp1,edx
  329. mov eax,RemdRec+4
  330. mul dword ptr RemdDiv+4 ; (edx:eax) = Div.Hi * Rec.Hi
  331. ;
  332. ; TOS = carry flag from Col 1
  333. ;
  334. ; Col 2 = Col1 CF +
  335. ; Hi(Div.Hi * Rec.Lo) + Hi(Div.Lo * Rec.Hi) + Low(Div.Hi * Rec.Hi)
  336. ; = CF + RemdTmp3 + RemdTmp1 + eax
  337. ;
  338. ; Col 3 = Col2 CF + Hi(Div.Hi * Rec.Hi)
  339. ; = CF + edx
  340. ;
  341. add eax,RemdTmp1
  342. adc edx, 0 ; add carry to edx
  343. add eax,RemdTmp3 ; (eax) = col 2
  344. adc edx, 0 ; add carry to edx
  345. add eax, ecx
  346. adc edx, 0 ; (edx) = col 3
  347. ;
  348. ; (edx:eax) = the high 64 bits of the multiply, shift it right by
  349. ; shift count to discard bits to right of virtual decimal pt.
  350. ;
  351. ; RemdShift could be as large as 63 and still not 0 the result, 386
  352. ; will only shift 31 bits at a time, so must do the sift multiple
  353. ; times to get correct effect.
  354. ;
  355. mov cl,RemdShift
  356. remd20: cmp cl,31
  357. jbe remd30
  358. sub cl,31
  359. shrd eax,edx,31
  360. shr edx,31
  361. jmp remd20
  362. remd30: shrd eax,edx,cl
  363. shr edx,cl
  364. ;
  365. ; Negate the result if need be
  366. ;
  367. test esi,80000000h
  368. jz remd40 ; no sign, go return without negate
  369. neg edx
  370. neg eax
  371. sbb edx,0
  372. ;
  373. ; Store the result
  374. ;
  375. remd40:
  376. ; results in (edx:eax)
  377. pop esi
  378. mov esp,ebp
  379. pop ebp
  380. stdRET _RtlExtendedMagicDivide
  381. stdENDP _RtlExtendedMagicDivide
  382. page
  383. subttl "Extended Integer Multiply"
  384. ;++
  385. ;
  386. ; LARGE_INTEGER
  387. ; RtlExtendedIntegerMultiply (
  388. ; IN LARGE_INTEGER Multiplicand,
  389. ; IN ULONG Multiplier
  390. ; )
  391. ;
  392. ; Routine Description:
  393. ;
  394. ; This function multiplies a signed large integer by a signed integer and
  395. ; returns the signed large integer result.
  396. ;
  397. ; Arguments:
  398. ;
  399. ; (ebp+8,12)=multiplican (MCAN)
  400. ; (ebp+16)=multiplier (MPER)
  401. ;
  402. ; Return Value:
  403. ;
  404. ; The large integer result is stored in (edx:eax)
  405. ;
  406. ;--
  407. ReimMCAN equ <dword ptr [ebp+8]>
  408. ReimMPER equ <dword ptr [ebp+16]>
  409. cPublicProc _RtlExtendedIntegerMultiply ,3
  410. push ebp
  411. mov ebp,esp
  412. push esi
  413. mov esi,ReimMPER
  414. xor esi,ReimMCAN+4 ; (esi) = result sign
  415. test ReimMCAN+4,80000000h
  416. jz short reim10 ; MCAN pos, go look at MPER
  417. neg dword ptr ReimMCAN+4
  418. neg dword ptr ReimMCAN
  419. sbb dword ptr ReimMCAN+4,0 ; negate multiplican
  420. reim10: test ReimMPER,80000000h
  421. jz short reim20 ; MPER pos, go do multiply
  422. neg dword ptr ReimMPER ; negate multiplier
  423. reim20: mov eax,ReimMPER
  424. mul dword ptr ReimMCAN ; (edx:eax) = MPER * MCAN.low
  425. push edx
  426. mov ecx, eax
  427. mov eax,ReimMPER
  428. mul dword ptr ReimMCAN+4 ; (edx:eax) = MPER * MCAN.high
  429. add eax,[esp] ; (eax) = hi part of MPER*MCAN.low
  430. ; plus low part of MPER*MCAN.hi
  431. test esi,80000000h
  432. jz short reim30 ; result sign is OK, go return
  433. neg eax
  434. neg ecx
  435. sbb eax,0 ; negate result
  436. reim30: add esp,4 ; clean eax off stack
  437. pop esi ; restore nonvolatile reg
  438. mov edx,eax ; (edx:ecx) = result
  439. mov eax,ecx ; (edx:eax) = result
  440. pop ebp
  441. stdRET _RtlExtendedIntegerMultiply
  442. stdENDP _RtlExtendedIntegerMultiply
  443. page
  444. subttl "Large Integer Shift Left"
  445. ;++
  446. ;
  447. ; LARGE_INTEGER
  448. ; RtlLargeIntegerShiftLeft (
  449. ; IN LARGE_INTEGER LargeInteger,
  450. ; IN CCHAR ShiftCount
  451. ; )
  452. ;
  453. ;
  454. ; Routine Description:
  455. ;
  456. ; This routine does a left logical shift of a large integer by a
  457. ; specified amount (ShiftCount) modulo 64.
  458. ;
  459. ; Arguments:
  460. ;
  461. ; LargeInteger - Supplies the large integer to be shifted
  462. ;
  463. ; ShiftCount - Supplies the left shift count
  464. ;
  465. ; Return Value:
  466. ;
  467. ; LARGE_INTEGER - Receives the shift large integer result
  468. ;
  469. ;--
  470. cPublicProc _RtlLargeIntegerShiftLeft,3
  471. cPublicFpo 3,0
  472. mov ecx, [esp+12] ; (ecx) = ShiftCount
  473. and ecx, 3fh ; mod 64
  474. cmp ecx, 32
  475. jnc short sl10
  476. ;
  477. ; Shift count is less then 32 bits.
  478. ;
  479. mov eax, [esp+4] ; (eax) = LargeInteger.LowPart
  480. mov edx, [esp+8] ; (edx) = LargeInteger.HighPart
  481. shld edx, eax, cl
  482. shl eax, cl
  483. stdRET _RtlLargeIntegerShiftLeft
  484. align 4
  485. sl10:
  486. ;
  487. ; Shift count is greater than or equal 32 bits - low half of result is zero,
  488. ; high half is the low half shifted left by remaining count.
  489. ;
  490. mov edx, [esp+4] ; (edx) = LargeInteger.LowPart
  491. xor eax, eax ; store lowpart
  492. shl edx, cl ; store highpart
  493. stdRET _RtlLargeIntegerShiftLeft
  494. stdENDP _RtlLargeIntegerShiftLeft
  495. page
  496. subttl "Large Integer Shift Right"
  497. ;--
  498. ;
  499. ;LARGE_INTEGER
  500. ;RtlLargeIntegerShiftRight (
  501. ; IN LARGE_INTEGER LargeInteger,
  502. ; IN CCHAR ShiftCount
  503. ; )
  504. ;
  505. ;Routine Description:
  506. ;
  507. ; This routine does a right logical shift of a large integer by a
  508. ; specified amount (ShiftCount) modulo 64.
  509. ;
  510. ;Arguments:
  511. ;
  512. ; LargeInteger - Supplies the large integer to be shifted
  513. ;
  514. ; ShiftCount - Supplies the right shift count
  515. ;
  516. ;Return Value:
  517. ;
  518. ; LARGE_INTEGER - Receives the shift large integer result
  519. ;
  520. ;--*/
  521. cPublicProc _RtlLargeIntegerShiftRight,3
  522. cPublicFpo 3,0
  523. mov ecx, [esp+12] ; (ecx) = ShiftCount
  524. and ecx, 3fh ; mod 64
  525. cmp ecx, 32
  526. jnc short sr10
  527. ;
  528. ; Shift count is less then 32 bits.
  529. ;
  530. mov eax, [esp+4] ; (eax) = LargeInteger.LowPart
  531. mov edx, [esp+8] ; (edx) = LargeInteger.HighPart
  532. shrd eax, edx, cl
  533. shr edx, cl
  534. stdRET _RtlLargeIntegerShiftRight
  535. align 4
  536. sr10:
  537. ;
  538. ; Shift count is greater than or equal 32 bits - high half of result is zero,
  539. ; low half is the high half shifted right by remaining count.
  540. ;
  541. mov eax, [esp+8] ; (eax) = LargeInteger.HighPart
  542. xor edx, edx ; store highpart
  543. shr eax, cl ; store lowpart
  544. stdRET _RtlLargeIntegerShiftRight
  545. stdENDP _RtlLargeIntegerShiftRight
  546. ;++
  547. ;
  548. ;LARGE_INTEGER
  549. ;RtlLargeIntegerArithmeticShift (
  550. ; IN LARGE_INTEGER LargeInteger,
  551. ; IN CCHAR ShiftCount
  552. ; )
  553. ;
  554. ;Routine Description:
  555. ;
  556. ; This routine does a right arithmetic shift of a large integer by a
  557. ; specified amount (ShiftCount) modulo 64.
  558. ;
  559. ;Arguments:
  560. ;
  561. ; LargeInteger - Supplies the large integer to be shifted
  562. ;
  563. ; ShiftCount - Supplies the right shift count
  564. ;
  565. ;Return Value:
  566. ;
  567. ; LARGE_INTEGER - Receives the shift large integer result
  568. ;
  569. ;--
  570. cPublicProc _RtlLargeIntegerArithmeticShift,3
  571. cPublicFpo 3,0
  572. mov ecx, [esp+12] ; (ecx) = ShiftCount
  573. and ecx, 3fh ; mod 64
  574. cmp ecx, 32
  575. jc short sar10
  576. ;
  577. ; Shift count is greater than or equal 32 bits - high half of result is sign
  578. ; bit, low half is the high half shifted right by remaining count.
  579. ;
  580. mov eax, [esp+8] ; (eax) = LargeInteger.HighPart
  581. sar eax, cl ; store highpart
  582. bt eax, 31 ; sign bit set?
  583. sbb edx, edx ; duplicate sign bit into highpart
  584. stdRET _RtlLargeIntegerArithmeticShift
  585. align 4
  586. sar10:
  587. ;
  588. ; Shift count is less then 32 bits.
  589. ;
  590. ;
  591. mov eax, [esp+4] ; (eax) = LargeInteger.LowPart
  592. mov edx, [esp+8] ; (edx) = LargeInteger.HighPart
  593. shrd eax, edx, cl
  594. sar edx, cl
  595. stdRET _RtlLargeIntegerArithmeticShift
  596. stdENDP _RtlLargeIntegerArithmeticShift,3
  597. page
  598. subttl "Large Integer Negate"
  599. ;++
  600. ;
  601. ; LARGE_INTEGER
  602. ; RtlLargeIntegerNegate (
  603. ; IN LARGE_INTEGER Subtrahend
  604. ; )
  605. ;
  606. ; Routine Description:
  607. ;
  608. ; This function negates a signed large integer and returns the signed
  609. ; large integer result.
  610. ;
  611. ; Arguments:
  612. ;
  613. ; (TOS+4) = Subtrahend
  614. ;
  615. ; Return Value:
  616. ;
  617. ; The large integer result is stored in (edx:eax)
  618. ;
  619. ;--
  620. cPublicProc _RtlLargeIntegerNegate ,2
  621. cPublicFpo 2,0
  622. mov eax,[esp]+4 ; (eax) = lo
  623. mov edx,[esp]+8
  624. neg edx ; (edx) = 2's comp of hi part
  625. neg eax ; if ((eax) == 0) CF = 0
  626. ; else CF = 1
  627. sbb edx,0 ; (edx) = (edx) - CF
  628. ; (edx:eax) = result
  629. stdRET _RtlLargeIntegerNegate
  630. stdENDP _RtlLargeIntegerNegate
  631. page
  632. subttl "Large Integer Subtract"
  633. ;++
  634. ;
  635. ; LARGE_INTEGER
  636. ; RtlLargeIntegerSubtract (
  637. ; IN LARGE_INTEGER Minuend,
  638. ; IN LARGE_INTEGER Subtrahend
  639. ; )
  640. ;
  641. ; Routine Description:
  642. ;
  643. ; This function subtracts a signed large integer from a signed large
  644. ; integer and returns the signed large integer result.
  645. ;
  646. ; Arguments:
  647. ;
  648. ; (TOS+4) = Minuend
  649. ; (TOS+12) = Subtrahend
  650. ;
  651. ; Return Value:
  652. ;
  653. ; The large integer result is stored in (edx:eax)
  654. ;
  655. ;--
  656. cPublicProc _RtlLargeIntegerSubtract ,4
  657. cPublicFpo 4,0
  658. mov eax,[esp]+4
  659. sub eax,[esp]+12 ; (eax) = result.low
  660. mov edx,[esp]+8
  661. sbb edx,[esp]+16 ; (edx) = result.high
  662. stdRET _RtlLargeIntegerSubtract
  663. stdENDP _RtlLargeIntegerSubtract
  664. page
  665. subttl "Convert Long to Large Integer"
  666. ;++
  667. ;
  668. ; LARGE_INTEGER
  669. ; RtlConvertLongToLargeInteger (
  670. ; IN LONG SignedInteger
  671. ; )
  672. ;
  673. ; Routine Description:
  674. ;
  675. ; This function converts the input signed integer to a signed large
  676. ; integer and returns the latter as the result.
  677. ;
  678. ; Arguments:
  679. ;
  680. ; (TOS+4) = SignedInteger
  681. ;
  682. ; Return Value:
  683. ;
  684. ; The large integer result is stored (edx:eax)
  685. ;
  686. ;--
  687. cPublicProc ___RtlConvertLongToLargeInteger ,1
  688. cPublicFpo 1,0
  689. mov eax,[esp]+4 ; (eax) = SignedInteger
  690. cdq ; (edx:eax) = signed LargeInt
  691. stdRET ___RtlConvertLongToLargeInteger
  692. stdENDP ___RtlConvertLongToLargeInteger
  693. page
  694. subttl "Convert Ulong to Large Integer"
  695. ;++
  696. ;
  697. ; LARGE_INTEGER
  698. ; RtlConvertUlongToLargeInteger (
  699. ; IN LONG UnsignedInteger
  700. ; )
  701. ;
  702. ; Routine Description:
  703. ;
  704. ; This function converts the input unsigned integer to a signed large
  705. ; integer and returns the latter as the result.
  706. ;
  707. ; Arguments:
  708. ;
  709. ; (TOS+4) = UnsignedInteger
  710. ;
  711. ; Return Value:
  712. ;
  713. ; The large integer result is stored in (edx:eax)
  714. ;
  715. ;--
  716. cPublicProc ___RtlConvertUlongToLargeInteger ,1
  717. cPublicFpo 1,0
  718. mov eax,[esp]+4 ; store low
  719. xor edx,edx ; store 0 in high
  720. stdRET ___RtlConvertUlongToLargeInteger
  721. stdENDP ___RtlConvertUlongToLargeInteger
  722. _TEXT$00 ends
  723. end