diff --git a/02/main.s b/02/main.s index cd3ec5e..d9bc193 100644 --- a/02/main.s +++ b/02/main.s @@ -1,31 +1,17 @@ %define BUFF_LIM 32768 -%define red_lim 12 -%define green_lim 13 -%define blue_lim 14 -%define limits ((red_lim << 16) | (green_lim << 8) | blue_lim) - -; 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] + +%include "utils.s" + _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 +call open_file mov ecx, read_buff mov edx, BUFF_LIM -int 0x80 -test eax,eax -js exit +call read_file add eax, read_buff mov [file_lim], eax @@ -90,77 +76,6 @@ mov eax, [final_value] call print_dec jmp exit -exit: -mov eax, 1 -int 0x80 ; exit - -; string in esi -; modifies EAX ESI -dec_parse: -push ebx -push ecx -push edx -push edi -xor eax, eax -xor ecx, ecx -xor edi, edi -mov ebx, 10 -.loop: -lodsb -sub al, '0' -js .dec_done -cmp al, 9 -jg .dec_done -xchg edi,eax -mul ebx -add edi,eax -jmp .loop -.dec_done: -mov eax,edi -pop edi -pop edx -pop ecx -pop ebx -ret - -; input in EAX, all regs unmodified -print_dec: -pushad ; save regs -; max 4294967296 is 10 chars -; round to nearest 32-bit boundary -sub esp, 12 -; string in ECX, length in EDX -lea ecx, [esp+11] ; last possible byte -; check for 0 -test eax, eax -jz .zero -mov ebx, 10 ; base 10 -xor esi, esi ; counter -.div_shit: -xor edx, edx -; divide -div ebx -dec ecx ; next char -inc esi -; store -add dl, '0' -mov byte [ecx], dl -; check if done -test eax, eax -jnz .div_shit ; continue -mov edx, esi ; counter in edx -jmp .write -.zero: -mov byte [ecx], '0' -mov edx, 1 ; length -.write: -mov eax, 4 ; write -mov ebx, 1 ; stdout -int 0x80 -add esp, 12 ; restore stack -popad ; restore regs -ret - [section .data] file_lim: dd 0 final_value: dd 0 diff --git a/02/utils.s b/02/utils.s new file mode 100644 index 0000000..3feccf8 --- /dev/null +++ b/02/utils.s @@ -0,0 +1,119 @@ +; call # val val2 +; int $0x80 eax eax edx - +; +; arg1 arg2 arg3 arg4 arg5 arg6 arg7 +; ebx ecx edx esi edi ebp - + +exit: +mov eax, 1 ; exit +int 0x80 + +; filename in EBX +; return handle in EBX +; read only +open_file: +push eax +push ecx +mov eax, 5 ; open +xor ecx, ecx ; read only +int 0x80 +mov ebx, eax +pop ecx +pop eax +ret + +; file handle in EBX +; buffer in ECX +; count of bytes to read in EDX +; return bytes actually read in EAX +; exits on error +read_file: +mov eax, 3 ; read +int 0x80 +test eax, eax +js .err +ret +.err: +mov eax, 4 ; write +mov ebx, 1 ; stdout +mov ecx, .err_str +mov edx, 21 +int 0x80 +jmp exit +.err_str: db `Could not read file.\n` + +; string input in ESI +; value in EAX +; CF set if none, clear if some +; ESI set past checked area +dec_parse: +push ebx +push edx +push edi +xor eax, eax +xor edi, edi +mov ebx, 10 ; base +lodsb +sub al, '0' +js .no_input +cmp al, 9 +jle .got_char +.no_input: +stc ; set CF +jmp .dec_done +.loop: +lodsb +sub al, '0' +js .dec_done +cmp al, 9 +jg .dec_done +.got_char: +xchg edi,eax +mul ebx +add edi,eax +jmp .loop +clc ; clear CF +.dec_done: +mov eax,edi +pop edi +pop edx +pop ebx +ret + +; input in EAX, all regs unmodified +print_dec: +pushad ; save regs +; max 4294967296 is 10 chars +; round to nearest 32-bit boundary +sub esp, 12 +; string in ECX, length in EDX +lea ecx, [esp+11] ; last possible byte +; check for 0 +test eax, eax +jz .zero +mov ebx, 10 ; base 10 +xor esi, esi ; counter +.div_shit: +xor edx, edx +; divide +div ebx +dec ecx ; next char +inc esi +; store +add dl, '0' +mov byte [ecx], dl +; check if done +test eax, eax +jnz .div_shit ; continue +mov edx, esi ; counter in edx +jmp .write +.zero: +mov byte [ecx], '0' +mov edx, 1 ; length +.write: +mov eax, 4 ; write +mov ebx, 1 ; stdout +int 0x80 +add esp, 12 ; restore stack +popad ; restore regs +ret