DOSовская прога на WinXP работает, в DOS зависает???

Тема в разделе "LANGS.C", создана пользователем Alice1144, 12 мар 2009.

  1. Alice1144

    Alice1144 New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    7
    Подскажите в чем проблема: есть прога на языке TurboС-3.0 с обработчиком прерывания от таймера (18 раз в секунду). По таймеру заполняется динамический список, в основной проге обрабатываются этот список. В WinXP все работало нормально, но возникла необходимость работать в DOS (системная дискета Win98), где этот же текст зависает (вроде бы на операторе new в обработчике прерывания, который или зависает или выдает NULL). Статический список не устраивает. В DOS прогу навсякий случай перекомпилил, не помогло.
    Упрощенный текст программы:

    Код (Text):
    1. #include <stdio.h>
    2. #include <dos.h>
    3. #include <conio.h>
    4.  
    5. #ifdef __cplusplus
    6.     #define __CPPARGS ...
    7. #else
    8.     #define __CPPARGS
    9. #endif
    10.  
    11. struct BuffList{                   //buffer obmena
    12.     unsigned int NumVK;
    13.     struct BuffList *next;
    14.     BuffList()  {NumVK=0; next=NULL;}
    15.     ~BuffList() {NumVK=0; next=NULL;}
    16. } start, *node, *first, *last, *ppp;
    17.  
    18. int cnt = 0;                        
    19. void interrupt get_out(__CPPARGS);
    20. void interrupt (*oldfunc)(__CPPARGS);
    21.  
    22. void main(void)
    23. { clrscr();
    24.   start.next = NULL;
    25.   node = first = last= &start;
    26.   oldfunc  = _dos_getvect(0x1c);
    27.   _disable();
    28.   _dos_setvect(0x1c,get_out);
    29.   _enable();
    30.   delay(100);
    31.   first=first->next;
    32.   while (1)
    33.   { if (first->next==NULL) continue;
    34.     node=first;
    35.     first=node->next;
    36.     // здесь должна быть длительная обработка информации
    37.     printf("drn",node->NumVK);
    38.     delete node;
    39.   }
    40.   _disable();
    41.   _dos_setvect(0x1c,oldfunc);
    42.   _enable();
    43. }
    44.  
    45. void interrupt get_out(__CPPARGS)  // обработка прерывания от таймера 18 раз в сек.
    46. { if (cnt==256) cnt=0;
    47.   last->next=new BuffList;
    48.   last=last->next;
    49.   last->NumVK=cnt++;
    50.   last->next=NULL;
    51. }
     
  2. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Alice1144
    Код (Text):
    1. #include <stdio.h>
    2. #include <dos.h>
    3. #include <conio.h>
    4.  
    5. #ifdef __cplusplus
    6.     #define __CPPARGS ...
    7. #else
    8.     #define __CPPARGS
    9. #endif
    10.  
    11. const unsigned int MAX_CNT = 256;
    12.  
    13. struct BuffList
    14. {
    15.   unsigned int NumVK;
    16.   struct BuffList *next;
    17.   BuffList()  { NumVK = 0; next = NULL;}
    18.   ~BuffList() { NumVK = 0; next = NULL;}
    19. } *first, *last;
    20.  
    21. unsigned int cnt = 0;                        
    22.  
    23. void interrupt get_out(__CPPARGS);
    24. void interrupt (*oldfunc)(__CPPARGS);
    25.  
    26. #if defined(__BORLANDC__)
    27. static c_break(void)
    28. {
    29.   _disable();
    30.   _dos_setvect(0x1c, oldfunc);
    31.   _enable();
    32.  
    33.   return 0;
    34. }
    35. #endif
    36.  
    37. void main(void)
    38. {
    39.   clrscr();
    40.  
    41.   first = last = new BuffList;
    42.   printf("first = %p, first->NumVK = %u\n", first, first->NumVK);
    43.  
    44.   oldfunc  = _dos_getvect(0x1c);
    45.   _disable();
    46.   _dos_setvect(0x1c, get_out);
    47.   _enable();
    48.  
    49. #if defined(__BORLANDC__)
    50.   ctrlbrk(c_break);
    51. #endif
    52.  
    53.   delay(100);
    54.  
    55.   while (1)
    56.   {
    57.     if (first->next == NULL) continue;
    58.  
    59.     struct BuffList *next = first->next;
    60.  
    61.     delete first;
    62.  
    63.     first = next;
    64.  
    65.     printf("first = %p, first->NumVK = %u\n", first, first->NumVK);
    66.   }
    67. }
    68.  
    69. void interrupt far get_out(__CPPARGS)
    70. {
    71.   if (cnt == MAX_CNT) cnt = 0;
    72.  
    73.   last->next  = new BuffList;
    74.   last        = last->next;
    75.   last->NumVK = ++cnt;
    76. }
    Запускал под wxpprorusp2, dos622 и rescue disk w98se - работает.
     
  3. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    компилировал так:
    bcc -ml foo.cpp
     
  4. Alice1144

    Alice1144 New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    7
    Проверил, в DOS от Win98 все равно не работает
     
  5. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Alice1144
    "не работает" что?
     
  6. Alice1144

    Alice1144 New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    7
    1. Зависает сразу на операторе "new" в обработчике прерывания.
    2. Иногда прерывание срабатывает, но "new" возвращает NULL, а потом все равно зависает.
     
  7. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Alice1144
    Перефразирую.
    "Не работает" какой код #1 или #2?
     
  8. Alice1144

    Alice1144 New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    7
    Все разобрался сам. Во все объявления надобавлял "huge", выбрал режим компилятора "huge" и все GOOD
     
  9. inviZ

    inviZ Сергей

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    92
    Адрес:
    Хабаровск
    Странное решение проблемы.
    Как-то в универе, когда тоже надо было в проге на Borland C (считай почти то же самое, что и Turbo C) под досом в обработчике прерывания вызывать функции C-шной библиотеки вроде printf и они не работали, я эту проблему решил после пары часов мучений примерно так:

    Код (Text):
    1. unsigned int savedSS;
    2. void interrupt handler()
    3. {
    4.     __asm {
    5.     mov ax,ss
    6.     mov savedSS,ax
    7.     push ds
    8.     pop ss
    9.     }
    10.  
    11.     ...  //код обработчика
    12.  
    13.     __asm  {
    14.     mov ax, savedSS
    15.     mov ss,ax
    16.     }
    17. }
    Короче говоря, оказалось, что SS должен был быть таким же, как и в основной программе, иначе вызовы CRT не работали (причем не просто не работали, а происходил полный ппц). А автоматически сгенерированный компилятором пролог обработчика прерывания, естественно, не меняет SS (что вполне логично), восстанавливает только DS.
     
  10. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Может вместо new попробуй malloc?
     
  11. Alice1144

    Alice1144 New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    7
    Проверил прогу с регистром SS: зависает, а с malloc я начинал и результат тот же что и с new