Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Работа для программиста > Фриланс
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.11.2010, 07:13   #21
I-Gor
 
Регистрация: 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.
I-Gor вне форума Ответить с цитированием
Старый 20.11.2010, 01:51   #22
I-Gor
 
Регистрация: 08.11.2010
Сообщений: 6
Вопрос

Немного изменил листинг Tronix’а, чтобы он мог собираться TASM’ом. Вновь собранный com-файл работает корректно, хотя при этом неадекватно много «весит» (2030 байт вместо 887 байт «в оригинале»). С чем это может быть связано? Заранее благодарен.

Использовал TASM 5.0. Строка компиляции: tasm /zn acp.asm. Строка компоновки: tlink /t acp.obj acp. Во вложении для справки исходные данные и полученный результат.
Вложения
Тип файла: zip Acp.zip (5.8 Кб, 7 просмотров)
I-Gor вне форума Ответить с цитированием
Старый 20.11.2010, 14:43   #23
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Не знаю как там у вас так получилось. Вот щаз взял, отрезал шапку до строки .286c и компильнул - размер байт в байт получился с исходником.
TASM у мну представляется так: Turbo Assembler Version 4.1
Компилил так:
tasm ACP3_DRV.ASM
tlink /t ACP3_DRV.obj

На выходе получил ACP3_DRV.COM размером в 887 байт.
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 23.11.2010, 14:00   #24
Mikl___
Участник клуба
 
Регистрация: 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 байт. Посмотри, если с ним твой АЦП работает нормально, тогда программу можно еще уменьшить, а с маленькой программой разбираться проще
Файлы не цепляются, куда выложить?
Mikl___ вне форума Ответить с цитированием
Старый 23.11.2010, 14:36   #25
I-Gor
 
Регистрация: 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.
I-Gor вне форума Ответить с цитированием
Старый 23.11.2010, 14:49   #26
I-Gor
 
Регистрация: 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.
I-Gor вне форума Ответить с цитированием
Старый 23.11.2010, 17:48   #27
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Я вообще не понимаю, зачем вы смотрите эти процедуры? Зачем на них вообще тратить время? Выкинули и забыли про них. Что такое
mov dx,556h
mov cl,4
shr dx,cl
я тоже не ведаю, если это заремить и без этого работает - туда им и дорога (всмысле удалить это и забыть).

Самая няшка это int_63h_entry, через int 63h и происходит общение с железкой. Вот ее надо разобрать и посмотреть что там за функции....
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 24.11.2010, 05:36   #28
Mikl___
Участник клуба
 
Регистрация: 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.
Mikl___ вне форума Ответить с цитированием
Старый 24.11.2010, 16:19   #29
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 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 csata_13[si] ; вот тут прыгаем на одну из процедур в таблице.

Int 1ch конечно работает постоянно, и именно там и происходит обсчение с железкой (команды in / out), но я думаю, что этот обработчик всего-лишь собирает данные в каком-то буфере (массиве). А вот с помощью int 63h и какой-то его функции можно получить указатель на этот массив, и производить другие действия.
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 25.11.2010, 04:27   #30
I-Gor
 
Регистрация: 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’ом.

__________________
«Мотор был как настоящий, но не работал» (И. Ильф и Е. Петров: «Двенадцать стульев»)
I-Gor вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Драйвер 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