[bits 32] [section .text] ; 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 .done .loop: xor eax,eax 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 .dec_done: clc ; clear CF .done: mov eax,edi pop edi pop edx pop ebx ret ; string input in ESI ; value in EAX ; CF set if none, clear if some ; ESI set past checked area sign_dec_parse: push ebx push ecx push edx push edi xor eax, eax xor edi, edi xor ecx, ecx ; neg flag mov ebx, 10 ; base cmp byte [esi], '-' jne .no_minus inc esi mov cl, 1 .no_minus: lodsb sub al, '0' js .no_input cmp al, 9 jle .got_char .no_input: stc ; set CF jmp .done .loop: xor eax,eax 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 .dec_done: test ecx, ecx jz .not_neg neg edi .not_neg: clc ; clear CF .done: mov eax,edi pop edi pop edx pop ecx pop ebx ret ; modifies no regs newline: pushad push 10 mov eax, 4 ; write mov ebx, 1 ; stdout mov ecx, esp ; string mov edx, 1 ; length int 0x80 add esp, 4 popad ret ; modifies no regs space: pushad push 9 mov eax, 4 ; write mov ebx, 1 ; stdout mov ecx, esp ; string mov edx, 1 ; length int 0x80 add esp, 4 popad 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 ; input in EAX, all regs unmodified print_sign_dec: pushad ; save regs ; range -2147483648 to 2147483647 is 11 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, negative xor ebp, ebp test eax, eax jz .zero jns .positive neg eax mov ebp, 1 .positive: 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: test ebp, ebp jz .no_minus dec ecx inc edx mov byte [ecx], '-' .no_minus: mov eax, 4 ; write mov ebx, 1 ; stdout int 0x80 add esp, 12 ; restore stack popad ; restore regs ret ; input in ESI, len in ECX, all regs unmodified print_string: pushad ; save regs mov eax, 4 ; write mov ebx, 1 ; stdout mov edx, ecx ; length mov ecx, esi ; string int 0x80 popad ; restore regs ret ; input in AL, all regs unmodified print_char: pushad ; save regs push eax mov eax, 4 ; write mov ebx, 1 ; stdout mov edx, 1 ; length mov ecx, esp ; string int 0x80 add esp, 4 popad ; restore regs ret ; --- MACROS --- %define len(x) x %+ .over - x %macro p_string 1 push esi push ecx mov esi, %1 mov ecx, len(%1) call print_string pop ecx pop esi %endmacro