| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Asm для начинающих > Прерывания DOS. Строка с консоли. |
| Автор: I_Am_Rock 7.2.2009, 00:02 | ||||
| Всем привет! Вот такой код:
С этим кодом все норм - т.е. строка выводится на консоль и ждет клавишу. Но вот я изменил его.
Я хочу, чтобы я ввел текст, он занимал бы место вот этого "Привета", и тут же выводился вместо него. Но это почему-то не происходит. Точнее происходит - но если введено больше 1 символа и меньше 5 и причем выводится вместе с какими-то др. символами (непонятно откуда). Кто знает - поясните, пожалуйста, что тут не так. |
| Автор: dumb 7.2.2009, 13:55 |
| функция 0ah ввода строки использует специальный формат данных. (найти пример работы можно найти в соседних темах) функция 09h вывода строки конец строки определяет по байту со значением 24h('$') |
| Автор: ФедосеевПавел 7.2.2009, 14:05 | ||
| Привет, I_Am_Rock Лишние символы оттого, что после ввода строки функцией 0a int 21h ты не ставишь признак конца строки для функции 09 int 21h - '$', а кроме того почитай о формате буфера ввода строки функции 0a int 21h. Вот пример работы этих функций в паре
|
| Автор: I_Am_Rock 7.2.2009, 16:02 |
| Вобщем, я почти разобрался. Только не могу понять одного - как определить размер строки, введенной с помощью 0A int 21h? (с тем, чтоб добавить после строки знак $). Чтобы лучше понять принцип - программир-ую, редактируя пустой com-файл в HVIEW'е. Как там это сделать? |
| Автор: ФедосеевПавел 7.2.2009, 22:46 | ||||||
Для ввода строки функцией 0ah int 21h определяется не просто строка, а структура
После вызова Fn 0ah int 21h нужно заменить символ 0dh на '$'
Ну а в Hiew'е - сам балуйся |
| Автор: I_Am_Rock 8.2.2009, 01:30 | ||
| ФедосеевПавел Спасибо за ответ. Но как программа понимает, что в kbLen находится длина? В представленном тобой коде (большом) есть
,т.е. содержимое kbLen записывается в bl. Но я не понимаю - как оно, содержимое, вообще изначально попадает в kbLen? Ведь во всей программе больше нет ни одного упоминания kbLen. Наверное, для знающего асм это кажется смешным. |
| Автор: ФедосеевПавел 8.2.2009, 02:21 |
| Подпрограмма обработки прерывания (Fn 0ah int 21h) записывает туда значение (одновременно с символами вводимой строкои asStr). Т.е. вызывая эту функцию, программа передаёт ей в ds:dx адрес структуры, в которой заполнен только один байт - kbMax. После нажатия на Enter, функция заполняет другие поля структуры - kbLen и asStr - и возвращает управление программе. Так программа приобретает введённую с клавиатуры строку и длину этой строки (как в рекламе - купите левый ботинок и правый получите бесплатно). |
| Автор: I_Am_Rock 8.2.2009, 12:58 |
| А если я во всех (абсолютно во всех) местах программы kbLen заменю на bkLen, она туда запишит то, что нужно? И как программа догадывается что именно сюда надо записать длину? Почему, например, не наоборот - в kbMax реальную длину, а в kbLen максимальную? А если у меня еще 10 переменных?.. |
| Автор: ФедосеевПавел 8.2.2009, 23:42 | ||||||||||
Прости, мне очень лень набирать ручками справку по функции ДОС из TechHelp'а или любой книги по Assembler'у. Но вкратце, для Fn 0ah требуется передать в ds:dx адрес буфера (структуры) со следующим форматом: 0-й байт - максимально возможная длина строки (1-254), 1-й байт - здесь после выполнения преравания будет находиться реальная длина введённой строки, 2-й байт - начало строки. Поэтому переменные в программе определяются в строго определённом порядке
При вызове Fn 0ah в ds:dx помещается адрес этой структуры (т.е. адрес kbMax, а не asStr - как это делалось в твоей программе)
А для вывода строки на экран используется уже адрес самой строки asStr
Твоё начальное желание
неосуществимо, по причине необходимости двух дополнительных байтов kbMax и kbLen. Пожалуйста, для изучения языка, перейди на нормальные компиляторы TASM или MASM, также можно изучать Assembler, встроенный в компиляторы других языков (Delphi, Pascal, C/C++). Так ты сможешь избежать неразберихи в адресах переменных. |
| Автор: I_Am_Rock 9.2.2009, 14:53 | ||||
Ааа... Теперь я кажется понял.
У меня MASM. И так-то я в нем уже чуть научился работать - понял как использовать в нем API-функции (я их давно изучил еще на др. языках) и сделал свой калькулятор. Да и дальше в MASM собираюсь учиться. Просто чтобы быстрее понять суть на этом этапе поигрался с чистым ассемблером (где прямо при создании проги я вижу байты которые ввожу и кроме которых ничего не будет). Большое спасибо. |
| Автор: I_Am_Rock 9.2.2009, 15:25 |
| Все, написал программку. Спасибо, Павел. И даже получилось лучше, чем ожидал. Удивила меня одна вещь. Записав строку с помощью Fn 0ah, строка пошла не поверх имеющихся данных, а как бы сместив их вправо. Знак доллара находился на месте для строки, она его отодвинула и получается - строка оканчивается долларом, как и надо. Не ожидал такого "сервиса". |
| Автор: ФедосеевПавел 9.2.2009, 21:21 |
| Ой, а я не все понял. Можно программу посмотреть, хоть одним глазком... Из чистого любопытства... |
| Автор: I_Am_Rock 9.2.2009, 23:42 |
| Скриншот в файле. А что именно не понятно? У меня у самого тут сейчас вопрос возник.((( Я делал этот файл - он находился прямо на диске (т.е. E:\art1.com), скопировал на Рабочий стол - ведет себя по другому, не дает ввести больше 3 символов! Хотя во всем остальном как тот, что на прямо на диске. Вот уже вообще ничего не понимаю....((( |
| Автор: ФедосеевПавел 10.2.2009, 00:13 | ||||||
Три символа оттого. что значение в ячейке [011a] не задаётся в программе, а заполняется мусором (вернее, там ещё перед запуском программы был какой-то мусор)
Добавление "$" в конец строки
или
|
| Автор: I_Am_Rock 10.2.2009, 12:14 | ||
Мусор - откуда он там может быть? И к тому же 3 символа - только если запускаешь прогу в других местах, а если в E:\art1.com (т.е. там где писал ее) - все норм! Объясни - как это мб? Спасибо. Буду так теперь делать. |
| Автор: ФедосеевПавел 12.2.2009, 19:52 | ||
"Мусор" от того, что программа при запуске не инициализирует переменные. Если в исходнике программы написать такие строки
То измниться и сам бинарный образ файла - в нем добавяться несколько байт (10 в данном случае). И именно к этим байтам и будет обращение при вызове прерываний. Но так как программа создавалась из Hiew и в ней (в её образе) не выделялось место под переменные, то при запуске программы в ячейке памяти [011a] будет находиться произвольное число - например 3. Могу лишь предположить, что при запуске из под различных оболочек, память заполняется значениями, характерными для данной оболочки. |
| Автор: I_Am_Rock 12.2.2009, 23:34 | ||
| Ммм... интересно. Позволю себе спросить не по теме. Павел, сколько вы учились ассемблеру? И пишите ли серьезные программы на нем (или только используете в Дельфи, С++ и т.п.)?
|