Консультация № 191922
28.11.2017, 15:24
0.00 руб.
0 8 2
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: В исходную строку вставить после заданного символа все символы предшествующие ему. Оставшуюся часть оставить без изменения. Платформа ДОС. На TASM, модель памяти SMALL. Заранее спасибо)

Обсуждение

давно
Посетитель
7438
7205
28.11.2017, 15:36
общий
Адресаты:
Здравствуйте, Алина!
Вы что-то пытались написать? Даже, если неправильно, покажите нам.
Хотя бы для того, чтобы увидеть, как у вас принято писать код.
А мы подправим, добавим...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401532
3
28.11.2017, 16:44
общий
28.11.2017, 16:53
Вот, пока все что есть (

[code lang=asm].model small
.stack 100h

.code
.data
MaxLen equ 79
Prompt1 db 'stroka: ',13,10,36
Prompt2 db 13,10,'char: ',36
Result db 13,10,'vstrecha $'
ResUnit db ' raz. $'
Buffer db MaxLen + 1
LenStr db ?
String db MaxLen + 1 dup (?)
main proc
mov AX,@data ;настройка сегментных
mov DS,AX ;регистров на
mov ES,AX ;сегмент данных
mov ah,9
lea dx,Prompt1 ;загружаем адрес строки
int 21h
inc ah
lea dx,Buffer ;загружаем адрес строки
int 21h
dec ah
lea dx,Prompt2
int 21h
mov ah,1
int 21h
mov cl,LenStr ;адрес
xor ch,ch ;
mov bl,ch
lea di,String ;кладем в Di адрес строки(index)
FindLoop:
jne Output
inc bl ;счетчик строки
jmp FindLoop
Output:
mov al,bl
mov bh,10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
endp main
end main[/code]
давно
Старший Модератор
31795
6196
28.11.2017, 16:54
общий
Адресаты:

Ну это практически ничего.
Тема у Вас какая? Строковые команды?
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
7438
7205
28.11.2017, 16:54
общий
Адресаты:
Уже неплохо
Лады, сегодня чуть позже посмотрю. Если кто-нибудь не опередит
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401532
3
28.11.2017, 17:08
общий
Адресаты:

Тема: Команды передачи управления
Спасибо большоое)
давно
Посетитель
7438
7205
28.11.2017, 19:00
общий
это ответ
Здравствуйте, varinkovaalina!
Держите код.
Будут вопросы - обращайтесь в мини-форум
[code lang=asm h=200];В исходную строку вставить после заданного символа все символы предшествующие ему.
;Оставшуюся часть оставить без изменения

.model small
.stack 100h

.data
MaxLen equ 79
Prompt1 db 'stroka: ',13,10,36
Prompt2 db 13,10,'char: ',36
Result db 13,10,'result: $'
sNotFound db 13,10,'Symbol not found$'
Buffer db MaxLen + 1
LenStr db ?
String db MaxLen + 1 dup (?)

.code
main proc
mov AX,@data ;настройка сегментных
mov DS,AX ;регистров на
mov ES,AX ;сегмент данных
mov ah,9
lea dx,Prompt1 ;загружаем адрес строки
int 21h
inc ah ;ah=0ah
lea dx,Buffer ;загружаем адрес строки
int 21h
dec ah ;ah=9
lea dx,Prompt2
int 21h
mov ah,1
int 21h
mov dl,al ;введенный символ

mov cl,LenStr ;длина введенной строки
xor ch,ch
mov bx,cx ;сохраним длину строки
lea di,String ;кладем в Di адрес строки(index)
lea si,[bx+di-1] ;адрес последнего символа в строке
FindLoop: ;цикл поиска символа dl в строке
mov al, [di] ;очередной символ
inc di ;инкремент адреса
cmp al,dl ;сравниваем
je Found ;если равно, то нашли
loop FindLoop ;циклим столько, чему равна длина строки
jmp NotFound ;прошли всю строку и не нашли

Found: ;символ найден
;скопируем символы строки за найденным, сместив их на количество символов перед найденным
;тем самым освободив место, чтобы скопировать символы перед сразу за найденным
dec cx ;количество символов за найденным
sub bx, cx ;количество до и сам символ
mov byte ptr [bx+si], '$' ;bx+si - адрес за последним символом новой строки. Закроем строку для вывода
cmp bx, 1 ;если найден первый символ
je PrintResult ; то вставлять нечего! Сразу на вывод результата!

jcxz CopyHead ;если найден последний символ, то на копирование передних за найденным

CopyTailLoop: ;собственно, копируем символы строки за найденным в конец новой строки
;освобождая тем самым место для передних символов
mov al,[si] ;идем с хвоста старой строки
dec si ;смещаемся к началу
mov [bx+si],al ;bx+si адрес хвоста новой строки
loop CopyTailLoop ;по всем символам за найденным

CopyHead: ;копируем символы перед найденным сразу за ним в освободившееся место
mov cx, bx ;количество до найденного плюс сам символ
dec cx ;исключим сам символ в количестве копируемых
;продолжаем копировать с хвоста
CopyHeadLoop:
dec si ;начинаем с уменьшения адреса, чтобы обойти сам символ
mov al,[si] ;читаем очередной
mov [bx+si],al ;и копируем на новое место
loop CopyHeadLoop ;по всем символам спереди найденного

PrintResult: ;вывод результата
lea dx,Result
mov ah,9
int 21h

lea dx,String ;новая строка
print: ;вывод, в том числе и сообщения о том, что символ не найден
mov ah,9
int 21h

xor ax,ax ;ждем нажатия на клавишу
int 16h

mov ax, 4c00h
int 21h

NotFound:
lea dx, sNotFound
jmp print
endp main
end main[/code]
5
Спасибо, Вам, огромное! Все работает!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
28.11.2017, 19:05
общий
Адресаты:
Нарисовал Вам программку
Отрабатываются все возможные случаи: найден первый символ, последний, в середине, не найден вообще...
Настоятельно рекомендую прошагать в отладчике...
Некоторые моменты достаточно неочевидны. Но тут уж придется напрячь голову
Если все равно что-то не будет понятно, спрашивайте...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Старший Модератор
31795
6196
28.11.2017, 19:45
общий
это ответ
Здравствуйте, varinkovaalina!

Строковые команды.

Добавлен ещё один случай, пользователь ввел пустую строку.
[code lang=asm h=250]model small
szStr equ 250
.data
dbInpStr db 10,13,'Enter string:$'
dbInpSim db 10,13,'Enter simbol:$'
dbRes db 10,13,'Result:$'
dbErr db 10,13,'String not found$'
dbNot db 10,13,'Simbol not found$'
dbMax db szStr
dblen db ?
dbStr db 2*szStr dup(?)
.stack 256
.code
;настариваем сегментные регистры
begin: mov ax,@data
mov ds,ax
mov es,ax
;просим ввести строку
mov ah,9
lea dx,dbInpStr
int 21h
;вводим
mov ah,10
lea dx,dbMax
int 21h
;просим ввести символ
mov ah,9
lea dx,dbInpSim
int 21h
;вводим
mov ah,1
int 21h
;читаем длину введенной строки
xor ch,ch
mov cl,dbLen
lea si,dbStr
mov bx,cx
;для функции вывода строки
mov byte ptr [bx+si],'$'
;пустая стока
lea dx,dbErr
jcxz outStr
;начнем работу со строковыми командами
mov di,si
cld
repne scasb
;нет символа в строке
lea dx,dbNot
or cx,cx
jz outStr
;начинаем копирование
mov dx,si
push di
push cx
add si,bx;в конец строки
mov di,si
add di,bx;освобождаем свободное место
dec di;адресация с нуля - коррекция
sub di,cx
inc cx;кооректируем адресацию с нуля
;копируем строку
std
rep movsb;
;востанавливаем параметры поиска
pop cx
pop si
dec si;корректируем от куда копируем
sub bx,cx;считаем количество копируемых символов
mov cx,bx
;копируем начальнуе символы
rep movsb
;выводим результат
outStr: push dx
mov ah,9
lea dx,dbRes
int 21h
mov ah,9
pop dx
int 21h
xor ax,ax
int 16h
mov ax,4C00h
int 21h
end begin[/code]
Удачи!
5
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа