Я потерял iretd

Тема в разделе "WASM.ASSEMBLER", создана пользователем Vilco, 20 авг 2007.

  1. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Доброго времени суток.
    Я думал все современные компиляторы поддерживают полный набор команд встроенного ассемблера... gcc (v 3.4.2 может быть старая?) при попытке скомпилить код с командой iretd gcc говорит "no such instruction: 'iretd'". Что с этим делать? Или, может быть, можно как-нибудь по другому?
     
  2. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Vilco
    iretl
     
  3. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    или просто
    iret
     
  4. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    iretl = iretd?=)
    Почему-то плохо както работает, bochs пишет
    IRET PROTECTED
    exception(0x01)
    interrupt(): ...
    interrupt(): gate descriptor is not valid sys seg
    Как должна выглядеть процедура обработки прерывания на Си и что за 'gate descriptor is not valid sys seg'?
     
  5. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Vilco
    Глобальные вопросы, скажем прямо. Процедура обработки прерывания, в принципе, не отличается от обычной процедуры. Разве что 'iret' в конце стоит. Дальше все зависит от того, что ты делаешь. Возможно, необходимо сохранить регистры, чтобы обработчик их не испортил, возможно, необходимо вытолкнуть из стека код ошибки, возможно послать EOI контроллеру прерываний. В общем, опиши более подробно, что тебе требуется.

    Bochs, по-видимому ругается на дескриптор в IDT. Скорее всего на тип дескриптора. В IDT могут жить лишь шлюзы ловушек, шлюзы прерываний и шлюзы задач. Чтобы сказать точнее надо увидеть код.
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    в gcc афаик есть модификатор функции. interrupt что-ли.
     
  7. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    да, синтаксис AT&T
    имхо, первичный обработчик нужно писать на ассемблере, а уж из него вызывать процедуру на С
    скорее всего компилятор генерирует
    Код (Text):
    1. push ebp
    2. mov ebp, esp
    в начале твоего обработчика, а iretd вызывается до pop ebp
    т. е
    Код (Text):
    1. void handler() {
    2.     __asm__("iretl")
    3. }
    Код (Text):
    1. handler:
    2.     pushl %ebp
    3.     movl %esp, %ebp
    4.     iretl
    5.     popl %ebp
    6.     ret
     
  8. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
     
  9. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Хм,
    Дело на 99% не в этом. Потому что до замены адреса обработчика (2 первых и 2 последних байта вроде) дескриптор нормально, корректно функционировал. Как только я ставлю туда си-процедуру - бред какой-то получается.
    Похоже так оно и есть=( Я натравил на бинарник еду, пролог действительно есть, а эпилог получается за iret. Получается что нужно просто вручную вытащить ebp из стека и остальное оставить как есть?
    Ах да, про interrupt где почитать?)
    Спасибо
     
  10. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
  11. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    Вроде разобрался, но как-то коряво получается. Самому приходится стек чистить от временных переменных - каждый раз смотреть чё он там скомпилил(.
    Если ли какой-нибудь аналог __declspec(naked) в gcc? Как нить его можно включить (а то по ссылке в списке тоже не вижу x86, а при попытке вставить гцц пишет 'naked' attribute directive ignored)?
     
  12. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    поэтому я и говорю
    пиши минимальный обработчик на ассемблере и вызывай с него сишную функцию
     
  13. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    __attrubute__ ((pure)) попробуй.
     
  14. Vilco

    Vilco Vitaly

    Публикаций:
    0
    Регистрация:
    5 мар 2007
    Сообщения:
    190
    Адрес:
    Nsk, Russia
    По-моему, это не то совсем... Описание говорит об этом, но я на всякий случай воткнул атрибут pure, компилер съел, а пролог-эпилог так и остался...
    Ладно пойду асм воткну...
    Edited: всем спасибо, можно закрывать. С помощью си так и не получилось на gcc сделать...
     
  15. KoliaZP

    KoliaZP New Member

    Публикаций:
    0
    Регистрация:
    20 янв 2009
    Сообщения:
    8
    Та же проблема...
    Действовал согласно http://wiki.osdev.org/Interrupt_Service_Routines
    получилось такое:
    Код (Text):
    1. .globl int_timer
    2.  
    3. int_timer:
    4.     pushal
    5.     call _int_timer
    6.     popal
    7.     iret
    bochs пишет следущее
    Код (Text):
    1. 00013627163e[DEV  ] write to port 0x0007 with len 4 ignored
    2. 00013627169i[CPU0 ] BxError: instruction with opcode=0xff
    3. 00013627169i[CPU0 ] mod was c0, nnn was 7, rm was 7
    4. 00013627169i[CPU0 ] WARNING: Encountered an unknown instruction (signalling illegal instruction)
    5. 00013627169e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
    6. 00013627169e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
    7. 00013627169i[CPU0 ] protected mode
    8. 00013627169i[CPU0 ] CS.d_b = 32 bit
    9. 00013627169i[CPU0 ] SS.d_b = 32 bit
    10. 00013627169i[CPU0 ] | EAX=00100800  EBX=0002cea0  ECX=0000000c  EDX=0010004f
    11. 00013627169i[CPU0 ] | ESP=001ffff8  EBP=00067eac  ESI=00053b25  EDI=00053b2a
    12. 00013627169i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf af pf cf
    13. 00013627169i[CPU0 ] | SEG selector     base    limit G D
    14. 00013627169i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
    15. 00013627169i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
    16. 00013627169i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
    17. 00013627169i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
    18. 00013627169i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
    19. 00013627169i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
    20. 00013627169i[CPU0 ] |  GS:0010( 0002| 0|  0) 00000000 000fffff 1 1
    21. 00013627169i[CPU0 ] | EIP=0002ceac (0002ceac)
    22. 00013627169i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
    23. 00013627169i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
    24. 00013627169i[CPU0 ] >> (invalid)  : FFFF
    25. 00013627169e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
    EIP=0002ceac - я так понял, шо раз он сюда попал то при выходе из прерывания eip содержал неправильное значение...
     
  16. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    А можно IDT/GDT увидеть? Как я понял из лога, происходит исключение 6 (#UD), а обработчики не настроены.
     
  17. KoliaZP

    KoliaZP New Member

    Публикаций:
    0
    Регистрация:
    20 янв 2009
    Сообщения:
    8
    Код (Text):
    1. exception(): 3rd (13) exception]
    с IDT и GDT все в порядке, если код изменить так:
    Код (Text):
    1. pushal
    2. popal
    3. hlt
    4. iret
    или внутри функции _int_timer поставить for(;;); то все работает, как и должно...
     
  18. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Код (Text):
    1. 00013627163e[DEV  ] write to port 0x0007 with len 4 ignored
    2. 00013627169i[CPU0 ] BxError: instruction with opcode=0xff  <--Началось все здесь.
    3. 00013627169i[CPU0 ] mod was c0, nnn was 7, rm was 7
    4. 00013627169i[CPU0 ] WARNING: Encountered an unknown instruction (signalling illegal instruction) <--Bochs понял, что с инструкцией беда.
    5. 00013627169e[CPU0 ] interrupt(): gate descriptor is not valid sys seg <--Продолжение банкета.
    6. 00013627169e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
    IDT можно посмотреть командой info idt. И раз используется Bochs, почему бы не посмотреть по шагам что происходит? Либо код покажите.
     
  19. KoliaZP

    KoliaZP New Member

    Публикаций:
    0
    Регистрация:
    20 янв 2009
    Сообщения:
    8
    IDT не виновато... Но все же:
    Код (Text):
    1. void __idt::edit(unsigned char vector,void (*func)(void), unsigned char type)
    2. {
    3.     unsigned char* idt_table=(unsigned char*)IDT_TABLE;
    4.     unsigned char rec[8];
    5.     rec[0]=(unsigned int)func & 0xFF;
    6.     rec[1]=((unsigned int)func & 0xFF00)>>8;
    7.     rec[2]=SYS_CODE_SELECTOR;
    8.     rec[3]=0;
    9.     rec[4]=0;
    10.     rec[5]=type;
    11.     rec[6]=((unsigned int)func & 0xFF0000)>>16;
    12.     rec[7]=((unsigned int)func & 0xFF000000)>>24;
    13.     for(int i=0;i<8;*((unsigned char*)(IDT_TABLE+vector*8+i))=rec[i++]);
    14. }
    Код (Text):
    1. edit(0x8,&int_timer,0x8E);
    Проблема в том, шо он начал исполнять инструкцию по адресу 0002ceac, туда он не должен попадать. Ядро заканчивается гораздо раньше.
     
  20. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Пардон, я имел в виду код ф-ии _int_timer.