Вопрос № 111074: Здравствуйте. Мне нужно написать программу, которая бы инверсировала данную строку. За основу взял следующий код
...
MOV AX,@DATA
MOV DS,AX
MOV ES,AX
CLD
LEA SI,SOURCE
LEA DI,DEST
MOV CX,20
REP MOVS DEST,SO...
Вопрос № 111.074
Здравствуйте. Мне нужно написать программу, которая бы инверсировала данную строку. За основу взял следующий код
...
MOV AX,@DATA
MOV DS,AX
MOV ES,AX
CLD
LEA SI,SOURCE
LEA DI,DEST
MOV CX,20
REP MOVS DEST,SOURCE
...
Здесь флаг df=0 и строка проходится справа налево, т.е. в итоге получаю ту же строку. Если же df=1, вроде бы обход должен идти справа налево, но в результате получаю не понятно что... Подскажите как правильно написать данную програмку.
Отправлен: 26.11.2007, 16:38
Вопрос задал: Petrovich (статус: Посетитель)
Всего ответов: 4 Мини-форум вопроса >>> (сообщений: 5)
Отвечает: Лысков Игорь Витальевич
Здравствуйте, Petrovich! Только "ручками": MOV AX,@DATA MOV DS,AX MOV ES,AX LEA SI,SOURCE LEA DI,DEST+19 ;адрес последнего байта результата MOV CX,20 reverse_loop: mov al,[si] mov [di],al inc si ;адрес источника идет вперед dec di ;адрес результата - назад loop reverse_loop
--------- Удачи!
Ответ отправил: Лысков Игорь Витальевич (статус: Практикант)
Ответ отправлен: 26.11.2007, 17:29 Оценка за ответ: 4
Отвечает: Зенченко Константин Николаевич
Здравствуйте, Petrovich!
Флаг df влияет на направление увеличения(уменьшения) регистров SI и DI одновременно.
Вам нужно строку:
REP MOVSB;W,D DEST,SOURCE
заменить на:
CopyLoop:
;если флаг df=0
;I)
lodsb
mov [di],al
dec di
;если флаг df=1
;II)
mov al,[si]
inc si
stosb
;с изменением флага
;III)
cld
lodsb
std
stosb
;для всех вариантов
loop CopyLoop
Удачи!
--------- И только наступив на грабли мы приобретаем драгоценный опыт!
Ответ отправил: Зенченко Константин Николаевич (статус: Специалист)
Ответ отправлен: 26.11.2007, 17:40 Оценка за ответ: 4
Отвечает: Овчинников Алексей
Здравствуйте, Petrovich!
Правильно написано что нужно ручками.
Но учтите что регистор источника вы должны сместить на 20 байт
вниз, чтобы начинать читать текст в обратную сторону
с конца. А не сначала.
тоесть после получения адреса начала строки LEA SI,SOURCE
вы должны добавить ADD SI,20.
Префикс REP , и команда MOVS здесь в данном случае не подходят.
необходимо заменить циклом
push ax
CI1:
mov al,[si]
mov [di],al
dec si
inc di
loop CI1
кроме того даже в этом случае ваш результат
вы вряд-ли увидите на экране
потому-что символ конца строки '$' у вас получится
в самом начале выводимой строки, т.е строка просто не выведется.
Ответ отправил: Овчинников Алексей (статус: 2-ой класс)
Ответ отправлен: 27.11.2007, 00:28 Оценка за ответ: 4
Отвечает: an42
Здравствуйте, Petrovich!
Предлагаю такой способ решения:
Длину введенной строки делим на 2
Результат частного (остаток не играет роли) будет числом шагов в инверсии строки
1-й этап: определяем адрес начало и конца строки
2-й этап: меняем местами крайний левый символ с крайним правым символом (это 1-й шаг в инверсии строки)
3-й этап: увеличиваем адрес слева на 1 и умешаем адрес с права на 1, и обмениваем эти символы строки между собой (это следующий шаг в инверсии строки)
Обмен местами нужно проводит столько раз, сколько мы получили в частном при делении длины введенной строки на два.
В приложении пояснения
Удачи
Приложение:
Ответ отправил: an42 (статус: 6-ой класс)
Ответ отправлен: 28.11.2007, 17:27
Отправить вопрос экспертам этой рассылки
Приложение (если необходимо):
* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.
Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!
Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.
Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.