Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос про прерывания в паскале
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Diusha
Упрощенно прога:

Var xxx : pointer;
{$F+}
Procedure pr; interrupt;
begin
. . . . . .
end;
{F-}
BEGIN
getintvec($08, xxx);
setintvec($08, addr(pr));
. . . . . . .
END.

Вместо срандартного прерывания $08 назначена и выполняется моя процедурка pr, это работает. А как бы так сделать, чтобы кроме pr выполнялась и штатная ПП этого прерывания? (то биш в pr надо как-то вставить CALL (xxx) ???)
zltigo
Цитата(Diusha @ Aug 26 2008, 16:14) *
...то биш в pr надо как-то вставить CALL (xxx)

И пред этим pushf не забыть smile.gif, ибо iret. А вообще не лезте на 08h таймера, тем более Паскль... Учтите матчасть - 1Сh для юзеров.
И вообще, учитесь вопросы задавать, тем более на эмбеддерском форуме вдруг со своими боладопаскалями и писишкаим sad.gif.
Diusha
1. А Вы не могли бы написать с правильным синтаксисом про pushf и call?
2. Правильно ли я понял, что если 1С, а не 08, то call не нужен?
(сейчас откопал, что inicially он указывает на dummy iret)
zltigo
Цитата(Diusha @ Aug 26 2008, 16:47) *
1. А Вы не могли бы написать с правильным синтаксисом про pushf и call?

На борландячем паскале нет - нет желания вспоминать. На C++, даже борландячем, могу, на ASM могу...
Цитата
2. Правильно ли я понял, что если 1С, а не 08, то call не нужен?

Это уже штатный callback из 08h - вешайте на него свой обработчик прерывания и пользуйте.
AHTOXA
Я делал так:
Код
  GetIntVec($08,Save_08);
  SetIntVec($60,Save_08);
  SetIntVec($08,@Int_08);

и в прерывании:
Код
procedure Int_08;
begin
...
  Intr($60,Reg);
  Port[$20]:=$20;
end;

Но я перепрограммировал таймер, потому вынужден был висеть на 8м прерывании. Если такой нужды нет, то лучше 1C конечно.
Diusha
zltigo, AHTOXA,
спасибо!
zltigo
Цитата(AHTOXA @ Aug 26 2008, 18:09) *
SetIntVec($60,Save_08);

Только вот гарантий свободости 60h вектора в общем случае нет.
AHTOXA
Конечно. Но это не помешает работать нашей программеsmile.gif
zltigo
Цитата(AHTOXA @ Aug 26 2008, 20:09) *
Конечно. Но это не помешает работать нашей программеsmile.gif

Еще как помешает sad.gif - именно в качестве софтового прерывания его именно и используют, например Ethernet пакетный драйвер попытается общаться с обработчиком.
AHTOXA
Цитата(zltigo @ Aug 27 2008, 00:18) *
Еще как помешает sad.gif - именно в качестве софтового прерывания его именно и используют, например Ethernet пакетный драйвер попытается общаться с обработчиком.


Это настраивается. И в пакетном драйвере, и в программе.
Однако же не припоминаю конфликтов. У меня это работало под всеми дос от 3.3 до 7.0 и с несколькими драйверами сетевух.
zltigo
Цитата(AHTOXA @ Aug 26 2008, 20:31) *
Это настраивается. И в пакетном драйвере, и в программе.

Естествнно настраивается, если знать sad.gif что надо убираться с этого прерывания при использовании Вашей программы, можно и искать свободный, эмулировать jump,... многое, что можно...
Demeny
Не нужно придумывать лишнего, усложняя себе жизнь с дополнительным int 60h. Вот заведомо рабочий код с вызовом старого обработчика. Здесь также продемонстрирована подмена стека прерванной программы на собственный стек размером 2048 байт. Подмена стека нужна, если только предполагается запускать программы в защищённом режиме DPMI, иначе возникнет "Runtime Error 202"
Код
const
          MyStackSize = 2048;
type      
...
          TInterrupt = procedure (Flags: Word);
...
var
...
          { store original Interrupt service routine }
          OldIntHandler : TInterrupt;  
          
          SSp, SPp : word;
          MyStack : array[1..MyStackSize] of char;  
...


{==== Interrupt Handlers ====}

{$F+}

procedure MyIntHandler(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word);
                     interrupt;
begin
  asm
    mov SSp, ss
    mov SPp, sp
    mov ss, ax
    mov ax, offset MyStack
    add ax, MyStacksize-2
    mov sp, ax
  end;
  
.... {user defined code}....

  OldIntHandler(Flags);

  asm
    mov ss, SSp
    mov sp, SPp
  end;

  port[$20]:=$20;

end;

{$F-}

begin
...
getintvec($08,@OldIntHandler);
setintvec($08,@MyIntHandler);
...
end.
AHTOXA
Цитата(zltigo @ Aug 27 2008, 00:38) *
Естествнно настраивается, если знать sad.gif что надо убираться с этого прерывания при использовании Вашей программы


А какие проблемы настроить? Почему захват пакетным драйвером вектора 60h вас не смущает, а захват оного моей программой - смущает?


Цитата(zltigo @ Aug 27 2008, 00:38) *
можно и искать свободный, эмулировать jump,... многое, что можно...

Да много чего можно, кто же споритsmile.gif

Цитата(Demeny @ Aug 27 2008, 11:33) *
Вот заведомо рабочий код с вызовом старого обработчика.


А где pushf перед вызовом?

Цитата(Demeny @ Aug 27 2008, 11:33) *
Здесь также продемонстрирована подмена стека прерванной программы на собственный стек размером 2048 байт. Подмена стека нужна, если только предполагается запускать программы в защищённом режиме DPMI, иначе возникнет "Runtime Error 202"


Ничего не возникает и без этого.
zltigo
Цитата(AHTOXA @ Aug 27 2008, 10:11) *
А какие проблемы настроить? Почему захват пакетным драйвером вектора 60h вас не смущает, а захват оного моей программой - смущает?

Надо отличать минимально необходимые настройки от лишних сущностей.
Цитата
А где pushf перед вызовом?

В приведенном случае вызываемя функция вызывается с параметром smile.gif и декларирована, как обработчик прерывания.
Цитата
Ничего не возникает и без этого.

Слишком категорично smile.gif. Работает какая-то программа, имеет свой стек, на который и рассчитывает и вдруг ее кто-то прерывает и начинает пользовать ее стек sad.gif. Естественно, если Вы воспользуетесь счинанными байтами практически наверняка ничего не произойдет - редко стеки до байта рассчитывают, а вот если что-то будете более-менеее суровое в прерывании делать, то тогда свой стек надо ставить. Вопрос только как, ибо ASM вставки типа приведенных сносят оптимизацию борланду начисто.
Demeny
Цитата(AHTOXA @ Aug 27 2008, 12:11) *
А где pushf перед вызовом?

А зачем ? smile.gif Сохранить флаги и регистры и восстановить их - это задача старого обработчика, если он корректно написан (иначе как же он работал до этого).
Цитата(AHTOXA @ Aug 27 2008, 12:11) *
Ничего не возникает и без этого.

Не возникает, если Вы не используете локальные переменные в своём обработчике. У меня, например, в обработчике прерывания идёт гигантская работа с обилием локальных переменных, вызов других функий и т. п. Поэтому я сделал себе свой "локальный" стек. Без него у меня программа валится по "Runtime Error 202" (DPMI, защищённый режим).
zltigo
Цитата(Demeny @ Aug 27 2008, 10:38) *
Сохранить флаги и регистры и восстановить их - это задача старого обработчика, если он корректно написан (иначе как же он работал до этого).

Понятно sad.gif переписали прием откуда-то не думая... Обработчик прерывания возвращается по iret а не по ret и соответственно из стека извлекается еще и слово флагов. Посему оно должно быть туда помещено. В Вашем коде оно помещается передачей "функции" при вызове наследуемого параметра. Естественно функция-обработчик знать о нем не знает, но зато он попадает в стек...
Demeny
Цитата(zltigo @ Aug 27 2008, 12:49) *
Понятно sad.gif переписали прием откуда-то не думая...

Ну дык ... если сороконожка будет думать, как ходит её каждая нога - она вообще с места не сдвинется. smile.gif
А ресурс по Паскалю, откуда я это списал, и вправду неплохой http://pascal.sources.ru. Но то, что у меня это работает - истинная правда.
AHTOXA
Цитата(zltigo @ Aug 27 2008, 14:36) *
Надо отличать минимально необходимые настройки от лишних сущностей.


Настройки есть, как данность. Так что сущностей не добавляется.
[off]Меня удивляет вот что. Человек задал вопрос, на который вы не дали ответа, ибо у вас "нет желания вспоминать". Я дал готовый, проверенный вариант, и тут у вас неожиданно появилось это желание. Выходит, желание раскритиковать сильнее желания помочь? smile.gif
[/off]

Цитата(zltigo @ Aug 27 2008, 14:36) *
В приведенном случае вызываемя функция вызывается с параметром smile.gif и декларирована, как обработчик прерывания.

Это где? Вот это чтоль:
Код
type      
          TInterrupt = procedure (Flags: Word);
var
          OldIntHandler : TInterrupt;

? Какой же это обработчик?

Цитата(zltigo @ Aug 27 2008, 14:36) *
Слишком категорично smile.gif. Работает какая-то программа, имеет свой стек, на который и рассчитывает и вдруг ее кто-то прерывает и начинает пользовать ее стек sad.gif.


Естественно стек делается с рассчётом на обработчик прерывания. Это гораздо проще, чем заводить отдельный стек на обработчик. "Зачем плодить лишние сущности"? smile.gif
А моё возражение было насчёт того, что в DPMI надо делать что-то особенное со стеком, а то без этого не работает.



Цитата(Demeny @ Aug 27 2008, 14:38) *
Не возникает, если Вы не используете локальные переменные в своём обработчике.


Конечно же использую, и ничего не валится. Дело наверное в чём-то другом. Может банально не хватает стека.
zltigo
Цитата(AHTOXA @ Aug 27 2008, 12:15) *
Человек задал вопрос, на который вы не дали ответа, ибо у вас "нет желания вспоминать".

Если быть точным и прочитать написанное мной полностью, то нет желания вспоминать диалект Паскаля не имеющий актуальности с 90x годов. Помочь не оказывался, в том числе и конкретными кодом smile.gif. И обсуждать начал отнюдь не Паскаль, а подход к делу. Не нервничайте.
Цитата
? Какой же это обработчик?

Опять через слово читаете sad.gif это декларация обработчика.
Цитата
Естественно стек делается с рассчётом на обработчик прерывания.

Да нуsmile.gif А DOS, насамом деле вполне себе многозадачная система - драйвера, TSR-ы, само ядро...
C чего Вы взяли, что прерывать будут исключительно Вашу программу c "рассчитанным" стеком?
AHTOXA
Цитата(zltigo @ Aug 27 2008, 22:29) *
Помочь не оказывался, в том числе и конкретными кодом smile.gif.

Однако же не помогли sad.gif.
Цитата
И обсуждать начал отнюдь не Паскаль, а подход к делу. Не нервничайте.

Да я не нервничаю. Просто удивляюсь...
Цитата
Опять через слово читаете sad.gif это декларация обработчика.

Это вы через слово цитируете. Вы написали, что
Цитата
В приведенном случае вызываемя функция вызывается с параметром и декларирована, как обработчик прерывания.
(выделение моё). Вот я и поинтересовался, где она декларирована как обработчик прерывания.
Цитата
C чего Вы взяли, что прерывать будут исключительно Вашу программу c "рассчитанным" стеком?

Да, тут я был не прав. Посмотрел, почему же тогда у меня всё работало, оказывается я в прерывании работал только с глобальными переменными. Но продолжаю настаивать, что это не зависит от DPMI smile.gif
zltigo
Цитата(AHTOXA @ Aug 27 2008, 19:38) *
Однако же не помогли sad.gif.

Однако предлагал C/C++/ASM но никого не заинтересовал smile.gif
Цитата
(выделение моё). Вот я и поинтересовался, где она декларирована как обработчик прерывания.

Декларирована и используется как обработчик прерывания c фокусом ввиде запихивания в стек параметра. В борлянячем "С" можно и "естественее" c квалификатором interrupt.
Код
void interrupt (*old_xxx_vect)(...);

void interrupt xxx_handler(...)
{
......
    (*old_xxx_vect)();
.....
}

Цитата
Но продолжаю настаивать, что это не зависит от DPMI

Продолжайте настаивать, только зачем обращаясь ко мне smile.gif?
AHTOXA
Цитата(zltigo @ Aug 28 2008, 01:07) *
Декларирована и используется как обработчик прерывания c фокусом ввиде запихивания в стек параметра.

Вот именно что декларирована она как обычная процедура с параметром типа word. А используется как обработчик прерывания. Кстати, какие гарантии, что параметр будет передан на стеке?
Цитата
Продолжайте настаивать, только зачем обращаясь ко мне smile.gif?
Да тут больше нет никого, а понастаивать охотаsmile.gif
zltigo
Цитата(AHTOXA @ Aug 27 2008, 21:18) *
Кстати, какие гарантии, что параметр будет передан на стеке?

Для Борланда 100% - он только классическую передачу параметров поддерживает. Передача через стек это уже навороты более свежих сишных компиляторов типа Watcom, кроме того (или прежде всего?) даже навороченные компиляторы не имеют права воспользоваться передачей не через стек для "чужих" функций.
AHTOXA
Цитата(zltigo @ Aug 28 2008, 01:25) *
Для Борланда 100% - он только классическую передачу параметров поддерживает.


Вообще-то, начиная с какой-то версии, борландовский паскаль в качестве основного соглашения о вызовах использует "register". Но это не для доса уже конечноsmile.gif

Ну что ж, получается, что всё там будет работать. Но я бы всё ж для наглядности применил pushf+call smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.