; PRIVATE FIELDS __shell.buf__ rd 1 __shell.name__ rb 16 __shell.str__ rb 16 ;----------------------------------- ; a = 0 ;----------------------------------- macro clear a { xor a, a } ;----------------------------------- ; if a == b then c ;----------------------------------- macro cmpe a, b, c { cmp a, b je c } ;----------------------------------- ; if a != b then c ;----------------------------------- macro cmpne a, b, c { cmp a, b jne c } ;----------------------------------- ; Shell`s initialization ; without arguments ;----------------------------------- shell.init: pusha ; Get PID mov eax, 68 mov ebx, 11 int 64 mov eax, 68 mov ebx, 12 mov ecx, 1024 int 64 mov esi, eax mov eax, 9 mov ebx, esi mov ecx, -1 int 64 mov eax, dword [esi + 30] mov [@pid], eax mov eax, 68 mov ebx, 13 mov ecx, esi int 64 ; Convert PID to STR mov eax, [@pid] mov ebx, 10 clear ecx @@: clear edx div ebx push edx inc ecx cmpne eax, 0, @b mov ebx, __shell.name__ @@: pop eax add al, "0" mov [ebx], al inc ebx loop @b ; Add postfix mov [ebx + 0], dword "-SHE" mov [ebx + 4], word "LL" mov [ebx + 6], byte 0 ; Open buffer mov eax, 68 mov ebx, 22 mov ecx, __shell.name__ mov edx, 4096 mov esi, 101b int 64 mov [__shell.buf__], eax mov eax, 5 mov ebx, 5 int 64 popa ret ;----------------------------------- ; Wait answer from shell ; ; INPUT: ; edi - shell-buffer ;----------------------------------- shell.wait: pusha @@: mov eax, 5 mov ebx, 1 int 64 cmpne [edi], byte 0, @b popa ret ;----------------------------------- ; Exit from shell ; without arguments ;----------------------------------- shell.destroy: pusha mov edi, [__shell.buf__] mov [edi], byte 1 call shell.wait mov eax, 68 mov ebx, 23 mov ecx, __shell.name__ int 64 popa ret ;----------------------------------- ; Print char to shell ; ; INPUT: ; al - char ;----------------------------------- shell.print_char: pusha mov edi, [__shell.buf__] mov [edi], byte 2 mov [edi + 1], al call shell.wait popa ret ;----------------------------------- ; Print string to shell ; ; INPUT: ; eax - string ;----------------------------------- shell.print_string: pusha mov edi, [__shell.buf__] mov [edi], byte 3 inc edi @@: mov bl, [eax] mov [edi], bl inc edi inc eax cmpne [eax], byte 0, @b mov [edi], byte 0 mov edi, [__shell.buf__] call shell.wait popa ret ;----------------------------------- ; Print number to shell ; ; INPUT: ; eax - number ;----------------------------------- shell.print_num: pusha mov ecx, eax and ecx, 1 shl 31 cmpe ecx, 0, @f mov [__shell.str__], "-" not eax inc eax @@: mov ebx, 10 clear ecx @@: clear edx div ebx push edx inc ecx cmpne eax, 0, @b mov ebx, __shell.str__ inc ebx @@: pop eax add al, "0" mov [ebx], al inc ebx loop @b mov [ebx], byte 0 mov eax, __shell.str__ cmpe [eax], byte "-", @f inc eax @@: call shell.print_string popa ret ;----------------------------------- ; Get char from shell ; ; OUTPUT: ; al - char ;----------------------------------- shell.get_char: push ebx ecx edx esi edi mov edi, [__shell.buf__] mov [edi], byte 4 call shell.wait mov al, [edi + 1] pop edi esi edx ecx ebx ret ;----------------------------------- ; Get string from shell ; ; INPUT: ; eax - addres of memory for str ;----------------------------------- shell.get_string: pusha mov edi, [__shell.buf__] mov [edi], byte 5 call shell.wait inc edi @@: mov bl, [edi] mov [eax], bl inc eax inc edi cmpne [edi], byte 0, @b mov [eax], byte 0 popa ret ;----------------------------------- ; Get number from shell ; ; OUTPUT: ; eax - number ;----------------------------------- shell.get_num: push ebx ecx edx esi edi mov eax, __shell.str__ call shell.get_string mov ebx, eax clear eax clear edi cmpne [ebx], byte "-", @f mov edi, 1 inc ebx @@: sub [ebx], byte "0" imul eax, 10 add al, [ebx] inc ebx cmpne [ebx], byte 10, @b cmpe edi, 0, @f not eax inc eax @@: pop edi esi edx ecx ebx ret ;----------------------------------- ; Clear shell ; without arguments ;----------------------------------- shell.clear: pusha mov edi, [__shell.buf__] mov [edi], byte 6 call shell.wait popa ret ;----------------------------------- ; Print char to shell ; ; INPUT: ; arg1 - char ;----------------------------------- macro shpc [char] { push eax mov al, char call shell.print_char pop eax } ;----------------------------------- ; Go to new line in shell ; without arguments ;----------------------------------- macro shln { shpc 10 shpc 13 } ;----------------------------------- ; Print string to shell ; ; INPUT: ; arg1 - string ;----------------------------------- macro shps [string] { local ..string, ..label jmp ..label ..string db string, 0 ..label: push eax mov eax, ..string call shell.print_string pop eax } ;----------------------------------- ; Print string to shell ; ; INPUT: ; arg1 - addres of string ;----------------------------------- macro shpsa [addr] { push eax mov eax, addr call shell.print_string pop eax } ;----------------------------------- ; Print number to shell ; ; INPUT: ; arg1 - number ;----------------------------------- macro shpn [num] { push eax mov eax, num call shell.print_num pop eax } ;----------------------------------- ; Get char from shell ; ; OUTPUT: ; al - char ;----------------------------------- macro shgc { call shell.get_char } ;----------------------------------- ; Get string from shell ; ; INPUT: ; arg1 - addres of memory for str ;----------------------------------- macro shgs [addr] { mov eax, addr call shell.get_string } ;----------------------------------- ; Get number from shell ; ; INPUT: ; arg1 - addres of memory for num ;----------------------------------- macro shgn [addr] { push eax call shell.get_num mov [addr], eax pop eax } ;----------------------------------- ; Wait any char from shell ; without arguments ;----------------------------------- macro shw { push eax call shell.get_char pop eax } ;----------------------------------- ; Clear shell ; without arguments ;----------------------------------- macro shc { call shell.clear } ;----------------------------------- ; Choice ; ; INPUT: ; arg1 - question ; arg2 - asnwers ; ; OUTPUT: ; al - answer ;----------------------------------- macro shchs str, chs { local ..loop1, ..loop2, ..chs, ..start, ..res jmp ..start ..chs db chs, 0 ..start: push ebx shps str, " [" shpsa ..chs shps "]: " ..loop1: call shell.get_char mov ebx, ..chs ..loop2: cmpe al, [ebx], ..res inc ebx cmpe [ebx], byte 0, ..loop1 jmp ..loop2 ..res: mov al, [ebx] call shell.print_char shln mov eax, ebx sub eax, ..chs pop ebx }