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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 25.11.2010, 04:34   #31
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Tronix о подфункциях loc_20 и loc_27 можно сказать что это инициалиазация и завершение
;================================== ===========
data_13 dw offset loc_20 <-- инициализация
data_14 dw offset loc_21
data_15 dw offset loc_22
data_16 dw offset loc_26
data_17 dw offset loc_27 <-- восстановление di, si, es, ds и выход из процедуры
data_18 dw 0 <-- признак конца таблицы переходов
;===============================
proc_3 proc
...
cmp ah, 4; смотрим номер подфункции
ja loc_27; если больше 4 выходим из proc_3
xchg al, ah; меняем AH и AL местами
mov si, ax
xchg al, ah; восстанавливаем AX
and si, 7 ; обнуляем в SI все биты кроме 4 младших бит т.е. SI=AH
shl si, 1 ; в SI четное число меньше или равно 8 (0, 2, 4, 6, 8)
jmp cs : data_13[si] ; переход на loc_20, loc_21, loc_22, loc_26 или выход из процедуры proc_3
loc_20: xor ax,ax; ax=0
cli ; запрещаем прерывания
mov limit, ax ; limit = 0
mov count_chanal, ax ; count_chanal = 0
mov count2,ax ; count = 0
loc_21: mov word ptr word_19C, dx
mov word ptr word_19C+2,cx
sti ; разрешаем прерывания
jmp short loc_27
....
loc_27: pop di
pop si
pop ds
pop es
iret
proc_3 endp
;==========================

Последний раз редактировалось Mikl___; 25.11.2010 в 04:51.
Mikl___ вне форума Ответить с цитированием
Старый 25.11.2010, 04:45   #32
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

I-Gor
это можно было предположить, тогда давай изменять по частям для начала вопрос о числе 556h возможно что при длине резидента в 887 байт (377h) под кодом резидента оставлено место в 556h-337h=1DFh=479 байт для данных попробуй поменять только
;================================== ==============

mov dx,556h ; в DX общая длина программы в байтах
mov cl, 4
shr dx, cl ; DX = объем резервируемой памяти в параграфах
mov ax, cs
call proc_6 ; резидент при запуске выведит адрес CS на экран
mov ax, 3100h ; завершить программу и оставить ее резидентной в памяти
int 21h
end start
;================================== ==============
на
;===============================
mov dx,((end_of_prog-start)+0Fh)/16;556h ; в DX общая длина программы в параграфах
mov ax, cs
call proc_6 ; резидент при запуске выведет адрес CS на экран
mov ax, 3100h ; завершить программу и оставить ее резидентной в памяти
int 21h
end_of_prog:
end start
;================================== ===========
и скажи о результате
судя по времени выхода на форум ты где-то восточнее Новосибирска?

Последний раз редактировалось Mikl___; 25.11.2010 в 12:16.
Mikl___ вне форума Ответить с цитированием
Старый 26.11.2010, 06:13   #33
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

I-Gor
Последняя активность: Сегодня 10:50
Текущая активность: Смотрит тему Драйвер ISA устройства для DOS
Чего молчим?
Mikl___ вне форума Ответить с цитированием
Старый 26.11.2010, 07:07   #34
I-Gor
 
Регистрация: 08.11.2010
Сообщений: 6
Сообщение

1. Mikl___оказался прав. Резидент виснет из за команды mov dx, ((end_of_prog-start)+0Fh)/16. Самое смешное, что, если ее вообще убрать (что я и сделал, прочитав пост Tronix’а #27), и, до кучи, убрать процедуры sub_4 и sub_5 в листинге Sourcer’а, (proc_6 и IntToASCII по листингу IDA), то есть написать:
mov dx, offset proc_1
mov ax, 251Ch
int 21h
mov ax, 3100h
int 21h
то резидент работает нормально.

2. Прочитал посты Tronix’а #27 и #29, а также пост Mikl___’а #28 и #31, где говорилось об int 63h. Предположил, что, если это прерывание служит для передачи данных пользователю, то вызываться оно должно не однократно, а, скорее, эпизодически. А каким образом прерывание может передавать данные? Стандартный способ - через регистры процессора. Int 63h должно передавать через регистры либо собственно запрашиваемую инфу, либо ссылку на ее размещение в памяти.

Под подозрение попали регистры AX, BX, CX и DX. Остальные либо не используются, либо перед выполнением прерывания сохраняются в стеке, а при выходе восстанавливаются оттуда в первозданном виде инструкциями push/pop.

В итоге написал на QuickBASIC’е прогу, которая циклически вызывает int 63h, и выводит на экран состояние регистров при завершении обработки прерывания. Интересные получились вещи. Результат сильно зависит от состояния AH на момент вызова прерывания. Например, при вызове с AH=3 получаем на выходе: в AL – номер текущего канала измерения (от 0 до 7), в BX – результат аналого-цифрового преобразования для данного канала (что, собственно, и нужно было!), в CX – ноль, в DX не знаю что. Подробности во вложении. Там же скриншот фирменной тестовой программы. Интересная выявляется закономерность…

Предположу, что int 63h имеет несколько функций, определяемых значениями AH при запуске (не спроста AH в первую очередь проверяется). Хотелось бы выяснить их все (по крайней мере, узнать все допустимые значения АН).

И не нужно заморачиваться командой mov dx, ((end_of_prog-start)+0Fh)/16. Забыли о ней. Резидент даже в кастрированном виде (с удаленными процедурами вывода на экран начального адреса) без этой команды (и вообще без загрузки в DX чего-либо перед выполнением 31h функции int 21h) отлично работает. Не знаю, правда, почему.

Mikl___ говорил о таблице переходов int 63h, об инициализации и восстановлении. Вот об этом, пожалуйста, поподробнее.

3. Mikl___:
«…судя по времени выхода на форум ты где-то восточнее Новосибирска?»

Я живу в Татарстане (город Нижнекамск), в самой, что ни на есть средней полосе России. Просто, часто пробивает бессонница. Да и сигареты + черный кофе -- отличный допинг.
Вложения
Тип файла: zip int63h.zip (7.5 Кб, 8 просмотров)

Последний раз редактировалось I-Gor; 26.11.2010 в 07:52.
I-Gor вне форума Ответить с цитированием
Старый 26.11.2010, 11:02   #35
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Так Mikl___ же расписал там выше процедуру вызова подпрограмм в зависимости от номера функции в AH. Вот же она:
======================
proc_3 proc
...
cmp ah, 4; смотрим номер подфункции
ja loc_27; если больше 4 выходим из proc_3
....
shl si, 1 ; в SI четное число меньше или равно 8 (0, 2, 4, 6, 8)
jmp cs : data_13[si] ; переход на loc_20, loc_21, loc_22, loc_26 или выход из процедуры proc_3
======================
Таким образом, в AH могут быть значения от 0 до 4 (или даже до 3, потому как если AH=4, то происходит выход из обработчика). Значит в AH может быть от 0 до 3 - всего 4 подпрограммы.

Далее, я уже писал про Turbo Debugger и ту тестовую программу, что на Си написана. Можно ловить по вызывам int 63h и смотреть что и как.
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 26.11.2010, 13:07   #36
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

I-Gor
бросаешься из одной крайности в другую -- функция 31 прерывания 21h требует в DX размера резервируемой памяти в параграфах если он оказывается меньше 55h hiew32 показывает что
mov dx,2Eh;(((end_prog-start)+0Fh)/16) мы отвели памяти меньше чем требуется программе
mov ax,3100h
int 21h
тогда твоя программа намертво завешивает компьютер (ты сам пишешь что сброс только кнопкой RESET) ты совсем ничего не передаешь в DX надеясь на число которое там осталось после предыдущего вызова int 21h но в этом случае надеяться приходится только на аллаха всемилостивейшего и милосердного... Можешь проверить на каком этапе происходит завешивание твоего компьютера если в DX начнешь передавать число меньше 55h (от 2E до 55h) отнимая по 5
;============================
mov dx, offset proc_1
mov ax, 251Ch
int 21h
mov ax, 3100h
mov dx,55h<-- пусть будет пока так
int 21h
;==============================
изменения которые нужно вносить последовательно
в int_1Ch_entry замени
;============================
push ax ; new 1Ch vector to be used for specified interrupt
push bx
push cx
push dx
push es
push ds
push si
push di
push bp
...
pop bp
pop di
pop si
pop ds
pop es
pop dx
pop cx
pop bx
pop ax
iret
;==================
на
;==================
pusha
push es
push ds
....
pop ds
pop es
popa
iret
;========================
в int_1Ch_entry
;=======================
jz loc_2
jmp loc_9
nop
loc_2:
;==========================
на
;============
jnz loc_9
loc_2:
;=============================
в sub_1
shl bx,1
shl bx,1
shl bx,1
на shl bx,3
;=========
в int_63h_entry
jbe loc_19 ; Jump if below or =
jmp loc_27
loc_19: xchg al,ah
mov si,ax
xchg al,ah
and si,7
shl si,1 ; Shift w/zeros fill
jmp word ptr cs : data_13[si]
;================================== ================
на
ja loc_27
loc_19: mov si,ax
and si,700h
shr si,7
jmp word ptr cs : data_13[si]
;================================== ===============================
в int_63h_entry
mov data_5,di
jmp short loc_27
db 90h
loc_27: pop di
pop si
pop ds
pop es
iret ; Interrupt return
int_63h_entry endp
на
mov data_5,di
loc_27: pop di
pop si
pop ds
pop es
iret
int_63h_entry endp
в int_63h_entry
shl si,1
shl si,1
shl si,1
на shl si,3
процедура sub_2 вызывается только один раз поэтому имеет смысл перенести ее на место вызова в int_1Ch_entry
вместо
;===============================
mov dx,[bx]
call sub_2
add bx,14h
;=================================
писать
;================================== =
mov dx,[bx]
;call sub_2
and al,27h
out dx,al
or al,8
out dx,al
add bx,14h
;================================== ==========
а sub_2 убрать совсем
и если все будет работать нормально поставь перед вызовом sub_2
не mov dx,[bx] а mov dx,320h

Последний раз редактировалось Mikl___; 26.11.2010 в 13:36.
Mikl___ вне форума Ответить с цитированием
Старый 27.11.2010, 02:37   #37
I-Gor
 
Регистрация: 08.11.2010
Сообщений: 6
Сообщение

Mikl___
К вопросу о количестве параграфов памяти под резидент.

Ну, на Аллаха надеяться в данном случае особого смысла нет. Тем более, что я не мусульманин...
Итак, 556h, или 1366, байт – это общая длина (код + данные) оригинального acp3_drv. Правда, менеджер резидентных программ в Volkov Commander, а также Microsoft Diagnostics почему-то в один голос утверждают о 1584 байтах. Предположим, что все-таки 1366. Из них под сегмент кода (end_of_prog-start) приходится 887 байт, а еще 15 байт нужны, если при делении на 16 число параграфов не получится целым.. Вычитаем: 1366 – 887 -15. Итого выходит 464 (1D0h) байта под данные.
Далее изменяем исходник резидента по своему усмотрению, а в конце пишем:

mov dx,((end_of_prog-start)+0Fh+1D0h)/10h
; 1D0h – максимальная длина сегмента данных
mov ax, 3100h
int 21h
end_of_prog:
end start

Компилируем. Запускаем. Все OK! Таким макаром удалось «оживить» присланный тобою acp5_drv.asm. Собранный com-файл похудел до 787 байт и заработал отлично. После этого я сделал в нем изменения, о которых ты говорил в предыдущем посте. Работать с acp_5 оказалось удобнее, чем с листингом Sourcer’а, т. к. часть указанных замен уже была сделана. В результате из acp5_drv.asm получился acp6_drv.asm. Соответствующий ему .com сбросил вес уже до 769 байт. Работает корректно, за исключением последнего пункта: если в разделе a06 команду mov dx, [bx] заменить на mov dx, 320h, то резидент только симулирует опрос, передавая нули для всех каналов измерения.

И еще. В acp5_drv.com, например, hiew сообщает:
mov dx,0004F
mov ax,03100
int 021
То есть проге должно быть выделено 4F параграфов, или 1264 байта, памяти, а вот MSD и Волков дружно говорят о 1504. Подобная ситуация была и с оригинальным резидентом (см. выше). Почему, интересно, так?
Вложения
Тип файла: zip acp6_drv.zip (3.0 Кб, 6 просмотров)

Последний раз редактировалось I-Gor; 27.11.2010 в 23:32.
I-Gor вне форума Ответить с цитированием
Старый 29.11.2010, 07:18   #38
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

I-Gor
1) хотя нужно было (begin - start)+0Fh так как код стартующий наш резидент и устанавливающий адреса процедур обработчиков прерываний 1Ch и 63h уже отработали и в памяти в качестве резидента не нужны
2) попробуй отключить обработчик 1Ch прерывания и отпишись, что из этого получится
;mov dx, offset int_1Сh_entry
;mov ax, 251Ch
;int 21h

