Created
October 15, 2017 03:38
-
-
Save netman69/fdd3b632fbfc070027067d657a73bc19 to your computer and use it in GitHub Desktop.
CRC32C calculation utility (standalone x86 32bit nasm version).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%define BUFSIZE 4096 | |
bits 32 | |
section .text | |
extern fdopen | |
extern fprintf | |
extern printf | |
extern open | |
extern close | |
extern read | |
%macro fail 1+ | |
push dword %%str | |
push dword [stderr] | |
call fprintf | |
add esp, 8 | |
popad | |
pop ebp | |
mov eax, 1 | |
ret | |
%%str: db %1, 10, 0 | |
%endmacro | |
global main | |
align 16 | |
main: | |
; Set up stack frame. | |
push ebp | |
mov ebp, esp | |
pushad | |
; Get command line arguments in an easy place. | |
mov eax, [ebp+8] ; argc | |
mov [argc], eax | |
mov eax, [ebp+12] ; argv | |
mov [argv], eax | |
; Get a FILE* for stderr. | |
push dword .s_w | |
push dword 2 | |
call fdopen | |
add esp, 8 | |
mov [stderr], eax | |
; Check if we got the right amount of arguments (1). | |
cmp dword [argc], 2 | |
je .argc_ok | |
; If we reach here we have more or less than 1 argument. | |
mov eax, [argv] | |
push dword [eax] | |
push dword .err_args | |
push dword [stderr] | |
call fprintf | |
add esp, 12 | |
popad | |
pop ebp | |
mov eax, 1 | |
ret | |
.err_args: db "usage: %s <filename>", 10, 0 | |
.argc_ok: | |
; Try to open the specified file. | |
mov eax, [argv] | |
add eax, 4 | |
push dword 0 | 0o00100000 ; O_RDONLY | O_LARGEFILE | |
push dword [eax] | |
call open | |
add esp, 8 | |
mov [fd], eax | |
test eax, eax | |
jns .open_ok | |
fail "error: can't open file" | |
.open_ok: | |
; EBX will hold the sum here. | |
mov ebx, 0xFFFFFFFF | |
align 16 | |
.doblock: | |
; Read a bit of the file. | |
push dword BUFSIZE | |
push dword buf | |
push dword [fd] | |
call read | |
add esp, 12 | |
; Count the length while we're at it. | |
add dword [len], eax | |
adc dword [len+4], 0 | |
; Calculate CRC of that bit. | |
mov edx, buf | |
.crc32c: ; eax = length, ebx = sum, edx = buf | |
; Do 4-byte blocks. | |
mov ecx, eax | |
shr ecx, 2 | |
test ecx, ecx | |
jz .end32 | |
align 16 | |
.step32: | |
crc32 ebx, dword [edx] ; Doesn't seem to matter much wether aligned. | |
add edx, 4 | |
loop .step32 | |
.end32: | |
; Finish. | |
mov ecx, eax | |
and ecx, 3 | |
test ecx, ecx | |
jz .end | |
align 16 | |
.step8: | |
crc32 ebx, byte [edx] | |
inc edx | |
loop .step8 | |
.end: | |
cmp eax, BUFSIZE | |
je .doblock | |
xor ebx, 0xFFFFFFFF | |
; Close the file. | |
push dword [fd] | |
call close | |
add esp, 4 | |
; Print out the result. | |
push dword [len+4] | |
push dword [len] | |
push ebx | |
push dword .format | |
call printf | |
add esp, 16 | |
; The end. | |
popad | |
pop ebp | |
xor eax, eax | |
ret | |
.format: db "%08X %llu", 10, 0 | |
.s_w: db "w", 0 | |
section .bss | |
stderr: resd 1 | |
argc: resd 1 | |
argv: resd 1 | |
fd: resd 1 | |
len: resq 1 | |
buf: resb BUFSIZE |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment