Skip to content

Instantly share code, notes, and snippets.

@netman69
Created October 15, 2017 03:38
Show Gist options
  • Select an option

  • Save netman69/fdd3b632fbfc070027067d657a73bc19 to your computer and use it in GitHub Desktop.

Select an option

Save netman69/fdd3b632fbfc070027067d657a73bc19 to your computer and use it in GitHub Desktop.

Revisions

  1. netman69 created this gist Oct 15, 2017.
    140 changes: 140 additions & 0 deletions crc32c_32bit.asm
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,140 @@
    %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