Идею предложить не могу, все мысли отходят к си++
необходимо ввести дескриптор на клавиатуру
tasm name
tlink name /t
.model tiny
.code
.startup
mov bx, 1 ;выведем сообщение через стандартное выходное устройство - монитор
lea dx, prompt
mov cx, len_prt
mov ah, 40h
int 21h
xor bx, bx ;строку считываем через стандартное входное устройство - клавиатуру
lea dx, string
mov cx, 256 ;длину взял побольше, чтобы наверняка хватило :)
mov ah, 3fh
int 21h
lea si, string ;адрес строки
mov bx, ax ;длина принятой строки
sub bx, 2 ;последние 0dh, 0ah нам не нужны
push bx ;сохраним длину строки для вывода на экран
start_sep: ;старт с позиции разделителя
mov dl, 0 ;dl=0: предыдущее состояние - разделитель
main_loop: ;цикл считывания очередного символа
lodsb ;читаем, si автоматом инкрементируется
cmp al, 0dh ;проверим на конец строки
je finish ;прошли до конца
call separator ;проверим код на разделитель
jz sep_cmp_step ;FZ=1 - встретился разделитель
cmp dl, 0 ;не разделитель, проверяем предыдущее состояние
jne main_loop ;не разделитель - на чтение следующего символа
lea bx, [si+1] ;разделитель - начинается новое слово, запоминаем позицию
; на 2 больше начала слова! (для чего - см дальше)
mov dl, 1 ;и помечаем состояние слова
jmp main_loop ;на ввод следующего символа
sep_cmp_step: ;встретили разделитель
cmp dl, 0 ;если были в позиции разделителя,
je main_loop ; то на ввод следующего символа
call rotate ;были в позиии слова - значит оно закончилось
; при этом si указывает на символ за первым разделителем за словом
; т.к. адрес последнего символа слова = [si-2],
; отсюда и начало слова по адресу [bx-2]
jmp start_sep ;опять начинаем с позиции разделителя
finish: ;дошли до конца
call rotate ;последнее слово надо тоже перевернуть
mov bx, 1 ;выводим заголовок строки
lea dx, result
mov cx, len_res
mov ah, 40h
int 21h
pop cx ;сохраненная длина введеной строки
mov bx, 1 ;выведем преобразованную строку
lea dx, string
mov ah, 40h
int 21h
mov bx, 1 ;сообщение "Press any key"
lea dx, press_any
mov cx, len_press
mov ah, 40h
int 21h
mov ah, 8 ;ждем "any key" :)
int 21h
.exit 0 ;выход
;проверка на разделители
;результат: FZ=1 - код в al - разделитель
separator proc
lea di, sep_string ;строка кодов разделителей
mov cx, len_sep_string ;длина
repne scasb ;ищем
ret
separator endp
;переворот слова
;[bx-2] - адрес первого символа слова
;[si-2] - адрес последнего
rotate proc
push si ;сохраним для продолжения анализа
rotate_loop:
cmp bx, si ;адреса "встретились"?
jae rotate_ret ;да, выходим
mov al, [bx-2] ;меняем местами
xchg al, [si-2]
mov [bx-2], al
inc bx ;"голову" вперед
dec si ;"хвост" назад
jmp rotate_loop ;на повтор
rotate_ret:
pop si ;восстановим адрес конца
lea bx, [si] ;необходимо для случая, когда строка заканчивается разделителями
ret
rotate endp
;данные
.data
press_any db 0dh,0ah,'Press any key for exit'
len_press equ $-press_any
;все возможные разделители
sep_string db 9,' ,.:;?!-+=\/()[]{}'
len_sep_string equ $-sep_string
prompt db 'Enter string: '
len_prt equ $-prompt
result db 'Result: '
len_res equ $-result
;зарезервируем буфер для вводимой строки в неинициализируемом сегменте,
; чтобы не занимать место в результируещем EXE-файле
.data?
string db 256 dup (?)
end
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.