Вопрос № 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