Последний раз редактировалось Mikl___; 29.11.2010 в 13:09.
Mikl___ вне форума Ответить с цитированием
Старый 29.11.2010, 10:15   #39
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Igor Ilyin (I-Gor)
;================================== =============================
;при вызове с AH=3 получаем на выходе: в AL - номер текущего канала измерения
;(от 0 до 7), в BX - результат аналого-цифрового преобразования для данного
;канала (что, собственно, и нужно было!), в CX - ноль, в DX не знаю что.
a38: mov al,0FFh
cli
mov di,count_chanal
cmp di,limit
jz short exit3
mov si,di
shl si,3
add si,offset n5; si := [count_chanal * 8 + n5]
mov ax,[si];в AL - номер текущего канала измерения от 0 до 7
mov bx,[si+2];в BX - результат АЦ-преобразования для данного канала
mov dx,[si+4];в DX - не знаю что
mov cx,[si+6];в CX - ноль
inc di
and di,7; di циклически увеличивается от 0 до 7
mov count_chanal,di
exit3: pop di
pop si
pop ds
pop es
iret
proc_3 endp
;================================== ====================
ищем по тексту n5 и находим
;================================== ===================
proc_2 proc
mov si,limit
mov bx,si
shl bx,3
add bx,offset n5 ; bx = [limit *8 + n5]
mov [bx],dx;номер текущего канала измерения от 0 до 7
mov [bx+2],ax;результат АЦ-преобразования для данного канала
.386
mov eax,dword_19C;наверное, номер измерения - старшая половина в CX, младшая в DX
mov [bx+4],eax; то, что потом при вызове AH=3 int 63h получат через CX и DX
inc si
and si,7
mov limit,si
mov di,count_chanal
cmp si,di
jnz short exit2
inc di
and di,7
mov count_chanal,di
exit2: retn
proc_2 endp
;================================== ====================
получается в proc_2 через AX и DX передают в память номер канала и результат измерения

и опиши, что возвращается в AX, BX, CX, DX при вызове AH=0 int 63h; AH=1 int 63h; AH=2 int 63h

Последний раз редактировалось Mikl___; 29.11.2010 в 12:17.
Mikl___ вне форума Ответить с цитированием
Старый 29.11.2010, 13:07   #40
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Igor Ilyin (I-Gor)
К вопросу о количестве параграфов памяти под резидент передаваемых в регистре DX
Функция с кодом 31h имеет два параметра: необязательный параметр код возврата, используемый для указания состояния при выходе из подпрограммы, и обязательный параметр, представляющий собой значение размера блока памяти в параграфах, которое остается распределенным за процессом. При вызове функции MS-DOS резервирует запрошенное количество памяти, начиная с адреса PSP (сегмента программного префикса). Это происходит почти также как и при вызове функции "Модифицировать блок распределенной памяти" с адресом PSP и требуемым размером. В случае функции "сохранить процесс" MS-DOS знает, что блок, размер которого должен быть модифицирован, начинается с адреса PSP, так что параметр не требуется.
Листинг 3-4. Функция с кодом 31h - "Сохранить процесс"
----------------------------------------------------------------
.code
ORG 0 <-- а не 100h как у нас!
seg_org equ $
ORG 100h
start: jmp begin
...

mov dx,(last_byte - seg_org + 15) / 16
mov ah,31h ; сохранить процесс
int 21h ; вызов MS-DOS
...
last_byte:
end start
под hiew32 mov dx,40h а в твоем варианте mov dx,4Dh наверное с 40h параграфами резидент будет работать и теперь ясно как формируется это число
посмотрел внимательно: offset seg_org = 0 offset begin (с учетом начального ORG 0) = 3D9h 3D9h+0Fh=3E8h 3E8h/10h=3Eh
вот такая арифметика: mov dx,(offset begin + 0Fh)/16

Последний раз редактировалось Mikl___; 29.11.2010 в 15:21.
Mikl___ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 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