Рассылка закрыта
При закрытии подписчики были переданы в рассылку "RFpro.ru: Ассемблер? Это просто! Учимся программировать" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
RusFAQ.ru: программирование на языке Assembler
Информационный Канал Subscribe.Ru |
/ КОМПЬЮТЕРЫ И ПО / Языки программирования / Assembler
Выпуск № 195
от 24.07.2005, 20:20
Администратор: | Калашников О.А. |
В рассылке: | Подписчиков: 253, Экспертов: 14 |
В номере: | Вопросов: 6, Ответов: 14 |
Вопрос № 23684: Вопрос такой : какой ассеблер поддерживает ключевое слово LOCALS и он же поддерживает конструкции вида move byte ptr [bx], offset @@1 - offset labelN? Мне чтобы скомпилировать понадобилось move byte ptr [bx], byte ptr [offset @@1 - ...
Вопрос № 23687: Приношу извенения за предыдущие вопросы, которые задовал по несколько раз. :-) Уважаемые эксперты не могли бы вы объяснить мне словестно, как устроена 32-ух разрядная организация памяти. Можно ли 32-ух разрядную адресацию использо...
Вопрос № 23696: Здравствуйте! У меня такой вопрос. Делею несколько объектных модулей. В одном делаю PUPLIC процедуру. Хочу вызвать ее с другого. Компилируется, ругается: Calll1.obj(calll1.asm) : warning L4004: possible fixup overflow at 8 in segment...
Вопрос № 23698: Здравствуйте! Еще вопрос: программа не более 1 кб. Хочу оставить резидентой в младших адрессах. Пробовал копировать, по случайному адрессу, но затер что-то важное. Как узнать, куда можно скопировать? Если бы еще и пометить, что даный участок пренадле...
Вопрос № 23730: Добрый день. У меня вопрос относительно всем известной рассылки Калашникова. В 23-ем выпуске, где рассматривается резидент, записывающий нажимаемые пользователем клавиши, обработчик 9-го прерывания содержит следующие строки: 1 cli ;Запрещаем ...
Вопрос № 23734: Добрый день! Я изучаю 17 урок. Там следующий текс: Обратите внимание, как мы просто вычисляем длину строки. Но это только в том случае, если длина строки известна: Mess_quit db 'Ассемблер',0 Mess_quitl equ $-Mess_quit Причем, последн...
Вопрос № 23.684 |
Вопрос такой : какой ассеблер поддерживает ключевое слово LOCALS и он же поддерживает конструкции вида move byte ptr [bx], offset @@1 - offset labelN? Мне чтобы скомпилировать понадобилось move byte ptr [bx], byte ptr [offset @@1 - offset labelN] делать на ml.exe 6.14.xxxx Тогда все работало замечательно... |
Отправлен: 18.07.2005, 20:00 Вопрос задал: Some Stupid Guy (статус: Посетитель) Всего ответов отправлено: 2 |
Отвечает: Евгений Иванов Здравствуйте, Some Stupid Guy! LOCAL поддерживает TASM, MASM. proc Edge_add ARG @@ei: dword, @@type :dword, @@pos :dword USES esi, edi, ebx, ecx, edx, eax LOCAL @@z :dword --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 18.07.2005, 21:37 Оценка за ответ: 3 |
Отвечает: DSota Здравствуйте, Some Stupid Guy! Ключевое слово LOCALS в его виде с буквой "S" поддерживает только TASM. Правда и он не скомпилит эту строку, но он точно скомпилит: "mov byte ptr [bx], offset @@1 - offset labelN" (там буквы "e" в слове "move" нет). --------- Открыть глаза навстречу солнцу. |
Ответ отправил: DSota (статус: Практикант) Отправлен: 19.07.2005, 10:39 Оценка за ответ: 5 |
Вопрос № 23.687 |
Приношу извенения за предыдущие вопросы, которые задовал по несколько раз. :-) Уважаемые эксперты не могли бы вы объяснить мне словестно, как устроена 32-ух разрядная организация памяти. Можно ли 32-ух разрядную адресацию использовать в чистом DOS-е. Я врде читал, что можно 32-ух разрядные регистры использовать, только нужно следить, чтобы они не превыщали объем 16-го. |
Отправлен: 18.07.2005, 20:46 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 2 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! можно использовать, но опять же сегменты. и действительно будет только младшие 16 бит. но старшие нужно обязательно обнулять! sub eax,eax mov ax, 17h push 4 pop ds mov bl, [eax] вот так вот можно. удачи! --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 18.07.2005, 21:34 |
Отвечает: Стас Здравствуйте, Терсков Алексей Николаевич! в дополнение: 1)Используй 32 регистры для арифметики и с осторожностью для адресации. 2)В чистом DOS-е можно также перейти и в защищенный режим, тогда вообще никаких ограничений в использовании 32 разрядных регистров. |
Ответ отправил: Стас (статус: Практикант) Отправлен: 19.07.2005, 00:53 |
Вопрос № 23.696 |
Здравствуйте! У меня такой вопрос. Делею несколько объектных модулей. В одном делаю PUPLIC процедуру. Хочу вызвать ее с другого. Компилируется, ругается: Calll1.obj(calll1.asm) : warning L4004: possible fixup overflow at 8 in segment T1 target external 'Beep' Calll1.obj(calll1.asm) : error L2002: fixup overflow at 8 in segment T1 target external 'Beep' Calll1.obj(calll1.asm) : warning L4004: possible fixup overflow at B in segment T1 target external 'Quit' Calll1.obj(calll1.asm) : error L2002: fixup overflow at B in segment T1 target external 'Quit' Но файл запускается. Привожу два ассемблерных файла Командная строка линковки. D:masm61inlink.exe Calll1.obj+L_1.obj, Cal_1.com,,, /t /nologo Пробовал и ехе файлы - ругается, но файл запускается Подскажиту, где ошибка. Пожалуйста, испрате asm файлы, если есть ошибка, и укажите параметры линковки и компилирования, если где-то ошибка. Приложение: |
Отправлен: 19.07.2005, 00:12 Вопрос задал: Igor Vlad. (статус: Посетитель) Всего ответов отправлено: 2 |
Отвечает: Евгений Иванов Здравствуйте, Igor Vlad.! model поставь. TINY и ты ret забыл в конце подпрограммы quit. удачи. --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 19.07.2005, 00:28 Оценка за ответ: 2 Комментарий оценки: НЕ РАБОТАЕТ. А может просто нужно сегменты назвать одним именем? |
Отвечает: Ayl Здравствуйте, Igor Vlad.! Ты определил 2 разных сегмента: t1 и text, но при этом внешнии ссылки указываешь через near. Вот в этом и причина - у тебя дальний вызов должен быть либо объявляй кодовый сегмент с одним именем. --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 19.07.2005, 11:38 Оценка за ответ: 5 Комментарий оценки: Спасибо, я понял. Я так уже и пробовал. |
Вопрос № 23.698 |
Здравствуйте! Еще вопрос: программа не более 1 кб. Хочу оставить резидентой в младших адрессах. Пробовал копировать, по случайному адрессу, но затер что-то важное. Как узнать, куда можно скопировать? Если бы еще и пометить, что даный участок пренадлежит DOS или еще какому-нибудь системному драйверу было бы просто замечательно! Заранее благодарен! |
Отправлен: 19.07.2005, 00:28 Вопрос задал: Igor Vlad. (статус: Посетитель) Всего ответов отправлено: 4 |
Отвечает: Стас Здравствуйте, Igor Vlad.! Нельзя копировать куда угодно. Даже если не затрешь что нибудь важное - тебя кто нибудь затрет :). Выделяй память DOS функцией (ah=48; int 21h). Либо нужно хорошо знать архитектуру DOS, этапы загрузки и т.п. Для того чтобы переместить что-то или даже затереть. |
Ответ отправил: Стас (статус: Практикант) Отправлен: 19.07.2005, 00:58 |
Отвечает: Евгений Иванов Здравствуйте, Igor Vlad.! смотри исходник, там технология записи в окружение и psp. вот кусочек :)) это когда ищутся переменные окружения. mov bx,88 push cx si m162a: mov cx,bx m172a: lodsb cmp al,'=' jz m202a loop m172a jmp m142a m212a: pop bx ds push dx jmp m162a m202a: pushf push si std sub si,2 mov di,ofs d1+5 mov bx,cx mov cx,6 repz cmpsb lahf pop si popf sahf jnz m162a pop dx всего хорошего! Прикреплённый файл: Загрузить >> |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 19.07.2005, 08:30 |
Отвечает: Котиев Зураб Здравствуйте, Igor Vlad.! можно использовать MSB (memory control block) ┌───┐ ┌──'M'(4dH) - за этим блоком есть еще блоки +0 1 │Тип ├──┴──'Z'(5aH) - данный блок является последним ├───┴───┐ +1 2 │Владелец | параграф владельца (для FreeMem); 0 = владеет собой сам ├───┴───┤ +3 2 │Размер │ число параграфов в этом блоке распределения ├───┴───┴──────── ─ ────┐ +5 0bH│зарезервировано │ └───┴───┴───┴───┴ ─ ┴───┘ если ты пометишь владельца 0008h то владелец дос .сам mcb находится на один параграф ниже psp . тут те пара ссыл на тему http://www.wasm.ru/article.php?article=1006005 http://www.wasm.ru/article.php?article=1006004 если есть вопросы залазь мне ко мне на форум |
Ответ отправил: Котиев Зураб (статус: 5-ый класс) Отправлен: 19.07.2005, 11:47 |
Отвечает: Ayl Здравствуйте, Igor Vlad.! Чую, чую, что вирусом пахнет! В младших адресах... Хм... В младших адресах все занято... Можно, конечно, попробовать прописаться в область векторов прерываний, начиная с адреса 0:200h (вторая половина таблицы, обычно неиспользуются), но при этом твоя программа должна быть не больше 512Кб. Еще вариант - область видеопамяти, но это не младшие адреса. Причем ты можешь часть кода прописать в область векторов (которая будет получать управление от прерывания), а основной код - в видеопамять. Либо тебе нужно искать первый незанятый кусок памяти достаточного объема по цепочке MCB. А для того, чтобы тебя не было видно, сам кусок памяти помечаешь как облать DOS (см. структуру MCB). Приложение: |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 19.07.2005, 12:09 Оценка за ответ: 5 Комментарий оценки: Спасибо за совет! Попробую. Относительно вируса... Да. Но что я могу сделать под ДОСом? |
Вопрос № 23.730 |
Добрый день. У меня вопрос относительно всем известной рассылки Калашникова. В 23-ем выпуске, где рассматривается резидент, записывающий нажимаемые пользователем клавиши, обработчик 9-го прерывания содержит следующие строки: 1 cli ;Запрещаем все прерывания 2 pushf ;Дадим сперва управление... 3 call dword ptr cs:[0FCh] ;...оригинальному обработчику 4 pusha ;Сохраним регистры в стеке... 5 push es 6 push ds 7 cld ;Направление - вперед! 8 in al,60h ;Получим СКАН-КОД нажатой клавиши. 9 test al,10000000b ;(=80h) Это отпускание клавиши? 10 jnz Exit_09h ;Если так, то сохранять ее код не надо 11 mov ax,cs ;Сегментные регистры должны указывать на наш сегмент. 12 mov ds,ax 13 mov es,ax 14 mov ah,1 ;Получим ASCII-код нажатой клавиши. 15 int 16h 16 jz Ext_code ;Буфер клавиатуры пуст? Тогда на выход. ........................и так далее...................... Меня интересуют сроки 8-16. Что в частности делают строки 8 и 9? Почему в строке 9 проверяется именно число 80h? Что делают строки 14,15? И еще один вопрос. При освобождении памяти функцией DOS 49h. Почему мы указываем только сегмент в регистре ES? Например, при выделении памяти мы еще указываем в регистре BX размер выделяемого участка. Здесь же почему-то только сегмент. Заранее спасибо. |
Отправлен: 19.07.2005, 18:45 Вопрос задал: AlexB (статус: Посетитель) Всего ответов отправлено: 3 |
Отвечает: Евгений Иванов Здравствуйте, AlexB! 1. в строке 9 проверяется не число 80h, а там проверяется 7 бит - используется так называемая маска при операции И. если бит проверяемый сброшен, то результат будет нулю и флаг ZF=1. и наоборот. 2. а ты посмотри, что там содержится по адресу [ES - 1:0] именно так. На 16 байт меньше. там содержится блок управления памятью. там тоже есть M и Z. M - значит дальше есть блок Z - последний блок. ну и размеры там указываются блоков и кому он принадлежит - сегмент окружения по моему... во вложении смотри программу, которая остаётся резидентной без каких либо функций доса ;) она вклинивается в наиболее подходящий свободный блок памяти... потому что они не полностью заняты.. :) удачи!! Прикреплённый файл: Загрузить >> |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 19.07.2005, 21:45 |
Отвечает: Стас Здравствуйте, AlexB! Опять позволю себе расшифровать: >Почему в строке 9 проверяется именно число 80h? Как сказал Евгений Иванов проверяется старший бит. Дело в том, что при нажатии на кнопку на клавиатуре на 60 порт приходит её "порядковый номер". А когда ты ее отпускаешь то на 60 порт опять идет её порядковый номер + 80h (128). Таким образом когда ты просто нажимашь(и отпускашь) на клаве кнопку "A" - Int 9 срабатывает ДВА раза на нажатие и на отпускание. Так вот - "9 test al,10000000b ;(=80h) Это отпускание клавиши?" фиксирует именно отпускание клавиши, игнорируя её нажатие. Про память проще - когда выделяешь память - системе нужно знать сколько тебе нужно, когда высвобождаешь системе этого знать не надо - так как она сама хранит размер выделеного блока. Иначе как выделить следующий если не знаешь размеров всех блоков которые есть в системе в текущий момент? |
Ответ отправил: Стас (статус: Практикант) Отправлен: 20.07.2005, 00:37 |
Отвечает: Ayl Здравствуйте, AlexB! Строка 8 - получить значение из порта 60h. Порт 60h - это один из интерфейсных портов для работы с клавиатурой, в нем находится скен-код последней нажатой или отпушенной клавиши. Да-да, именно или нажатой, или отпущенной. Когда пользователь работает с клавиатурой, то последняя отслеживает все изменения состояния клавиш. Когда пользователь нажимает клавишу, то контроллер клавиатуры помещает в 60-й порт ее скен-код (число от 1 до 127). То есть, байт, у которого старший бит равен 0. И выдает прерывание IRQ1. Когда пользователь отпускает клавишу, то КК помещает в 60-й порт скен-код, увеличенный на 128. То есть, байт, у которого старший бит равен 1. С помощью команды в строке 8 мы считываем это код, а с помощью команды в строке 9 проверяем, установлен ли старший бит, т.е. нажата ли или отпущена клавиша. Строки 14 и 15 проверяют, есть ли в буфере клавиатуры какая-либо клавиша. Это вызов прерывания 16h BIOS. В области BIOS выделяется 32-байтная область, которая называется буфером клавиатуры. Эта область организована по принципу очереди (FIFO - First In, First Out; первым пришел - первым ушел). В нее помещается информация о нажатых клавишах (2 байта, старший байт - скен-код, младший - ASCII-код либо 0). Функция 1 прерывания 16h проверяет, есть ли что-то в буфере, и в зависимости от этой проверки устанавливает флаг ZF (ZF = 0 => буфер пуст, ZF = 1 => в буфере что-то есть). При выделении памяти DOS предваряет выделенную область специальным 16-байтным заголовком, т.н. контрольным блоком памяти (MCB - Memory Control Block). В этом блоке содержится информация о расположении блока в цепочке (последний/непоследний), о владельце блока (адрес PSP владельца или 0 для нераспределенных блоках), о размере блока в параграфах и т.п. При освобождении памяти нам достаточно указать только сегмент освобождаемого блока, т.к. информация о размере блока будет взята системой из соответствующего MCB. --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 20.07.2005, 12:42 |
Вопрос № 23.734 |
Добрый день! Я изучаю 17 урок. Там следующий текс: Обратите внимание, как мы просто вычисляем длину строки. Но это только в том случае, если длина строки известна: Mess_quit db 'Ассемблер',0 Mess_quitl equ $-Mess_quit Причем, последняя строка занимать памяти не будет! В отладчике строка mov dx,offset Mess_quitl будет выглядеть как mov dx,9. Так как строка Mess_quitl equ $-Mess_quit не занимает памяти, то в строке mov dx,offset Mess_quitl я не понимаю “кого” мы заносим смещение в регистр dx? Зачем нужен offset? |
Отправлен: 19.07.2005, 19:17 Вопрос задал: Programist (статус: Посетитель) Всего ответов отправлено: 1 |
Отвечает: John Freeman Здравствуйте, Programist! Последняя строка в смысле Mess_quitl equ $-Mess_quit это константа, которая будет вычислена компилятором и подставлена везде где юзается $ - текущий адрес , $-mess_Quit - разность адресов начала и конца строки= длина строки --------- You're trying to take me They trying to make me This is the only Gives me the only thing Tired of lying, I'm tired of lying The only thing I inderstand is what I feel... |
Ответ отправил: John Freeman (статус: Профессор) Отправлен: 19.07.2005, 19:55 |
© 2001-2005, RusFAQ.ru, Россия, Москва. Все права защищены.
Идея, дизайн, программирование, авторское право: Калашников О.А.
Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки:
comp.soft.prog.faq
Отписаться
Вспомнить пароль
В избранное | ||