lbn80386.asm
上传用户:zbbssh
上传日期:2007-01-08
资源大小:196k
文件大小:8k
源码类别:

CA认证

开发平台:

C/C++

  1. ;;; Assembly primitives for bignum library, 80386 family, 32-bit code.
  2. ;;;
  3. ;;; Copyright (c) 1995, Colin Plumb.
  4. ;;; For licensing and other legal details, see the file legal.c.
  5. ;;;
  6. ;;; Several primitives are included here.  Only lbnMulAdd1 is *really*
  7. ;;; critical, but once that's written, lnmMulN1 and lbnMulSub1 are quite
  8. ;;; easy to write as well, so they are included here as well.
  9. ;;; lbnDiv21 and lbnModQ are so easy to write that they're included, too.
  10. ;;;
  11. ;;; All functions here are for 32-bit flat mode.  I.e. near code and
  12. ;;; near data, although the near offsets are 32 bits.
  13. .386
  14. ;_TEXT   segment para public use32 'CODE' ; 16-byte aligned because 486 cares
  15. ;_TEXT ends
  16. ifdef @Version
  17. if @Version le 510
  18. FLAT group _TEXT
  19. endif
  20. else
  21. FLAT group _TEXT
  22. endif
  23. assume cs:FLAT, ds:FLAT, ss:FLAT
  24. _TEXT   segment para public use32 'CODE' ; 16-byte aligned because 486 cares
  25. public  _lbnMulN1_32
  26. public  _lbnMulAdd1_32
  27. public  _lbnMulSub1_32
  28. public _lbnDiv21_32
  29. public _lbnModQ_32
  30. ;; Register usage:
  31. ;; eax - low half of product
  32. ;; ebx - carry to next iteration
  33. ;; ecx - multiplier (k)
  34. ;; edx - high half of product
  35. ;; esi - source pointer
  36. ;; edi - dest pointer
  37. ;; ebp - loop counter
  38. ;;
  39. ;; Stack frame:
  40. ;; +--------+ esp+20  esp+24  esp+28  esp+32
  41. ;; |    k   |
  42. ;; +--------+ esp+16  esp+20  esp+24  esp+28
  43. ;; |   len  |
  44. ;; +--------+ esp+12  esp+16  esp+20  esp+24
  45. ;; |   in   |
  46. ;; +--------+ esp+8   esp+12  esp+16  esp+20
  47. ;; |   out  |
  48. ;; +--------+ esp+4   esp+8   esp+12  esp+16
  49. ;; | return |
  50. ;; +--------+ esp     esp+4   esp+8   esp+12
  51. ;; |   esi  |
  52. ;; +--------+         esp     esp+4   esp+8
  53. ;; |   ebp  |
  54. ;; +--------+                 esp     esp+4
  55. ;; |   edi  |
  56. ;; +--------+                         esp
  57. align 16
  58. _lbnMulN1_32 proc near
  59. push esi ; U
  60. mov esi,[esp+12] ; V load in
  61. push ebp ; U
  62. mov ebp,[esp+20] ; V load len
  63. mov ecx,[esp+24] ; U load k
  64. push edi ; V
  65. mov edi,[esp+16] ; U load out
  66. ;; First multiply step has no carry in.
  67. mov eax,[esi] ; V
  68. lea ebx,[ebp*4-4] ; U loop unrolling
  69. mul ecx ; NP first multiply
  70. mov [edi],eax ; U
  71. and ebx,12 ; V loop unrolling
  72. add esi,ebx ; U loop unrolling
  73. add edi,ebx ; V loop unrolling
  74. jmp DWORD PTR m32_jumptable[ebx] ; NP loop unrolling
  75. align 4
  76. m32_jumptable:
  77. dd m32_case0
  78. dd m32_case1
  79. dd m32_case2
  80. dd m32_case3
  81. nop
  82. align 8
  83. nop
  84. nop
  85. nop ; Get loop nicely aligned
  86. m32_case0:
  87. sub ebp,4 ; U
  88. jbe SHORT m32_done ; V
  89. m32_loop:
  90. mov eax,[esi+4] ; U
  91. mov ebx,edx ; V Remember carry for later
  92. add esi,16 ; U
  93. add edi,16 ; V
  94. mul ecx ; NP
  95. add eax,ebx ; U Add carry in from previous word
  96. adc edx,0 ; U
  97. mov [edi-12],eax ; V
  98. m32_case3:
  99. mov eax,[esi-8] ; U
  100. mov ebx,edx ; V Remember carry for later
  101. mul ecx ; NP
  102. add eax,ebx ; U Add carry in from previous word
  103. adc edx,0 ; U
  104. mov [edi-8],eax ; V
  105. m32_case2:
  106. mov eax,[esi-4] ; U
  107. mov ebx,edx ; V Remember carry for later
  108. mul ecx ; NP
  109. add eax,ebx ; U Add carry in from previous word
  110. adc edx,0 ; U
  111. mov [edi-4],eax ; V
  112. m32_case1:
  113. mov eax,[esi] ; U
  114. mov ebx,edx ; V Remember carry for later
  115. mul ecx ; NP
  116. add eax,ebx ; U Add carry in from previous word
  117. adc edx,0 ; U
  118. mov [edi],eax ; V
  119. sub ebp,4 ; U
  120. ja SHORT m32_loop ; V
  121. m32_done:
  122. mov [edi+4],edx ; U
  123. pop edi ; V
  124. pop ebp ; U
  125. pop esi ; V
  126. ret ; NP
  127. _lbnMulN1_32 endp
  128. align 16
  129. _lbnMulAdd1_32 proc near
  130. push esi ; U
  131. mov esi,[esp+12] ; V load in
  132. push edi ; U
  133. mov edi,[esp+12] ; V load out
  134. push ebp ; U
  135. mov ebp,[esp+24] ; V load len
  136. mov ecx,[esp+28] ; U load k
  137. ;; First multiply step has no carry in.
  138. mov eax,[esi] ; V
  139. mov ebx,[edi] ; U
  140. mul ecx ; NP first multiply
  141. add ebx,eax ; U
  142. lea eax,[ebp*4-4] ; V loop unrolling
  143. adc edx,0 ; U
  144. and eax,12 ; V loop unrolling
  145. mov [edi],ebx ; U
  146. add esi,eax ; V loop unrolling
  147. add edi,eax ; U loop unrolling
  148. jmp DWORD PTR ma32_jumptable[eax] ; NP loop unrolling
  149. align 4
  150. ma32_jumptable:
  151. dd ma32_case0
  152. dd ma32_case1
  153. dd ma32_case2
  154. dd ma32_case3
  155. nop
  156. align 8
  157. nop
  158. nop
  159. nop ; To align loop properly
  160. ma32_case0:
  161. sub ebp,4 ; U
  162. jbe SHORT ma32_done ; V
  163. ma32_loop:
  164. mov eax,[esi+4] ; U
  165. mov ebx,edx ; V Remember carry for later
  166. add esi,16 ; U
  167. add edi,16 ; V
  168. mul ecx ; NP
  169. add eax,ebx ; U Add carry in from previous word
  170. mov ebx,[edi-12] ; V
  171. adc edx,0 ; U
  172. add ebx,eax ; V
  173. adc edx,0 ; U
  174. mov [edi-12],ebx ; V
  175. ma32_case3:
  176. mov eax,[esi-8] ; U
  177. mov ebx,edx ; V Remember carry for later
  178. mul ecx ; NP
  179. add eax,ebx ; U Add carry in from previous word
  180. mov ebx,[edi-8] ; V
  181. adc edx,0 ; U
  182. add ebx,eax ; V
  183. adc edx,0 ; U
  184. mov [edi-8],ebx ; V
  185. ma32_case2:
  186. mov eax,[esi-4] ; U
  187. mov ebx,edx ; V Remember carry for later
  188. mul ecx ; NP
  189. add eax,ebx ; U Add carry in from previous word
  190. mov ebx,[edi-4] ; V
  191. adc edx,0 ; U
  192. add ebx,eax ; V
  193. adc edx,0 ; U
  194. mov [edi-4],ebx ; V
  195. ma32_case1:
  196. mov eax,[esi] ; U
  197. mov ebx,edx ; V Remember carry for later
  198. mul ecx ; NP
  199. add eax,ebx ; U Add carry in from previous word
  200. mov ebx,[edi] ; V
  201. adc edx,0 ; U
  202. add ebx,eax ; V
  203. adc edx,0 ; U
  204. mov [edi],ebx ; V
  205. sub ebp,4 ; U
  206. ja SHORT ma32_loop ; V
  207. ma32_done:
  208. pop ebp ; U
  209. mov eax,edx ; V
  210. pop edi ; U
  211. pop esi ; V
  212. ret ; NP
  213. _lbnMulAdd1_32 endp
  214. align 16
  215. _lbnMulSub1_32 proc near
  216. push esi ; U
  217. mov esi,[esp+12] ; V load in
  218. push edi ; U
  219. mov edi,[esp+12] ; V load out
  220. push ebp ; U
  221. mov ebp,[esp+24] ; V load len
  222. mov ecx,[esp+28] ; U load k
  223. ;; First multiply step has no carry in.
  224. mov eax,[esi] ; V
  225. mov ebx,[edi] ; U
  226. mul ecx ; NP first multiply
  227. sub ebx,eax ; U
  228. lea eax,[ebp*4-4] ; V loop unrolling
  229. adc edx,0 ; U
  230. and eax,12 ; V loop unrolling
  231. mov [edi],ebx ; U
  232. add esi,eax ; V loop unrolling
  233. add edi,eax ; U loop unrolling
  234. jmp DWORD PTR ms32_jumptable[eax] ; NP loop unrolling
  235. align 4
  236. ms32_jumptable:
  237. dd ms32_case0
  238. dd ms32_case1
  239. dd ms32_case2
  240. dd ms32_case3
  241. nop
  242. align 8
  243. nop
  244. nop
  245. nop
  246. ms32_case0:
  247. sub ebp,4 ; U
  248. jbe SHORT ms32_done ; V
  249. ms32_loop:
  250. mov eax,[esi+4] ; U
  251. mov ebx,edx ; V Remember carry for later
  252. add esi,16 ; U
  253. add edi,16 ; V
  254. mul ecx ; NP
  255. add eax,ebx ; U Add carry in from previous word
  256. mov ebx,[edi-12] ; V
  257. adc edx,0 ; U
  258. sub ebx,eax ; V
  259. adc edx,0 ; U
  260. mov [edi-12],ebx ; V
  261. ms32_case3:
  262. mov eax,[esi-8] ; U
  263. mov ebx,edx ; V Remember carry for later
  264. mul ecx ; NP
  265. add eax,ebx ; U Add carry in from previous word
  266. mov ebx,[edi-8] ; V
  267. adc edx,0 ; U
  268. sub ebx,eax ; V
  269. adc edx,0 ; U
  270. mov [edi-8],ebx ; V
  271. ms32_case2:
  272. mov eax,[esi-4] ; U
  273. mov ebx,edx ; V Remember carry for later
  274. mul ecx ; NP
  275. add eax,ebx ; U Add carry in from previous word
  276. mov ebx,[edi-4] ; V
  277. adc edx,0 ; U
  278. sub ebx,eax ; V
  279. adc edx,0 ; U
  280. mov [edi-4],ebx ; V
  281. ms32_case1:
  282. mov eax,[esi] ; U
  283. mov ebx,edx ; V Remember carry for later
  284. mul ecx ; NP
  285. add eax,ebx ; U Add carry in from previous word
  286. mov ebx,[edi] ; V
  287. adc edx,0 ; U
  288. sub ebx,eax ; V
  289. adc edx,0 ; U
  290. mov [edi],ebx ; V
  291. sub ebp,4 ; U
  292. ja SHORT ms32_loop ; V
  293. ms32_done:
  294. pop ebp ; U
  295. mov eax,edx ; V
  296. pop edi ; U
  297. pop esi ; V
  298. ret ; NP
  299. _lbnMulSub1_32 endp
  300. ;; Two-word by one-word divide.  Stores quotient, returns remainder.
  301. ;; BNWORD32 lbnDiv21_32(BNWORD32 *q, BNWORD32 nh, BNWORD32 nl, BNWORD32 d)
  302. ;;                      4            8            12           16
  303. align 4
  304. _lbnDiv21_32 proc near
  305. mov edx,[esp+8] ; U Load nh
  306. mov eax,[esp+12] ; V Load nl
  307. mov ebx,[esp+4] ; U Load q
  308. div DWORD PTR [esp+16] ; NP
  309. mov [ebx],eax ; U Store quotient
  310. mov eax,edx ; V Return remainder
  311. ret
  312. _lbnDiv21_32 endp
  313. ;; Multi-word by one-word remainder.
  314. ;; This speeds up key generation.  It's not worth unrolling and so on;
  315. ;; using 32-bit divides is enough of a speedup.
  316. ;;
  317. ;; The modulus (in ebp) is often 16 bits.  Given that the dividend is 32
  318. ;; bits, the chances of saving the first divide because the high word of the
  319. ;; dividend is less than the modulus are low enough it's not worth taking
  320. ;; the cycles to test for it.
  321. ;;
  322. ;; unsigned lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
  323. ;;                     4                  8             12
  324. align 4
  325. _lbnModQ_32 proc near
  326. mov ebx,[esp+4] ; U Load n
  327. mov ecx,[esp+12] ; V Load d
  328. push ebp ; U
  329. mov ebp,[esp+12] ; V Load len
  330. xor edx,edx ; U
  331. modq32_loop:
  332. mov eax,[ebx] ; U
  333. add ebx,4 ; V
  334. div ecx ; NP
  335. dec ebp ; U
  336. jnz SHORT modq32_loop ; V
  337. pop ebp ; U
  338. mov edx,eax ; V
  339. ret ; NP
  340. _lbnModQ_32 endp
  341. _TEXT ends
  342. end