getinput: вызов функции через invoke, добавил секцию с указателями на функции
parent
23a93da088
commit
fd1b036929
|
@ -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', \
|
||||
|
|
Loading…
Reference in New Issue