📄 crc32.asm
字号:
;本代码引用了老罗的 <<矛与盾的较量——CRC原理篇>>
;略作改动
;原文出自:www.luocong.com
.data
crc32tbl dd 256 dup(0)
.code
init_crc32table proc
;如果用C语言来表示,应该如下:
;
; for (i = 0; i < 256; i++)
; {
; crc = i;
; for (j = 0; j < 8; j++)
; {
; if (crc & 1)
; crc = (crc >> 1) ^ 0xEDB88320;
; else
; crc >>= 1;
; }
; crc32tbl[i] = crc;
; }
;
;呵呵,让我们把上面的语句改成assembly的:
mov ecx, 256 ; repeat for every DWORD in table
mov edx, 0EDB88320h
$BigLoop:
lea eax, [ecx-1]
push ecx
mov ecx, 8
$SmallLoop:
shr eax, 1
jnc @F
xor eax, edx
@@:
dec ecx
jne $SmallLoop
pop ecx
mov [crc32tbl+ecx*4-4], eax
dec ecx
jne $BigLoop
ret
init_crc32table endp
;**************************************************************
;函数功能:计算CRC-32
;传入参数:
;@lpBuf:数组的开始地址
;@lpBufEnd:数组的结束地址
;返回值:
;eax-计算出来的CRC32值
;**************************************************************
calc_crc32 proc uses edx ebx @lpBuf,@lpBufEnd
;计算 CRC-32 ,我采用的是把整个字符串当作一个数组,
;然后把这个数组的首地址赋值给 EBX,把数组的长度赋值给 ECX,然后循环计算,
;返回值(计算出来的 CRC-32 值)储存在 EAX 中:
;
; 参数:
; EBX = address of first byte
; 返回值:
; EAX = CRC-32 of the entire array
; EBX = ?
; ECX = 0
; EDX = ?
call init_crc32table
mov eax, -1 ; 先初始化eax
mov ebx,@lpBuf;我添加的
;or ebx, ebx
;jz $Done ; 避免出现空指针
@@:
mov dl, [ebx]
;or dl, dl;老罗原文
cmp ebx,@lpBufEnd
ja $Done ;判断是否对字符串扫描完毕
;这里我用查表法来计算 CRC-32 ,因此非常快速:
;因为这是assembly代码,所以不需要给这个过程传递参数,
;只需要把oldcrc赋值给EAX,以及把byte赋值给DL:
;
; 在C语言中的形式:
;
; temp = (oldcrc ^ abyte) & 0x000000FF;
; crc = (( oldcrc >> 8) & 0x00FFFFFF) ^ crc32tbl[temp];
;
; 参数:
; EAX = old CRC-32
; DL = a byte
; 返回值:
; EAX = new CRC-32
; EDX = ?
xor dl, al
movzx edx, dl
shr eax, 8
xor eax, [crc32tbl+edx*4]
inc ebx
jmp @B
$Done:
not eax
ret
calc_crc32 endp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -