Skip to content

Instantly share code, notes, and snippets.

@netman69
Created October 15, 2017 03:38
Show Gist options
  • Save netman69/fdd3b632fbfc070027067d657a73bc19 to your computer and use it in GitHub Desktop.
Save netman69/fdd3b632fbfc070027067d657a73bc19 to your computer and use it in GitHub Desktop.
CRC32C calculation utility (standalone x86 32bit nasm version).
%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