IPB
ЛогинПароль:

> ПРАВИЛА РАЗДЕЛА!!!

1. Заголовок или название темы должно быть информативным
2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE]
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора.
5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM!
6. Проверяйте программы перед тем, как выложить их на форум!!

> Обработка символьной информации, с помощью функций DOS
сообщение
Сообщение #1


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Вот задание: Ввести с клавиатуры две строки. Сравнить их. Вывести на экран какая из строк больше и насколько. Какие мысли есть по реализации данной программы? Как осуществить сравнение строк?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


Гость






Цитата
А вот как организовать подпрограмму поиска одной введённой строки в другой строке? И ещё: вывод позиции, с которой подстрока содержится в строке...
Вот тебе программа, которая это делает... В виде подпрограммы оформляй сам:

MODEL small

stack 100
.286

DATASEG
entrStr db 13, 10, 'string:$'
entrSStr db 13, 10, 'substring:$'
sNotFound db 13, 10, 'substring was not found$'
sResult db 13, 10, 'pos = $'

inpStr db 200
inpStrLen db ?
inpStrDat db 200 dup(?)

inpSStr db 200
inpSStrLen db ?
inpSStrDat db 200 dup(?)

count_of_digits dw 6

CODESEG

writeDEC proc

; ...

writeDEC endp

show_ax proc
mov cx, 10
xor di, di
@@conv:
xor dx, dx
div cx
add dl, '0'
inc di
push dx ; складываем в стэк
or ax, ax
jnz @@conv
; выводим из стэка на экран
@@show:
pop dx ; dl = очередной символ
mov ah, 2 ; ah - функция вывода символа на экран
int 21h
dec di ; повторяем пока di<>0
jnz @@show
ret
show_ax endp

start:
mov ax,@DATA
mov ds, ax
mov es, ax

; вводим строку
mov ah, 09h
mov dx, offset entrStr
int 21h
mov ah, 0ah
mov dx, offset inpStr
int 21h

; записываем '$' в конец строки
mov di, offset inpStrDat
xor ch, ch
mov cl, inpStrLen
add di, cx
mov byte ptr[di], '$'

; вводим подстроку
mov ah, 09h
mov dx, offset entrSStr
int 21h
mov ah, 0ah
mov dx, offset inpSStr
int 21h

; Подготовка
xor cx, cx
mov di, offset inpStrDat
mov si, offset inpSStrDat
mov cl, inpStrLen

; Ищем первый символ подстроки
FindFirstCh:
mov al, [di] ;
inc di
cmp al, [si]
jz beginCompare ; Нашли

nextCompare:
loop FindFirstCh

; Если цикл FindFirstCh закончился - значит подстроки нет
mov ah, 09h
mov dx, offset sNotFound
int 21h
jmp exit_prog

beginCompare:
; Проверяем следующие за первым в подстроке символы
push cx
push si
push di
dec di
mov cl, inpSStrLen

; Проверка
yesCompare:
mov al, [di]
inc di
cmp al, [si]
jnz noCompare ; Очередной символ не совпал
inc si
loop yesCompare

; Если здесь - значит все совпало
jmp found

; Не совпало - восстанавливаем данные и ищем дальше
; первый символ подстроки в строке
noCompare:
pop di
pop si
pop cx
jmp short nextCompare

found:
; Есть совпадение, выводим сообщение
mov ah, 09h
mov dx, offset sResult
int 21h

; вытягиваем из стека адрес первого символа
pop di

; и вычисляем его позицию
mov dx, offset inpStrDat
mov ax, di
sub ax, dx
call writeDEC ; Эту процедуру я показывал раньше

exit_prog:
mov ah, 4ch
int 21h
end start

(процедуру writeDEC возьми из предыдущих постов, я не стал ее опять копировать...)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Цитата(volvo @ 7.12.2008 12:24) *
Вот тебе программа, которая это делает...

У меня возник ряд вопросов по реализации...
1) Использование "offset". Я так полагаю, что это полный аналог команды "lea" ?
2) inpStrDat что это за переменная, для чего она нужна?
3)
mov di, offset inpStrDat
что делает конструкция такого вида?
4) Как определяется размер строки? т.е.
mov cl, inpStrLen
почему в cl сразу помещается размер строки?
5) При переходе на метку
beginCompare:
, где мы должны проверять последующие за первой буквы, мы снова проверяем совпадение первых букв, так ли это?
6) Когда мы из стека вытаскиваем di, разве он сразу не указывает на позицию, с которой начинается подстрока в строке? Как вообще происходит тогда вычисление позиции?

