diff --git a/getinput/echo.asm b/getinput/echo.asm index 7ad1131..3a28695 100644 --- a/getinput/echo.asm +++ b/getinput/echo.asm @@ -3,62 +3,6 @@ format PE console entry start include '%FASMINC%\WIN32A.INC' - -section '.code' code readable executable -start: - invoke printf, usage - invoke printf, req - call get_string_stdin - invoke printf, resp, eax - pop ebx - pop eax - invoke free, eax - invoke getch - invoke ExitProcess, 0 - -; Функция, считывающая строку любой длины из консоли -get_string_stdin: - push ebp ; указатель на начало стека в ebp - mov ebp, esp ; новый epb - esp - invoke malloc, 2 ; аллоцирую изначально 2 байта под символ и нуль-терминатор - pop ebx ; двойку убираю со стека - mov ebx, eax ; адрес строки будет в ebx - push 2 ; емкость - push 0 ; длина строки -.next_char: - pop eax ; длина - pop ecx ; емкость - inc eax ; увеличиваю длину на 1 - cmp eax, ecx ; если длина = емкость - je .realloc_memory ; реаллоцирую память - push ecx ; новая емксоть в стек - push eax ; новая длина в стек - jmp .continue ; иначе продолжаю программу -.realloc_memory: - shl ecx, 1 ; удваиваю емкость - push ecx ; новая емксоть в стек - push eax ; новая длина в стек - invoke realloc, ebx, ecx - pop ebx - pop ecx - mov ebx, eax ; в ebx новый адрес данных -.continue: - invoke getche ; считываю символ с клавиатуры - cmp al, 13 - je .exit ; Если Enter, завершаем ввод - mov edx, eax ; символ из eax в edx - pop eax ; берем новую длину - mov [ebx + eax - 1], dl ; сохраняю считанный символ в выделенной памяти - mov byte [ebx + eax], 0 ; добавляю нуль-терминатор - push eax - jmp .next_char ; след итерация -.exit: - mov eax, ebx ; ответ в eax - mov esp, ebp ; восстанавлиает указатель указатель на вершину стека вызывающей функции - pop ebp ; восстанавливает указатель на начало стека вызывающей функции - ret ; возвращение управления - - section '.data' data readable writeable usage db \ 'This is a test echo program written in FASM,', \ @@ -67,6 +11,66 @@ section '.data' data readable writeable req db 'TEXT: ', 0 resp db 10, 'ECHO: %s', 10, 'Press any button to exit: ', 0 +section '.funcs' data readable writeable + ; считывание пользовательской строки любого размера из stdin + get_string_stdin dd _get_string_stdin + +section '.code' code readable executable +start: + invoke printf, usage + invoke printf, req + invoke get_string_stdin + invoke printf, resp, eax + pop ebx + pop eax + invoke free, eax + invoke getch + invoke ExitProcess, 0 + +; Функция, считывающая строку любой длины из консоли +proc _get_string_stdin + .start: + push ebp ; указатель на начало стека в ebp + mov ebp, esp ; новый epb - esp + invoke malloc, 2 ; аллоцирую изначально 2 байта под символ и нуль-терминатор + pop ebx ; двойку убираю со стека + mov ebx, eax ; адрес строки будет в ebx + push 2 ; емкость + push 0 ; длина строки + .next_char: + pop eax ; длина + pop ecx ; емкость + inc eax ; увеличиваю длину на 1 + cmp eax, ecx ; если длина = емкость + je .realloc_memory ; реаллоцирую память + push ecx ; новая емксоть в стек + push eax ; новая длина в стек + jmp .continue ; иначе продолжаю программу + .realloc_memory: + shl ecx, 1 ; удваиваю емкость + push ecx ; новая емксоть в стек + push eax ; новая длина в стек + invoke realloc, ebx, ecx + pop ebx + pop ecx + mov ebx, eax ; в ebx новый адрес данных + .continue: + invoke getche ; считываю символ с клавиатуры + cmp al, 13 + je .end ; Если Enter, завершаем ввод + mov edx, eax ; символ из eax в edx + pop eax ; берем новую длину + mov [ebx + eax - 1], dl ; сохраняю считанный символ в выделенной памяти + mov byte [ebx + eax], 0 ; добавляю нуль-терминатор + push eax + jmp .next_char ; след итерация + .end: + mov eax, ebx ; ответ в eax + mov esp, ebp ; восстанавлиает указатель указатель на вершину стека вызывающей функции + pop ebp ; восстанавливает указатель на начало стека вызывающей функции + ret ; возвращение управления +endp + section '.idata' import data readable library \ msvcrt, 'msvcrt.dll', \