ok... I'm trying to generate the lookup table for ANSI CRC16 poly/reflect/reverse of reciprocal 8005h / A001h / C002h. Doing this in real mode x86. I can't seem to get it working I've fiddled with the code for a few days to no avail. Any help would be appreciated.


crc_16_table dw 0x0600
crc_16_poly dw 0A001h
crc_16_reflect dw 08005h
crc_16_neg dw 0FFFFh
push CX

mov CX, 08h
xor AL, 0FFh
shr AX, 1
jnc .next_bit
xor AX,
loop .begin

pop CX


push SI

; mov SI, ;for saving table to later... after i get this working
xor CX, CX ;counter = 0

mov AL, CL ;initial current char = 00h
inc CX ;increment counter
call create_crc
call hex_print_16 ;print hex of AX
cmp CX, 100h
jne .next_char

pop SI

Posted on 2009-11-18 07:21:54 by Goose007
Maybe you should post the actual algorithm you are trying to implement.

Here's what your create_crc code seems to do

crc = crc ^ 0FFh; //flip all bits 0's to 1's, 1's to 0's
for(bit=0; bit<8; bit++){ //loop 8 times
  carry = crc & 1; //get the bit that will be shifted out
  crc = crc >> 1; //shift lowest bit out (same as divide by 2
  if(carry == 1){ //if the shifted bit was set
    crc = crc ^ 0A001h; //xor by magic number

Other notes:
- Your hex_print_16 function might be changing the value of CX which could cause problems, but you didn't post that code so there's no way of knowing.
- You have _reflect and _neg variables that you don't seem to be using.

Good luck, and comment your code
Posted on 2009-11-18 09:08:02 by r22
right... sorry it was super early. I sometimes forget my manners. well I have working (i think) CRC16 but it is slowww. I wanted to add the lookup table to speed things up. I can't find a good axample of creating the table that I've been able to implement. as for commenting... i was changing things around trying to get it to work i was leaving it out till i found something that worked. I will try and be awake enough to put comments in before posting. This is my first attempt at CRC so I'm still grasping the concept. I will post the algo and the slow working code(if i didn't overwrite it) when i get back to the house in about 2.5 hours. thanks for reminding me of my bad forum habits... I am truly sorry.
Posted on 2009-11-18 09:43:39 by Goose007
Here's a link to a C++ implementation of CRC16, it looks complete and correct.

It should help you with your ASM solution

good luck
Posted on 2009-11-18 11:38:55 by r22
Ok, here is my completed code for generating CRC16. I'm pretty sure this is IEEE standard (not for certain since I only found an excerpt, didn't realize subscriptions were $10k)... I think at first I was trying to do modbus(which switches the high and low bytes of words). Either way this seems to work.. From what I've read this should be able to generate unique CRCs for data up to 8192 bytes in length. Can anyone verify my work? Most of the apps I found to check my work were CCITT so I was getting very frustrated.


crc_16_table dw 0x0600
crc_16_poly dw 0A001h
crc_16_init dw 0000h

call init_crc_16
;call init_crc_32

push SI
push AX
push CX

CLD ;clear direction

mov SI, ;for saving table to later... after i get this working
xor CX, CX
xor AX, AX ;counter = 0

mov AX, CX ;current char to be processed = count
inc CX ;increment counter
call create_crc ;create crc of byte
mov , AX ;copy crc to memory
add SI, 2 ;increment SI by word length
cmp CX, 100h ;have we done all 256 chars
jne .next_char

pop CX
pop AX
pop SI


; AL = char
push CX

mov CX, 08h ; 8 bits per byte
xor AL, ; xor with initiating value
shr AX, 1 ; shift rightmost bit into carry
jnc .next_bit ; if 0 goto next bit
xor AX, ; else xor with poly
.next_bit: ; next bit is zero, do nothing
loop .begin ; do this for all 8 bits

pop CX

ret ; return with crc of initial char in AX

;AX = Address
;CX = Length
push SI
push DI
push BX

CLD ; direction up
xor SI, SI ; zero SI
mov SI, AX ; SI = start of input
mov DI, ; DI = our precalculated table

mov BX, ; BX = initial crc

xor AX, AX ; Zero AX
mov AL, ; grab a byte from our input
inc SI ; increment for next grab
xchg AX, BX ; exchange CRC with our Char BL = char, AX = crc
xor BL, AL ; xor with current crc to get our index in table
xor BH, BH ; zero out hi bytes
shl BX, 1 ; *2 to get our word index
shr AX, 8 ; shift high byte to low byte
xor AX, word ; CRC = CRC xor table
mov BX, AX ; BX = CRC
loop .crc_loop ; do this till counter reaches zero

mov AX, BX ; move crc to AX

pop BX
pop DI
pop SI

ret ; returns CRC in AX

Posted on 2009-11-20 11:19:51 by Goose007