Значит, придется написать процедуру вывода десятичного числа:
А можно более подробно объяснить логику данной подпрограммы?...не предполагал, что реализация будет столь замысловатой
Сообщение отредактировано: volvo -
1. Заголовок или название темы должно быть информативным
2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE]
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора.
5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM!
6. Проверяйте программы перед тем, как выложить их на форум!!
Обработка символьной информации, с помощью функций DOS |
Rocket |
Сообщение
#21
|
Знаток Группа: Пользователи Сообщений: 306 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
|
volvo |
Сообщение
#22
|
Гость |
Цитата А можно более подробно объяснить логику данной подпрограммы? Комментарии добавлены в предыдущее сообщение... |
Rocket |
Сообщение
#23
|
Знаток Группа: Пользователи Сообщений: 306 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
|
volvo |
Сообщение
#24
|
Гость |
Цитата А вот как организовать подпрограмму поиска одной введённой строки в другой строке? И ещё: вывод позиции, с которой подстрока содержится в строке... Вот тебе программа, которая это делает... В виде подпрограммы оформляй сам:MODEL small(процедуру writeDEC возьми из предыдущих постов, я не стал ее опять копировать...) |
Rocket |
Сообщение
#25
|
Знаток Группа: Пользователи Сообщений: 306 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Вот тебе программа, которая это делает... У меня возник ряд вопросов по реализации... 1) Использование "offset". Я так полагаю, что это полный аналог команды "lea" ? 2) inpStrDat что это за переменная, для чего она нужна? 3) mov di, offset inpStrDatчто делает конструкция такого вида? 4) Как определяется размер строки? т.е. mov cl, inpStrLenпочему в cl сразу помещается размер строки? 5) При переходе на метку beginCompare:, где мы должны проверять последующие за первой буквы, мы снова проверяем совпадение первых букв, так ли это? 6) Когда мы из стека вытаскиваем di, разве он сразу не указывает на позицию, с которой начинается подстрока в строке? Как вообще происходит тогда вычисление позиции? Сообщение отредактировано: volvo - |
volvo |
Сообщение
#26
|
Гость |
1) Использование "offset". Я так полагаю, что это полный аналог команды "lea" ? Правильно полагаешь... ; можно вот так получить смещение inpStrDatВ обоих случаях смещение этого массива от начала сегмента будет занесено в регистр DI... 2) inpStrDat что это за переменная, для чего она нужна? Как это "для чего"? А строку ты что, в воздухе хранить будешь? Вообще-то для нее надо место выделять. Вот я и выделил 200 байт.Вообще обрати внимание, для ввода строки используется функция 0AH прерывания 21H... А она требует для работы вот чего: Цитата(Абель) LABEL представляет собой директиву с атрибутом BYTE. Первый байт содержит максимальную длину вводимых данных. Так как это однобайтовое поле, то возможное максимальное значение его - FFh или 255. Второй байт необходим DOS для занесения в него действительного числа введенных символов. Третьим байтом начинается поле, которое будет содержать введенные символы. Вот так... А поскольку я не описывал LABEL (ленивый я, не люблю набирать лишние символы ), то в DX загружал смещение inpStr, то есть, первого из необходимых параметров...NAMEPAR LABEL BYTE ; Список параметров: Так как в списке параметров директива LABEL не занимает места, то NAMEPAR и MAXLEN указывают на один и тот же aдрес памяти. В трансляторе MASM для определения списка параметров в виде структуры может использоваться также директива STRUC. Однако, в связи с тем, что ссылки на имена, определенные внутри, требуют специальной адресации, воздержимся cейчас от рассмотрения данной темы до гл. 24 "Директивы ассемблера". Для запроса на ввод необходимо поместить в регистр AH номер функции - 10 (шест. 0Ah), загрузить адрес списка параметров (NAMEPAR в нашем примере) в регистр DX и выполнить INT 21H Я надеюсь, вопрос 4) Как определяется размер строки? т.е.
исчерпан? Я там, в цитате, выделил ответ на него...mov cl, inpStrLenпочему в cl сразу помещается размер строки? 5) При переходе на метку
Так, но почему тебя это пугает? Я же уменьшаю DI перед проверкой, то есть, DI указывает именно на первый, совпавший символ в строке...beginCompare:, где мы должны проверять последующие за первой буквы, мы снова проверяем совпадение первых букв, так ли это? 6) Когда мы из стека вытаскиваем di, разве он сразу не указывает на позицию, с которой начинается подстрока в строке? Как вообще происходит тогда вычисление позиции? Нет, он указывает на смещение относительно начала сегмента... А для того, чтобы вычислить позицию, надо из этого самого смещения, которое хранится в DI, вычесть смещение первого символа строки, которое я и заношу в DX... После вычитания в AX имеем позицию подстроки в строке... |
Rocket |
Сообщение
#27
|
Знаток Группа: Пользователи Сообщений: 306 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Всё стало на свои места! Спасибо
Так, вот ещё несколько вопросов вопросов : 1) процедура show_ax для чего предназначена? мы вроде её не используем нигде... 2) Зачем записывать $ конец введённой строки? Я знаю, что это признак конца строки... 3) Как это в виде процедуры оформить? Я полагаю, что после ввода строки и подстроки и после соответствующих подготовок. Нужно что-нибудь передавать в процедуру или прятать в стек? Сообщение отредактировано: volvo - |
volvo |
Сообщение
#28
|
Гость |
1) процедура show_ax для чего предназначена? мы вроде её не используем нигде... Это я забыл удалить, она не нужна тут...2) Зачем записывать $ конец введённой строки? Я знаю, что это признак конца строки... Ну, раз знаешь - чего спрашиваешь? Допустим, ты ввел 20 символов, места выделено под 200, и тебе понадобилось распечатать введенную строку. Что делать будешь? Правило хорошего тона требует заполнить строку как положено (если этого не делает функция DOS - то это должен сделать программист, чтоб потом не отлавливать глюки). Раз строка должна заканчиваться символом "$", значит его надо добавить...3) Как это в виде процедуры оформить? Я полагаю, что после ввода строки и подстроки и после соответствующих подготовок. Нужно что-нибудь передавать в процедуру или прятать в стек? Да, скорее всего надо в процедуре получать через DI адрес строки, через SI - адрес подстроки, и через CX - длину строки... А возвращать значение она должна через AX, как обычно, если AX = 0, то совпадений нет, иначе в AX содержится индекс первого элемента строки... Сохранять надо все регистры, которые изменяются внутри процедуры, опять же правило хорошего тона: не делай сам себе проблем, после возврата из процедуры содержимое регистров (кроме тех, через которые возвращаются результаты) должно быть точно таким же, как и до ее вызова... |
Rocket |
Сообщение
#29
|
Знаток Группа: Пользователи Сообщений: 306 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Да, скорее всего надо в процедуре получать через DI адрес строки, через SI - адрес подстроки, и через CX - длину строки... А возвращать значение она должна через AX, как обычно, если AX = 0, то совпадений нет, иначе в AX содержится индекс первого элемента строки... Сохранять надо все регистры, которые изменяются внутри процедуры, опять же правило хорошего тона: не делай сам себе проблем, после возврата из процедуры содержимое регистров (кроме тех, через которые возвращаются результаты) должно быть точно таким же, как и до ее вызова... Я переделал следующим образом:
и всё-таки походу криво процедуру оформил... ? |
volvo |
Сообщение
#30
|
Гость |
А я переделал вот так:
findSStr proc, что я сделал не так? Опять же, замечание: у тебя процедура должна найти вхождение подстроки в строку. Только найти... Все, на этом ее работа закончилась. Выводить результаты - не ее дело, этим занимается вызывающая программа, если надо. |
Rocket |
Сообщение
#31
|
Знаток Группа: Пользователи Сообщений: 306 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Вот последняя вариация программы:
и в ней присутствует косяк... Вобщем, когда подстроки нет в строке, то программа всё равно выводит сообщение с номером позиции...выводит 0. Мне кажется, что не происходит вот это:
|
volvo |
Сообщение
#32
|
Гость |
Цитата Мне кажется, что не происходит вот это: Нет... Проблема не тут. Замени вот эти 2 строки:xor ax, ax; не найдено, вернем 0 test ax, 0 на or ax, axи проверь... |
Rocket |
Сообщение
#33
|
Знаток Группа: Пользователи Сообщений: 306 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Нет... Проблема не тут. Замени вот эти 2 строки: test ax, 0 на or ax, axи проверь... Идельно! Всё работает! Недеюсь больше по этой программе вопросов не возникнет) Я решил в первой программе, которая определяла какая из двух строк больше и насколько, решил изменить функцию ввода с 3Fh на 0ah, я же теперь знаю особенности этой функции в отличии от функции 3Fh... Всё бы ничего, только вот вывод цифры отказывается работать... Вот собственно сама переделанная программа:
по-видимому, что-то с регистрами напутал...или стек? |
volvo |
Сообщение
#34
|
Гость |
Ты просто забыл кое что (например, очистить AX перед занесением в AL разности длин... Ну, младший байт занесется,а то, что было в старшем - останется... И чего ты напечатаешь тогда?), и ошибся при вычислении разности длин в нижнем фрагменте, там надо из второй длины вычитать первую, а ты 2 раза сделал одно и то же... Читай комментарии...
|
Rocket |
Сообщение
#35
|
Знаток Группа: Пользователи Сообщений: 306 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Ты просто забыл кое что (например, очистить AX перед занесением в AL разности длин... Ну, младший байт занесется,а то, что было в старшем - останется... И чего ты напечатаешь тогда?), и ошибся при вычислении разности длин в нижнем фрагменте, там надо из второй длины вычитать первую, а ты 2 раза сделал одно и то же... Читай комментарии... Большое человеческое спасибо! Сообщение отредактировано: volvo - |
Текстовая версия | 23.12.2024 20:38 |