![]() |
|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
|
Опции темы | Поиск в этой теме |
![]() |
#21 |
Регистрация: 08.11.2010
Сообщений: 6
|
![]()
Mikl___:
«Из задания на твою курсовую следует, что прежде всего нужно разбираться с тем, что делает твой драйвер-резидент, а этого у тебя не получится пока досконально не разберешься со всеми процедурами и переменными, с каждой командой». Вот это уже совершенно другой разговор. Более конструктивный. Mikl___: «Комментарии Soucer генерирует автоматически и если в процедуре sub_2 Soucer не знает какое число находится в DX поэтому он предполагает что DX равен 0 и в комментарии пишет про port 0 ... смотрим sub_3 ... опять не известно значение в DX и комментарии о port 0, после команды INC DX появляется комментарии о port 1, после команды DEC DX комментарии снова о port 0». А вот эту закономерность я и не заметил... Счет 1:0 в пользу Mikl___'а! P. S. Собственно, для таких целей, по-моему, и нужно коллективное обсуждение. А не для того, чтобы иронизировать друг над другом... Последний раз редактировалось I-Gor; 18.11.2010 в 07:39. |
![]() |
![]() |
![]() |
#22 |
Регистрация: 08.11.2010
Сообщений: 6
|
![]()
Немного изменил листинг Tronix’а, чтобы он мог собираться TASM’ом. Вновь собранный com-файл работает корректно, хотя при этом неадекватно много «весит» (2030 байт вместо 887 байт «в оригинале»). С чем это может быть связано? Заранее благодарен.
Использовал TASM 5.0. Строка компиляции: tasm /zn acp.asm. Строка компоновки: tlink /t acp.obj acp. Во вложении для справки исходные данные и полученный результат. |
![]() |
![]() |
![]() |
#23 |
Форумчанин
Регистрация: 15.06.2010
Сообщений: 740
|
![]()
Не знаю как там у вас так получилось. Вот щаз взял, отрезал шапку до строки .286c и компильнул - размер байт в байт получился с исходником.
TASM у мну представляется так: Turbo Assembler Version 4.1 Компилил так: tasm ACP3_DRV.ASM tlink /t ACP3_DRV.obj На выходе получил ACP3_DRV.COM размером в 887 байт.
Чтобы понять рекурсию, сперва нужно понять рекурсию.
|
![]() |
![]() |
![]() |
#24 |
Участник клуба
Регистрация: 11.01.2010
Сообщений: 1,139
|
![]()
I-Gor
Во вложении текст резидента, acp4_drv.asm, bat-файл который создает com-файл и acp4_drv.com в 887 байт, байт в байт соответствует исходному, присланному тобой если немного подумать, то лишнее из текста резидента можно убрать, в результате из acp4_drv.asm получаем acp5_drv.asm из которого создается acp5_drv.com размером в 787 байт. Посмотри, если с ним твой АЦП работает нормально, тогда программу можно еще уменьшить, а с маленькой программой разбираться проще Файлы не цепляются, куда выложить? |
![]() |
![]() |
![]() |
#25 |
Регистрация: 08.11.2010
Сообщений: 6
|
![]()
1. Tronix:
«Компилил так: tasm ACP3_DRV.ASM tlink /t ACP3_DRV.obj» Действительно, при компиляции без ключа /zn вновь собранный com-файл становится «копейка в копейку» с оригиналом. Наверное, TASM с этим ключом записывает какую-то отладочную информацию. 2. Выяснил, что пишет резидент в левом верхнем углу экрана при запуске. «Честным» путем этого не увидишь - как только резидент завершает свою работу, то DOS (точнее command.com) тут же сдвигает экран на строку вверх. Чтобы посмотреть, оформил запуск в bat-файле следующим образом: acp3_drv @pause >nul «Собаку» и параметр >nul вставил для предотвращения сдвига экрана при выполнении команды pause. Оказалось, что корректно запущенный резидент пишет даже не число, а сообщения вида «1;94» , «160?», «112<» , «15>>», в зависимости от своего расположения в памяти. Еще раз разобрал процедуры sub_4 и sub_5. Разработчик резидента, видимо, предполагал, что после выполнения в sub_4 команд mov ch,4 push ax mov cl,ch shr ax,cl mov cl,ch shr al,cl call sub_5 и инструкции and ax,0F0Fh из sub_5 в ah и al окажутся числа, не большие девяти. А вот черта с два они всегда такими окажутся! Четырьмя битами вообще-то можно закодировать шестнадцать значений. И если в ah:al будут числа от 10 до 16, то командой add ax,3030h в sub_5 они будут преобразованы в 3Ah – 3Fh, то есть в ASCII-коды символов «:», «;», «<», «=» «>» и «?». Для корректного отображения шестнадцатеричных цифр в таком случае к соответствующему коду нужно прибавить разность 41h – 3Ah (код буквы «А» минус код символа «:»), то есть число 7. С учетом этого внес в sub_5 следующие исправления: sub_5 proc near and ax,0F0Fh add ax,3030h ; получаем ASCII код цифр ;------------------------------- cmp ah,39h ; сравниваем код старшей цифры с кодом цифры "9" (39h) jle prn_h ; переход на печать, если код <= 39h add ah,7 ; прибавляем 7, если код > 39h ;------------------------------- prn_h: mov es:[bx],ah ; печать старшей цифры inc bx mov byte ptr es:[bx],0Fh inc bx ;------------------------------- cmp al,39h ; сравниваем код младшей цифры с кодом цифры "9" (39h) jle prn_l ; переход на печать, если код <= 39h add al,7 ; прибавляем 7, если код > 39h ;------------------------------- prn_l: mov es:[bx],al ; печать младшей цифры inc bx mov byte ptr es:[bx],0Fh inc bx retn sub_5 endp После компиляции и запуска резидента он, например, вместо последовательности «1;94» начинает выводить число 1B94, вместо «160?» - 160F (содержимое регистра CS, копируемое в AX перед вызовом sub_4), т. е. начальный адрес резидента в памяти. Mikl___: «…если немного подумать, то лишнее из текста резидента можно убрать…» Я, разобравшись с sub_4 и sub_5, вообще выкинул их из исходника к чертовой бабушке. Что они пишут, «нормальный» пользователь все равно не видит. Ну, а, если приспичит, то можно узнать эту информацию любой диагностической утилитой. Последний раз редактировалось I-Gor; 23.11.2010 в 15:37. |
![]() |
![]() |
![]() |
#26 |
Регистрация: 08.11.2010
Сообщений: 6
|
![]()
3. Выяснил алгоритм запуска «резидента». Вот листинг с моими комментариями:
real_start: push es ; Сохранение регистра es mov ax,3563h ; 35h - функция int 21h. Получить вектор прерывания 63h int 21h ; Вектор в es : bx, es - сегмент, bx - смещение адреса обработчика mov dx,es ; Копирование es в dx pop es ; Восстановление старого es or dx,bx ; Если dx : bx = 0, т. е. прерывание свободно jz loc_28 ; то переход на loc_28 int 20h ; Завершение работы, если прерывание занято loc_28: mov dx,offset int_63h_entry ; Адрес обработчика 63h в данной программе mov ax,2563h ; 25h - функция int 21h. Задать вектор прерывания 63h int 21h ; Вектор - в ds : dx, в ds - сегмент в dx - смещение mov dx,offset int_1Ch_entry ; Адрес обработчика 1Ch в данной программе mov ax,251Ch ; 25h - функция int 21h. Задать вектор прерывания 1Ch int 21h ; Вектор - в ds : dx, в ds - сегмет в dx – смещение mov dx,556h mov cl,4 shr dx,cl mov ax,cs ; В cs - начальный адрес программы call sub_4 ; Печать начального адреса. mov ax,3100h ; 31h - функция int 21h. Завершить int 21h ; программу и оставить резидентной seg_a ends Все равно осталось непонятным, зачем в строках: mov dx,556h mov cl,4 shr dx,cl помещать в dx константу 556h, затем сдвигать ее на фиксированное (четыре) количество бит вправо, то есть получать снова константу, но уже 55h? Не проще ли написать: mov dx,55h? И, главное, зачем понадобилось заносить это число в DX (точнее в DL) перед завершением работы (если процедура sub_4 и связанная с ней sub_5 ‘это значение не используют)? 4. Mikl___: «Файлы не цепляются, куда выложить?» Попробуй заархивировать zip’ом и зацепить снова. Если не получится, кидай на мыло ramis-nkсобакаrambler.ru Последний раз редактировалось I-Gor; 23.11.2010 в 15:44. |
![]() |
![]() |
![]() |
#27 |
Форумчанин
Регистрация: 15.06.2010
Сообщений: 740
|
![]()
Я вообще не понимаю, зачем вы смотрите эти процедуры? Зачем на них вообще тратить время? Выкинули и забыли про них. Что такое
mov dx,556h mov cl,4 shr dx,cl я тоже не ведаю, если это заремить и без этого работает - туда им и дорога (всмысле удалить это и забыть). Самая няшка это int_63h_entry, через int 63h и происходит общение с железкой. Вот ее надо разобрать и посмотреть что там за функции....
Чтобы понять рекурсию, сперва нужно понять рекурсию.
|
![]() |
![]() |
![]() |
#28 |
Участник клуба
Регистрация: 11.01.2010
Сообщений: 1,139
|
![]()
I-Gor
;================================== =========== mov dx, offset proc_3 ; процедура proc_3 будет вызываться если int 63h mov ax, 2563h ; AL = номер прерывания DS:DX --> новый обработчик прерывания int 21h ; прерывание 63h зарезервировано под прерывания пользователя mov dx, offset proc_1 ; процедура proc_1 будет вызываться если int 1Сh mov ax, 251Ch ; AL = номер прерывания DS:DX --> новый обработчик прерывания int 21h; прерывание 1Ch вызывается на каждый такт системного таймера, то есть 19,2 раза в секунду mov dx, 556h ; в DX общая длина программы в байтах mov cl, 4 shr dx, cl ; DX = объем резервируемой памяти в параграфах DX нужен для 31h функции 21h прерывания mov ax, cs; <--- можно удалить call proc_6 ; резидент при запуске выведит адрес CS на экран <--- можно удалить mov ax, 3100h ; завершить программу и оставить ее резидентной в памяти int 21h ;================================== ====================== что можно изменить? 556h=1366 байт -- это общая длина, вероятно, старой программы -- потом 1366 делят на 16 получают 85 параграфов для выделения в памяти места под резидент. Вообще резидент заканчивают так ;================================== ======================== mov dx,(end_of_prog - start + 15)/16; компилятор сам подсчитает это число и разделит на 16 поэтому здесь не нужны ; команды mov cl,4 / shr dx,cl mov ax,3100h int 21h end_of_prog:; адрес последнего байта end start ;================================== ========================= в теле программы в proc_2 есть shl bx,1 / shl bx,1 / shl bx,1 заменить три команды на shl bx,3 то же в proc_3 shl si,1 / shl si,1 / shl si,1 заменить на shl si,3 связано скорее всего с тем. что если при создании программы тип процессора не указывается, тогда считается, что это intel 8086, а в нем либо shl reg,1 либо shl reg,cl поэтому над .model tiny поставь .286 так же в теле программы достаточно много NOP'ов попробуй их закомментировать (; nop) по логике работы int 63h скорее всего используется однократно для инициализации или для завершения работы АЦП, а int 1Ch которое вызывается системой 19 раз в секунду -- это как раз для постоянного опроса каналов АЦП Последний раз редактировалось Mikl___; 24.11.2010 в 10:03. |
![]() |
![]() |
![]() |
#29 |
Форумчанин
Регистрация: 15.06.2010
Сообщений: 740
|
![]()
Mikl___
Я не согласен насчет вашей мысли, что int 63h вызывается однократно. Там же вон ясно видно, что в нем (обработчике int 63h) используется таблица переходов для вызовов подфункций. Вот так это выглядит: data_13 dw offset loc_20 ; Data table data_14 dw offset loc_21 data_15 dw offset loc_22 data_16 dw offset loc_26 data_17 dw offset loc_27 data_18 dw 0 ; Data table (indexed access) Таким образом, loc_20 .. loc_27 - это под-функции 63h прерывания. Вызов той или иной функции происходит в начале int 63h: xchg al,ah mov si,ax xchg al,ah and si,7 shl si,1 ; Shift w/zeros fill jmp word ptr cs ![]() Int 1ch конечно работает постоянно, и именно там и происходит обсчение с железкой (команды in / out), но я думаю, что этот обработчик всего-лишь собирает данные в каком-то буфере (массиве). А вот с помощью int 63h и какой-то его функции можно получить указатель на этот массив, и производить другие действия.
Чтобы понять рекурсию, сперва нужно понять рекурсию.
|
![]() |
![]() |
![]() |
#30 |
Регистрация: 08.11.2010
Сообщений: 6
|
![]()
Mikl___
«…из acp4_drv.asm получаем acp5_drv.asm из которого создается acp5_drv.com размером в 787 байт». Собрал acp4_drv.com и acp5_drv.com. Получились размерами соответственно 887 и 787 байт. Acp4 работает нормально. Не знаю, как АЦП’шник относится к acp5, но вот универовский комп, при попытке запустить после acp5 что-либо еще, виснет намертво. Не помогает даже <Ctrl – Alt – Del>. Приходится приводить комп в чувство Reset’ом. __________________ «Мотор был как настоящий, но не работал» (И. Ильф и Е. Петров: «Двенадцать стульев») |
![]() |
![]() |
![]() |
|
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Драйвер ISA устройства для DOS | I-Gor | Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM | 6 | 12.11.2010 06:49 |
Драйвер для hp laserjet 1010 для windows 7 | Юзер7 | Общие вопросы C/C++ | 6 | 04.08.2010 09:17 |
драйвер мыши для C++3.0 for dos | masta777 | Общие вопросы C/C++ | 3 | 20.06.2009 17:31 |
Разработка драйвер USB-HID устройства | _dx | Win Api | 5 | 10.06.2009 18:34 |
Для кадого ли устройства есть свой контроллер? | Elm0 | Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM | 6 | 21.06.2007 20:42 |