Сообщение отредактировано: volvo -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Цитата(Rocket @ 8.12.2008 23:36) *
1) Использование "offset". Я так полагаю, что это полный аналог команды "lea" ?
Правильно полагаешь...

; можно вот так получить смещение inpStrDat
; в сегменте данных
mov di, offset inpStrDat

; а можно - вот так:
lea di, inpStrDat
В обоих случаях смещение этого массива от начала сегмента будет занесено в регистр DI...

Цитата(Rocket @ 8.12.2008 23:36) *
2) inpStrDat что это за переменная, для чего она нужна?
Как это "для чего"? А строку ты что, в воздухе хранить будешь? Вообще-то для нее надо место выделять. Вот я и выделил 200 байт.

Вообще обрати внимание, для ввода строки используется функция 0AH прерывания 21H... А она требует для работы вот чего:
Цитата(Абель)
LABEL представляет собой директиву с атрибутом BYTE. Первый байт содержит максимальную длину вводимых данных. Так как это однобайтовое поле, то возможное максимальное значение его - FFh или 255. Второй байт необходим DOS для занесения в него действительного числа введенных символов. Третьим байтом начинается поле, которое будет содержать введенные символы.
 	NAMEPAR	LABEL BYTE	; Список параметров:
MAXLEN DB 20 ; Максимальная длина
ACTLEN DB ? ; Реальная длина
NAMEFLD DB 20 DUP (' ') ; Введенные символы

Так как в списке параметров директива LABEL не занимает места, то NAMEPAR и MAXLEN указывают на один и тот же aдрес памяти. В трансляторе MASM для определения списка параметров в виде структуры может использоваться также директива STRUC. Однако, в связи с тем, что ссылки на имена, определенные внутри, требуют специальной адресации, воздержимся cейчас от рассмотрения данной темы до гл. 24 "Директивы ассемблера".
Для запроса на ввод необходимо поместить в регистр AH номер функции - 10 (шест. 0Ah), загрузить адрес списка параметров (NAMEPAR в нашем примере) в регистр DX и выполнить INT 21H
Вот так... А поскольку я не описывал LABEL (ленивый я, не люблю набирать лишние символы smile.gif ), то в DX загружал смещение inpStr, то есть, первого из необходимых параметров...

Я надеюсь, вопрос
Цитата(Rocket @ 8.12.2008 23:36) *
4) Как определяется размер строки? т.е.
mov cl, inpStrLen
почему в cl сразу помещается размер строки?
исчерпан? Я там, в цитате, выделил ответ на него...

Цитата(Rocket @ 8.12.2008 23:36) *
5) При переходе на метку
beginCompare:
, где мы должны проверять последующие за первой буквы, мы снова проверяем совпадение первых букв, так ли это?
Так, но почему тебя это пугает? Я же уменьшаю DI перед проверкой, то есть, DI указывает именно на первый, совпавший символ в строке...

Цитата(Rocket @ 8.12.2008 23:36) *
6) Когда мы из стека вытаскиваем di, разве он сразу не указывает на позицию, с которой начинается подстрока в строке? Как вообще происходит тогда вычисление позиции?
Нет, он указывает на смещение относительно начала сегмента... А для того, чтобы вычислить позицию, надо из этого самого смещения, которое хранится в DI, вычесть смещение первого символа строки, которое я и заношу в DX... После вычитания в AX имеем позицию подстроки в строке...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Всё стало на свои места! Спасибоsmile.gif
Так, вот ещё несколько вопросов вопросов :
1) процедура show_ax для чего предназначена? мы вроде её не используем нигде...
2) Зачем записывать $ конец введённой строки? Я знаю, что это признак конца строки...
3) Как это в виде процедуры оформить? Я полагаю, что после ввода строки и подстроки и после соответствующих подготовок. Нужно что-нибудь передавать в процедуру или прятать в стек?

Сообщение отредактировано: volvo -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Цитата(Rocket @ 9.12.2008 23:24) *
1) процедура show_ax для чего предназначена? мы вроде её не используем нигде...
Это я забыл удалить, она не нужна тут...

Цитата(Rocket @ 9.12.2008 23:24) *
2) Зачем записывать $ конец введённой строки? Я знаю, что это признак конца строки...
Ну, раз знаешь - чего спрашиваешь? smile.gif Допустим, ты ввел 20 символов, места выделено под 200, и тебе понадобилось распечатать введенную строку. Что делать будешь? Правило хорошего тона требует заполнить строку как положено (если этого не делает функция DOS - то это должен сделать программист, чтоб потом не отлавливать глюки). Раз строка должна заканчиваться символом "$", значит его надо добавить...

Цитата(Rocket @ 9.12.2008 23:24) *
3) Как это в виде процедуры оформить? Я полагаю, что после ввода строки и подстроки и после соответствующих подготовок. Нужно что-нибудь передавать в процедуру или прятать в стек?
Да, скорее всего надо в процедуре получать через DI адрес строки, через SI - адрес подстроки, и через CX - длину строки... А возвращать значение она должна через AX, как обычно, если AX = 0, то совпадений нет, иначе в AX содержится индекс первого элемента строки... Сохранять надо все регистры, которые изменяются внутри процедуры, опять же правило хорошего тона: не делай сам себе проблем, после возврата из процедуры содержимое регистров (кроме тех, через которые возвращаются результаты) должно быть точно таким же, как и до ее вызова...
 К началу страницы 
+ Ответить 

Сообщений в этой теме
Rocket   Обработка символьной информации   5.10.2008 4:11
мисс_граффити   Что значит "строка больше"? По длине?   6.10.2008 23:22
Rocket   Что значит "строка больше"? По длине? …   7.10.2008 0:28
Lapp   Та по длине походу... сравнивать количество символ…   7.10.2008 3:02
Rocket   При чем тут загадка? Не понимаю. Если по длине,…   7.10.2008 3:23
Lapp   В ассемблере есть функция length(s)?...в мои позн…   7.10.2008 3:29
мисс_граффити   Ввод строк сделал? Проблемы только с определением …   7.10.2008 18:37
Rocket   Ввод строк сделал? Проблемы только с определением…   7.10.2008 21:09
мисс_граффити   Ну например... .model small .stack 512 .data buf1 …   8.10.2008 0:26
Rocket   Ну например... всё отлично, большое спасибо) вот т…   9.10.2008 3:38
мисс_граффити   У меня работает все. Да ты по сути ничего в этой с…   9.10.2008 3:54
Rocket   У меня работает все. Да ты по сути ничего в этой …   10.10.2008 3:21
volvo   Rocket, Чем компилируешь, если не секрет? Приведе…   10.10.2008 3:43
Rocket   Rocket, Чем компилируешь, если не секрет? Привед…   11.10.2008 1:31
volvo   А может, ты его просто не видишь? :wink: Alt+F5 н…   11.10.2008 1:51
Rocket   А может, ты его просто не видишь? :wink: Alt+F5 …   11.10.2008 2:01
Rocket   Всё-таки как организовать вывод сообщеия о том нас…   13.11.2008 5:20
volvo   Ну, и кто тебе сказал, что lea dx, X преобразует т…   13.11.2008 6:18
Rocket   А если у нас не 10 символом максимальный размер, а…   28.11.2008 2:31
volvo   Значит, придется написать процедуру вывода десятич…   28.11.2008 3:12
Rocket   Значит, придется написать процедуру вывода десятич…   28.11.2008 4:02
volvo   Комментарии добавлены в предыдущее сообщение...   28.11.2008 5:10
Rocket   Комментарии добавлены в предыдущее сообщение... …   5.12.2008 3:25
volvo   Вот тебе программа, которая это делает... В виде п…   7.12.2008 16:24
Rocket   Вот тебе программа, которая это делает... У меня …   9.12.2008 4:36
volvo   1) Использование "offset". Я так полага…   9.12.2008 5:08
Rocket   Всё стало на свои места! Спасибо:) Так, вот ещ…   10.12.2008 4:24
volvo   1) процедура show_ax для чего предназначена? мы в…   10.12.2008 4:46
Rocket   Да, скорее всего надо в процедуре получать через …   10.12.2008 16:42
volvo   А я переделал вот так: findSStr proc ; Ищем первы…   10.12.2008 17:09
Rocket   Вот последняя вариация программы: data segment en…   11.12.2008 3:20
volvo   Нет... Проблема не тут. Замени вот эти 2 строки: …   11.12.2008 3:56
Rocket   Нет... Проблема не тут. Замени вот эти 2 строки: …   11.12.2008 4:42
volvo   Ты просто забыл кое что (например, очистить AX пер…   11.12.2008 5:39
Rocket   Ты просто забыл кое что (например, очистить AX пер…   12.12.2008 2:40


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.03.2024 9:21
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name