%define BUFF_LIM 32768 ; call # val val2 ; int $0x80 eax eax edx - ; ; arg1 arg2 arg3 arg4 arg5 arg6 arg7 ; ebx ecx edx esi edi ebp - global _start [bits 32] [section .text] _start: push 0 ; eof mov eax, 5 ; open mov ebx, filename xor ecx, ecx ; read only int 0x80 mov ebx, eax mov eax, 3 ; read mov ecx, read_buff mov edx, BUFF_LIM int 0x80 cmp eax, -1 ; err je exit cmp eax, BUFF_LIM je .no_eof ; we hit eof inc dword [esp] .no_eof: ; parse section lea edi, [read_buff+eax] mov esi, read_buff .cont_read: xor ecx, ecx ; set if first is found ; last digit in ebx xor ebx, ebx ; counting loop xor eax, eax push eax ; first digit jmp .count_loop_cont .count_loop: lodsb cmp al, 10 ; newline je .next_line cmp al, '0' jl .count_loop_cont cmp al, '9' jg .check_str sub al, '0' ; reset string parsing when we got a numeral call reset_string_wheels .matched: test ecx, ecx jnz .have_first mov [esp], eax ; first digit inc ecx .have_first: mov ebx, eax ; set last to current .count_loop_cont: cmp esi, edi jl .count_loop .next_line: test ecx, ecx jz .check_end ; no digits (huh?) pop eax ; first digit mov dl, 10 mul dl add eax, ebx ; add to total add [final_value], eax .check_end: ; reset string parsing when we got a newline call reset_string_wheels ; check for more data cmp esi, edi jl .cont_read ; TODO handle files over BUFF_LIM bytes ; check for EOF cmp dword [esp], 1 jne .cont_read ; we're at EOF, print result mov eax, [final_value] call print_dec jmp exit .check_str: call weird_string_parser ; check result mov al, [matched_value] test al, al jnz .match_found ; nothing matched yet ; check if we got a word char cmp byte [matched_any_char], 1 je .count_loop_cont ; not a word char, reset wheels call reset_string_wheels jmp .count_loop_cont .match_found: ; we have a match ; reset the matched value ; and go back to loop mov byte [matched_value], 0 jmp .matched reset_string_wheels: push edi push ecx push eax mov edi, number_wheels mov ecx, number_lens - number_wheels xor eax, eax rep stosb pop eax pop ecx pop edi ret exit: mov eax, 1 int 0x80 ; exit ; i hate this print_dec: sub esp, 12 lea ecx, [esp+11] test eax, eax jz .zero mov esi, 0 mov ebx, 10 .div_shit: xor edx, edx div ebx dec ecx inc esi add dl, '0' mov byte [ecx], dl test eax, eax jnz .div_shit mov edx, esi jmp .write .zero: mov byte [esp+10], 0 lea ecx, [esp+10] mov edx, 1 ; count .write: mov eax, 4 ; write mov ebx, 1 ; stdout int 0x80 add esp, 12 ret ; i'm in hell weird_string_parser: pushad ; reset matched any char mov byte [matched_any_char], 0 mov edi, number_wheels mov esi, number_lens mov ebp, numbers mov ecx, 0 .test_loop: mov edx, ebp ; add current wheel value movzx ebx, byte [edi] add edx, ebx ; compare to input cmp byte [edx], al jne .next_test_fail ; match - increment counter inc bl ; test against length cmp byte [esi], bl je .full_match .partial_match: ; partial match - save value mov [edi], bl ; we matched any char mov byte [matched_any_char], 1 jmp .next_test_match .next_test_fail: ; reset the current wheel mov byte [edi], 0 ; check if it's the start of the word cmp byte [ebp], al jne .next_test_match ; nope ; yep! save mov bl, 1 jmp .partial_match .next_test_match: inc ecx ; check if we're done testing cmp ecx, 9 jge .done ; add current value length to string movzx ebx, byte [esi] add ebp, ebx inc edi inc esi ; loop jmp .test_loop .done: popad ret .full_match: ; save matched byte inc ecx ; zero -> one mov byte [matched_value], cl ; reset this wheel mov byte [edi], 0 ; next check jmp .next_test_match [section .data] final_value: dd 0 matched_value: db 0 matched_any_char: db 0 number_wheels: db 0,0,0,0,0,0,0,0,0 number_lens: db 3,3,5,4,4,3,5,5,4 numbers: db "onetwothreefourfivesixseveneightnine" filename: db "input",0 [section .bss] read_buff: resb BUFF_LIM