crc_i86.asm
上传用户:andy_li
上传日期:2007-01-06
资源大小:1019k
文件大小:10k
源码类别:

压缩解压

开发平台:

MultiPlatform

  1. ; Not copyrighted by Christian Spieler, 02 Apr 1997.
  2. ;
  3.         TITLE   crc_i86.asm
  4.         NAME    crc_i86
  5. ;
  6. ; Optimized 8086 assembler version of the CRC32 calculation loop, intended
  7. ; for real mode Info-ZIP programs (Zip 2.1, UnZip 5.2, and later versions).
  8. ; Supported compilers are Microsoft C (DOS real mode) and Borland C(++)
  9. ; (Turbo C). Watcom C (16bit) should also work.
  10. ; This module was inspired by a similar module for the Amiga (Paul Kienitz).
  11. ;
  12. ; It replaces the `ulg crc32(ulg crc, ZCONST uch *buf, extent len)' function
  13. ; in crc32.c.
  14. ;
  15. ; In March/April 1997, the code has been revised to incorporate Rodney Brown's
  16. ; ideas for optimized access to the data buffer. For 8086 real mode code,
  17. ; the data buffer is now accessed by aligned word-wide read operations.
  18. ; This new optimization may be turned off by defining the macro switch
  19. ; NO_16_BIT_LOADS.
  20. ;
  21. ; The code in this module should work with all kinds of C memory models
  22. ; (except Borland's __HUGE__ model), as long as the following
  23. ; restrictions are not violated:
  24. ;
  25. ; - The implementation assumes that the char buffer is confined to a
  26. ;   64k segment. The pointer `s' to the buffer must be in a format that
  27. ;   all bytes can be accessed by manipulating the offset part, only.
  28. ;   This means:
  29. ;   + no huge pointers
  30. ;   + char buffer size < 64 kByte
  31. ;
  32. ; - Since the buffer size argument `n' is of type `size_t' (= unsigned short)
  33. ;   for this routine, the char buffer size is limited to less than 64 kByte,
  34. ;   anyway. So, the assumption above should be easily fulfilled.
  35. ;
  36. ;==============================================================================
  37. ;
  38. ; Do NOT assemble this source if external crc32 routine from zlib gets used.
  39. ;
  40. ifndef USE_ZLIB
  41. ;
  42. ; Setup of amount of assemble time informational messages:
  43. ;
  44. ifdef     DEBUG
  45.   VERBOSE_INFO EQU 1
  46. else
  47.   ifdef _AS_MSG_
  48.     VERBOSE_INFO EQU 1
  49.   else
  50.     VERBOSE_INFO EQU 0
  51.   endif
  52. endif
  53. ;
  54. ; Selection of memory model, and initialization of memory model
  55. ; related macros:
  56. ;
  57. ifndef __SMALL__
  58.   ifndef __COMPACT__
  59.     ifndef __MEDIUM__
  60.       ifndef __LARGE__
  61.         ifndef __HUGE__
  62. ;         __SMALL__ EQU 1
  63.         endif
  64.       endif
  65.     endif
  66.   endif
  67. endif
  68. ifdef __HUGE__
  69. ; .MODEL Huge
  70.    @CodeSize  EQU 1
  71.    @DataSize  EQU 1
  72.    Save_DS    EQU 1
  73.    if VERBOSE_INFO
  74.     if1
  75.       %out Assembling for C, Huge memory model
  76.     endif
  77.    endif
  78. else
  79.    ifdef __LARGE__
  80. ;      .MODEL Large
  81.       @CodeSize  EQU 1
  82.       @DataSize  EQU 1
  83.       if VERBOSE_INFO
  84.        if1
  85.          %out Assembling for C, Large memory model
  86.        endif
  87.       endif
  88.    else
  89.       ifdef __COMPACT__
  90. ;         .MODEL Compact
  91.          @CodeSize  EQU 0
  92.          @DataSize  EQU 1
  93.          if VERBOSE_INFO
  94.           if1
  95.             %out Assembling for C, Compact memory model
  96.           endif
  97.          endif
  98.       else
  99.          ifdef __MEDIUM__
  100. ;            .MODEL Medium
  101.             @CodeSize  EQU 1
  102.             @DataSize  EQU 0
  103.             if VERBOSE_INFO
  104.              if1
  105.                %out Assembling for C, Medium memory model
  106.              endif
  107.             endif
  108.          else
  109. ;            .MODEL Small
  110.             @CodeSize  EQU 0
  111.             @DataSize  EQU 0
  112.             if VERBOSE_INFO
  113.              if1
  114.                %out Assembling for C, Small memory model
  115.              endif
  116.             endif
  117.          endif
  118.       endif
  119.    endif
  120. endif
  121. if @CodeSize
  122.         LCOD_OFS        EQU     2
  123. else
  124.         LCOD_OFS        EQU     0
  125. endif
  126. IF @DataSize
  127.         LDAT_OFS        EQU     2
  128. else
  129.         LDAT_OFS        EQU     0
  130. endif
  131. ifdef Save_DS
  132. ;                       (di,si,ds)+(size, return address)
  133.         SAVE_REGS       EQU     6+(4+LCOD_OFS)
  134. else
  135. ;                       (di,si)+(size, return address)
  136.         SAVE_REGS       EQU     4+(4+LCOD_OFS)
  137. endif
  138. ;
  139. ; Selection of the supported CPU instruction set and initialization
  140. ; of CPU type related macros:
  141. ;
  142. ifdef __586
  143.         Use_286_code    EQU     1
  144.         Align_Size      EQU     16      ; paragraph alignment on Pentium
  145.         Alig_PARA       EQU     1       ; paragraph aligned code segment
  146. else
  147. ifdef __486
  148.         Use_286_code     EQU    1
  149.         Align_Size       EQU    4       ; dword alignment on 32 bit processors
  150.         Alig_PARA        EQU    1       ; paragraph aligned code segment
  151. else
  152. ifdef __386
  153.         Use_286_code    EQU     1
  154.         Align_Size      EQU     4       ; dword alignment on 32 bit processors
  155.         Alig_PARA       EQU     1       ; paragraph aligned code segment
  156. else
  157. ifdef __286
  158.         Use_286_code    EQU     1
  159.         Align_Size      EQU     2       ; word alignment on 16 bit processors
  160.         Alig_PARA       EQU     0       ; word aligned code segment
  161. else
  162. ifdef __186
  163.         Use_186_code    EQU     1
  164.         Align_Size      EQU     2       ; word alignment on 16 bit processors
  165.         Alig_PARA       EQU     0       ; word aligned code segment
  166. else
  167.         Align_Size      EQU     2       ; word alignment on 16 bit processors
  168.         Alig_PARA       EQU     0       ; word aligned code segment
  169. endif   ;?__186
  170. endif   ;?__286
  171. endif   ;?__386
  172. endif   ;?__486
  173. endif   ;?__586
  174. ifdef Use_286_code
  175.         .286
  176.         Have_80x86      EQU     1
  177. else
  178. ifdef Use_186_code
  179.         .186
  180.         Have_80x86      EQU     1
  181. else
  182.         .8086
  183.         Have_80x86      EQU     0
  184. endif   ;?Use_186_code
  185. endif   ;?Use_286_code
  186. ;
  187. ; Declare the segments used in this module:
  188. ;
  189. if @CodeSize
  190. if Alig_PARA
  191. CRC32_TEXT      SEGMENT  PARA PUBLIC 'CODE'
  192. else
  193. CRC32_TEXT      SEGMENT  WORD PUBLIC 'CODE'
  194. endif
  195. CRC32_TEXT      ENDS
  196. else    ;!@CodeSize
  197. if Alig_PARA
  198. _TEXT   SEGMENT  PARA PUBLIC 'CODE'
  199. else
  200. _TEXT   SEGMENT  WORD PUBLIC 'CODE'
  201. endif
  202. _TEXT   ENDS
  203. endif   ;?@CodeSize
  204. _DATA   SEGMENT  WORD PUBLIC 'DATA'
  205. _DATA   ENDS
  206. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  207. _BSS    ENDS
  208. DGROUP  GROUP   _BSS, _DATA
  209. if @DataSize
  210.         ASSUME  DS: nothing, SS: DGROUP
  211. else
  212.         ASSUME  DS: DGROUP, SS: DGROUP
  213. endif
  214. if @CodeSize
  215. EXTRN   _get_crc_table:FAR
  216. else
  217. EXTRN   _get_crc_table:NEAR
  218. endif
  219. Do_CRC  MACRO
  220.         mov     bl,al
  221.         sub     bh,bh
  222. if Have_80x86
  223.         shl     bx,2
  224. else
  225.         shl     bx,1
  226.         shl     bx,1
  227. endif
  228.         mov     al,ah
  229.         mov     ah,dl
  230.         mov     dl,dh
  231.         sub     dh,dh
  232.         xor     ax,WORD PTR [bx][si]
  233.         xor     dx,WORD PTR [bx+2][si]
  234.         ENDM
  235. ;
  236. Do_1    MACRO
  237. if @DataSize
  238.         xor     al,BYTE PTR es:[di]
  239. else
  240.         xor     al,BYTE PTR [di]
  241. endif
  242.         inc     di
  243.         Do_CRC
  244.         ENDM
  245. ;
  246. Do_2    MACRO
  247. ifndef NO_16_BIT_LOADS
  248. if @DataSize
  249.         xor     ax,WORD PTR es:[di]
  250. else
  251.         xor     ax,WORD PTR [di]
  252. endif
  253.         add     di,2
  254.         Do_CRC
  255.         Do_CRC
  256. else
  257.         Do_1
  258.         Do_1
  259. endif
  260.         ENDM
  261. ;
  262. Do_4    MACRO
  263.         Do_2
  264.         Do_2
  265.         ENDM
  266. ;
  267. IF @CodeSize
  268. CRC32_TEXT      SEGMENT
  269.         ASSUME  CS: CRC32_TEXT
  270. else
  271. _TEXT   SEGMENT
  272.         ASSUME  CS: _TEXT
  273. endif
  274. ; Line 37
  275. ;
  276. ;ulg crc32(ulg crc,
  277. ;    ZCONST uch *buf,
  278. ;    extend len)
  279. ;
  280.         PUBLIC  _crc32
  281. if @CodeSize
  282. _crc32  PROC FAR
  283. else
  284. _crc32  PROC NEAR
  285. endif
  286. if Have_80x86
  287.         enter   WORD PTR 0,0
  288. else
  289.         push    bp
  290.         mov     bp,sp
  291. endif
  292.         push    di
  293.         push    si
  294. if @DataSize
  295. ;       crc = 4+LCOD_OFS        DWORD (unsigned long)
  296. ;       buf = 8+LCOD_OFS        DWORD PTR BYTE (uch *)
  297. ;       len = 12+LCOD_OFS       WORD (unsigned int)
  298. else
  299. ;       crc = 4+LCOD_OFS        DWORD (unsigned long)
  300. ;       buf = 8+LCOD_OFS        WORD PTR BYTE (uch *)
  301. ;       len = 10+LCOD_OFS       WORD (unsigned int)
  302. endif
  303. ;
  304. if @DataSize
  305.         mov     ax,WORD PTR [bp+8+LCOD_OFS]     ; buf
  306.         or      ax,WORD PTR [bp+10+LCOD_OFS]    ;     == NULL ?
  307. else
  308.         cmp     WORD PTR [bp+8+LCOD_OFS],0      ; buf == NULL ?
  309. endif
  310.         jne     crc_update
  311.         sub     ax,ax                           ; crc = 0
  312.         cwd
  313. ifndef NO_UNROLLED_LOOPS
  314.         jmp     fine
  315. else
  316.         jmp     SHORT fine
  317. endif
  318. ;
  319. crc_update:
  320.         call     _get_crc_table
  321. ;  When used with compilers that conform to the Microsoft/Borland standard
  322. ;  C calling convention, model-dependent handling is not needed, because
  323. ;   _get_crc_table returns NEAR pointer.
  324. ;  But Watcom C is different and does not allow one to assume DS pointing to
  325. ;  DGROUP. So, we load DS with DGROUP, to be safe.
  326. ;if @DataSize
  327. ;       push    ds
  328. ;       mov     ds,dx
  329. ;       ASSUME  DS: nothing
  330. ;endif
  331.         mov     si,ax                           ;crc_table
  332. if @DataSize
  333.         push    ds
  334.         mov     ax,SEG DGROUP
  335.         mov     ds,ax
  336.         ASSUME  DS: DGROUP
  337. endif
  338. ;
  339.         mov     ax,WORD PTR [bp+4+LCOD_OFS]     ;crc
  340.         mov     dx,WORD PTR [bp+6+LCOD_OFS]
  341.         not     ax
  342.         not     dx
  343. if @DataSize
  344.         les     di,DWORD PTR [bp+8+LCOD_OFS]    ;buf
  345.         mov     cx,WORD PTR [bp+12+LCOD_OFS]    ;len
  346. else
  347.         mov     di,WORD PTR [bp+8+LCOD_OFS]     ;buf
  348.         mov     cx,WORD PTR [bp+10+LCOD_OFS]    ;len
  349. endif
  350. ;
  351. ifndef NO_UNROLLED_LOOPS
  352. ifndef NO_16_BIT_LOADS
  353.         test    cx,cx
  354.         jnz     start
  355.         jmp     done
  356. start:  test    di,1
  357.         jz      is_wordaligned
  358.         dec     cx
  359.         Do_1
  360.         mov     WORD PTR [bp+10+LDAT_OFS+LCOD_OFS],cx
  361. is_wordaligned:
  362. endif ; !NO_16_BIT_LOADS
  363. if Have_80x86
  364.         shr     cx,2
  365. else
  366.         shr     cx,1
  367.         shr     cx,1
  368. endif
  369.         jcxz    No_Fours
  370. ;
  371.         align   Align_Size              ; align destination of branch
  372. Next_Four:
  373.         Do_4
  374.         loop    Next_Four
  375. ;
  376. No_Fours:
  377. if @DataSize
  378.         mov     cx,WORD PTR [bp+12+LCOD_OFS]    ;len
  379. else
  380.         mov     cx,WORD PTR [bp+10+LCOD_OFS]    ;len
  381. endif
  382.         and     cx,00003H
  383. endif ; !NO_UNROLLED_LOOPS
  384.         jcxz    done
  385. ;
  386.         align   Align_Size              ; align destination of branch
  387. Next_Byte:
  388.         Do_1
  389.         loop    Next_Byte
  390. ;
  391. done:
  392. if @DataSize
  393.         pop     ds
  394. ;       ASSUME  DS: DGROUP
  395.         ASSUME  DS: nothing
  396. endif
  397.         not     ax
  398.         not     dx
  399. ;
  400. fine:
  401.         pop     si
  402.         pop     di
  403. if Have_80x86
  404.         leave
  405. else
  406.         mov     sp,bp
  407.         pop     bp
  408. endif
  409.         ret
  410. _crc32  ENDP
  411. if @CodeSize
  412. CRC32_TEXT      ENDS
  413. else
  414. _TEXT   ENDS
  415. endif
  416. ;
  417. endif ;!USE_ZLIB
  418. ;
  419. END