Консультация № 191932
28.11.2017, 21:02
0.00 руб.
0 4 1
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
Дано задание:
Образовать строку, повторив фрагмент исходной строки с заданной позиции данной длины требуемое кол-во раз.
Выделить нужный фрагмент получается, но с его повторением проблемы. Не могли бы вы помочь разобрать, как лучше это сделать? TASM

Приложение:
.286
.model small
.code
start: mov ax,@data
mov ds,ax
mov es,ax

mov ah,9
mov dx,offset message1 ;вывели сообщ 1
int 21h

lea dx, str1
mov ah, 0ah ;прочли строку
int 21h

mov ah,9
mov dx,offset message2 ;вывели сообщ 2
int 21h

mov ah,1
int 21h
sub al,30h
mov byte ptr a,al ;прочли номер позиции

mov ah,9
mov dx,offset message3 ;вывели сообщ 3
int 21h

mov ah,1
int 21h
sub al,'0' ;число и символ числа отличаются на код '0'
test al,al
jz exit
mov byte ptr b,al ;счетчик на длину нужной подстроки
;lea di,str2+2
lea di,str2 ;указываем на области памяти "куда"
lea si,str1 ;указываем на области памяти "откуда"
add si,a
add si,2
mov cx,b
rep movsb ;пересылаем данные

mov ah,9
mov dx,offset message4 ;вывели сообщ 4
int 21h

mov ah,9
mov dx,offset str2 ;вывели ответ str2
int 21h

mov ah,0
int 16h
exit:
mov ah,4Ch
int 21h
.data
a dw 0 ;номер позиции
b dw 0 ;длина подстроки
str1 db 255 dup ('$')
message1 db 10,13,"Enter your string $"
message2 db 10,13,"Enter number of pozition $"
message3 db 10,13,"Enter length substring $"
message4 db 10,13,"Answer $"
str2 db 255 dup('$')
end start

Обсуждение

давно
Посетитель
7438
7205
29.11.2017, 14:25
общий
Адресаты:
Здравствуйте!
В целом неплохо
Но все же хочу высказать несколько замечаний по уже написанному коду
1) Вы знакомы с форматом параметра функции ah=0ah, передаваемым по адресу DS:DX ?
Задание его, как строки str1 db 255 dup ('$') немного некорректно. Вы чисто случайно задали максимальную длину строки 36 = 24h = '$'
2) Почему Вы ограничиваете вводимые числа только одноциферными? Впрочем, если это допустимо, то не вопрос...
3) Не проверяете переход выбираемой подстроки (и начало, и с учетом длины) за пределы строки. Вот это уже ошибка.
4) Чтобы вывести строку при помощи функции ah=9, необходимо в конце строки записать символ '$', тоже ошибка.

Чтобы сделать задачу полностью, осталось совсем немного:
1) Ввести количество повторов (проверить на 0)
2) Произвести копирование подстроки указанное число раз. При этом адрес куда (di) формируем только раз, в начале.
Адрес откуда (si) в начале каждого копирования подстроки. Циклим по переменой с количеством раз, отнимаем 1 и проверяем на 0

Пробуйте... Уверен, у Вас все получится! Если нет, давайте сюда свою исправленную программу, посмотрим, подправим...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401535
1
29.11.2017, 14:50
общий
Адресаты:
Спасибо за комментарии, попробую разобраться
давно
Старший Модератор
31795
6196
29.11.2017, 20:18
общий
это ответ
Здравствуйте, ann.zinger2010!

Смотрите код:
[code lang=asm h=300]model small
.data
szStr equ 250
dbStrng db 10,13,'Enter string:$'
dbPstn db 10,13,'Enter position:$'
dbLngth db 10,13,'Enter length:$'
dbCnt db 10,13,'Enter count:$'
dbRes db 10,13,'Result:$'

dbMax db szStr
dbLen db ?
dbStr db 2*szStr dup(?)

dwNum1 dw ?;
dwNum2 dw ?;
dwNum3 dw ?;
.stack 100h
.code
;адресуем сегментные регистры
begin: mov ax,@data
mov ds,ax
mov es,ax
;просим ввести строку
Str1: mov ah,9
lea dx,dbStrng
int 21h
;вводим
mov ah,10
lea dx,dbMax
int 21h
;контроль пустой строки
mov al,dbLen
or al,al
jz Str1
;просим ввести позицию
Num1: lea dx,dbPstn
call InpNum
dec ax
;контролируем позицию и длину строки
cmp al,dbLen
jae Num1;больше повторяем
mov dwNum1,ax
;просим ввести длину копируемого участка
Num2: lea dx,dbLngth
call InpNUm
;контролируем длину копирования и длину строки
mov bl,dbLen
add bl,al
cmp bl,dbLen
jb Num2;больше переходим
mov dwNum2,ax
;просим ввести количество копий
Num3: lea dx,dbCnt
call InpNUm
mov dwNum3,ax
;готовим строку для вывода
lea si,dbStr
mov dl,dbLen
xor dh,dh
add si,dx
mov byte ptr[si],'$'
;готовимся к перерносу кода
mov bx,dwNum2
mul bl
mov di,ax;=количество копий * длина копирования
add di,si
dec di
xor ch,ch
mov cl,dbLen
add si,dwNum1
sub cx,dwNum1
;перносим
std
rep movsb
;готовимся копировать код
mov cx,dwNum3
lea si,dbStr
mov ax,dwNum2
add si,dwNum1
mov di,si
cld
;копируем
Copy1: push si
push cx
mov cx,ax
rep movsb
pop cx
pop si
loop Copy1
;выодим результат
mov ah,9
lea dx,dbRes
int 21h
mov ah,9
lea dx,dbStr
int 21h
;выход
mov ax,4C00h
int 21h
;вводим одну цифру
InpNum: mov ah,9
int 21h
mov ah,1
int 21h
;не цифра повторяем ввод
cmp al,'1'
jb InpNum
cmp al,'9'
ja InpNum
and ax,0Fh
ret
end begin[/code]
Удачи!
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
29.11.2017, 20:19
общий
Адресаты:
Попробуйте сами написать, потом сравните.
Удачи!
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа