Консультация № 180367
19.10.2010, 08:22
0.00 руб.
0 4 1
Здравствуй эксперты, возник вопрос по заданию.
Основное: х86(специальных функций не нужно), платформа доса, Тасм, размер переменных вот тут с проблемой.
для работы с программой необходимо ввести дескриптор на клавиатуру.
задание вот как звучит: " Необходимо реализовать программу работы со строками. Исходная строка вводится с клавиатуры, результат выводится на экран. Слова в строке могут быть разделены пробелами и знаками препинания.В каждом слове строки заменить 1-ую букву на последнюю, 2-ую на предпоследнюю и т.д. "
Идею предложить не могу, все мысли отходят к си++.

Обсуждение

давно
Посетитель
7438
7205
19.10.2010, 08:35
общий
Мельников:
Идею предложить не могу, все мысли отходят к си++
Ну и прекрасно Да хоть на каком. Мы все принимаем
Скажите, как Вы понимаете. Это очень важно! И скажите, что Вы понимаете под
необходимо ввести дескриптор на клавиатуру
Можно понимать, например, как явное чтение из стандартной консоли, используя handle устройства stdin...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.10.2010, 10:16
общий
дескриптором кл. я понимаю. = mov bx,0 ;дескриптор клавиатуры
Идея была такая, что
мы вводим строчку со знаками итд, дальше заносим одно из слов в дополнительный буфер и начинаем работать с этим словом.
То есть например дали нам слово people. заносим 1 символ в bx и идем дальше до конца встречаем e заносим в ax и меняем местами.
возвращая eeoplp. идея больше на бред катит.
давно
Посетитель
7438
7205
19.10.2010, 10:36
общий
Мельников:
Ну почему же Бред не бред, а, по крайней мере, показывает, что Вы пытались понять поставленную задачу,
а это уже немало Ок, сейчас "наваяю" Вам программку
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
19.10.2010, 15:34
общий
это ответ
Здравствуйте, Мельников!
Вот Вам программа под Tasm, расчитана под формат COM
Т.е. компилируем так:
Код:
tasm name
tlink name /t
Удачи в освоении языка Ассемблера!
PS Все операции ввода-вывода сделал через работу с устройствами stdin, stdout

Код:

.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
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа