; Выведет строку, которую ты ввел, память под строку выделяется динамически на куче format PE console entry start include '%FASMINC%\WIN32A.INC' section '.data' data readable writeable usage db \ 'This is a test echo program written in FASM,', \ ' outputting to you the string you entered.', 10, \ 'Works with strings of any length!', 10, 10, 0 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 ; dt - 4 байта - размер адреса 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', \ kernel32, 'kernel32.dll' import msvcrt, \ malloc, 'malloc', \ realloc, 'realloc', \ free, 'free', \ printf, 'printf', \ getche, '_getche', \ getch, '_getch' import kernel32, \ ExitProcess, 'ExitProcess'