Перехват прерываний, без прерываний :)

Тема в разделе "WASM.ASSEMBLER", создана пользователем spa, 21 фев 2007.

  1. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    Надо вызвать прерывания, не используя int xx , вроде информации дофига, но она какаето не внятное, хотя мне всеголиш надо получить адресс фунции обрабодчика, и там еще коешто...
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    SPA
    адреса обработчиков хранятся в первом килобайте памяти.
    адрес обработчика равен номер_прерывания*4. (каждый обработчик - 4 байта: сегмент:смещение)

    Код (Text):
    1. INTERRUPT_NO equ C
    2.  
    3. ; Обнуление DS
    4. XOR    AX,AX
    5. MOV    DS,AX
    6.  
    7. ; Получение вектора
    8. MOV    SI, INTERRUPT_NO
    9. SHL    SI,02
    10. MOV    DI,[SI]
    11. MOV    SI,[SI+02]
    12. MOV    ES, DI
    13.  
    14. ; Вызов
    15. PUSH CS
    16. PUSH __ret
    17. PUSHF
    18. JMP ES:[SI]
    19. __ret:
    Ну если я ниче не напутал :)
    Я руководствовался тем, что вектор содержит в себе части адреса - сначала сегмент, потом смещение (насколько я помню) и тем, что при вызове прерывания в стек пихаются сегмент, смещение, флаги.

    Поскольку кодинг под ДОС у меня был давно, я мог ошибиться +) поправьте если что не так
     
  3. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    ну, грузи адрес таблицу idt, потом читай адрес обработчика, потом pushf/call IntHandler.
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Мдя. попробовал написать вывод строки:

    Код (Text):
    1. jmp start
    2.  
    3. hello db 'Hello, WORLD!!',13,10,'$'
    4.  
    5. start:
    6.  
    7. ; Обнуление DS
    8. PUSH  DS
    9. XOR   AX,AX
    10. MOV   DS,AX
    11.  
    12. ; Получение вектора
    13. MOV   SI, 21h
    14. SHL   SI,02
    15. MOV   DI,[SI]
    16. MOV   SI,[SI+02]
    17. MOV   ES, DI
    18.  
    19. ; Восстановление DS
    20. POP   DS
    21.  
    22. ; Показ строки
    23. MOV   AH, 9
    24. MOV   DX, offset hello
    25.  
    26. ; Вызов
    27. PUSH  CS
    28. PUSH  __ret
    29. PUSHF
    30. JMP   ES:SI
    31. __ret:
    32.  
    33. int    20h
    Чето нихрена не выводит :)
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    ойой, я почему-то решил, что надо под DOS :)))
    извиняюсь %)
    Я неизлечим =\
    Ну если тебе под защищенный режим, тогда SIDT тебе в помощь.

    зы. пойду ченить успокаивающее попью. ДОС меня преследует (:
     
  6. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Напутал :)
    pushf первым писать надо.
    А вообще у тебя изврат ещё тот.
    Проще писать как n0name говорит.
    Код (Text):
    1. pushf
    2. call Int_Handler
     
  7. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    n0name
    Надо в режиме реальной адрессации :)

    PS нуже самый короткий вариант, прерывания можно вызывать просто call адресс обработчика
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    SPA
    вау, если реальная, тогда читай, что я писал выше =)
    только правь на pushf / call, где я вызываю прерывание )
     
  9. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    Great
    Да там call круто, вызываеться :)


    ЗЫ это мин вариант, вроде не чего лишнего
     
  10. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    Great
    Ага кстати нехрена не выводи, а fasm ругаеться на call [ES:SI]
     
  11. Ultrin Faern

    Ultrin Faern New Member

    Публикаций:
    0
    Регистрация:
    25 июн 2006
    Сообщения:
    170
    А ничего работать и не будет :Р

    Смысл команды jmp\call [es:si] - предать управление по адресу, который находится по адресу es:si. Если в es:si - адрес куда нужно передать управление, то реально управление передается на адрес, который получается разглядыванием первых 2\4\6 (в зависимости от самой команды jmp\call) байт команд самого обработчика прерывания. :))

    А команда jmp es:si не прокатит, так как
    es - всего лишь префикс команды для выбора сегмента адреса отличного от по-умолчанию для этой адресации. А в данном случае адрес не выбирается - берется тоько значение регистра.
    jmp si - как ни странно кодируется вроде в FEH 11100110B (near) и даже FEH 11101110B (far). Но смысл теряется, куда передавать при far вызове, если в регистре всего 16 бит, а far требует 32 бит?
     
  12. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    И возникае вопрос, и чтоже предпринять :)
     
  13. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ступил....

    Код (Text):
    1. ; данные
    2. pointer dd ?
    3.  
    4. ; переход
    5. mov ax,es
    6. mov word ptr [pointer], ax
    7. mov word ptr [pointer+2], si
    8. jmp dword ptr [pointer]
    как-то так...

    блин меня сегодня плющит не по-детски. такую бредятину несу...
     
  14. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    SPA

    Вот тебе код в RM

    Код (Text):
    1. .286
    2. CSEG segment
    3. Assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
    4.  
    5. org 100h
    6.  
    7. begin:
    8.  
    9. lea ax, main
    10. jmp short main
    11.  
    12. int_9 proc far ; процедура обработки int 9h
    13.  
    14. pushf                      
    15. pusha
    16. push es
    17. push ds    
    18.  
    19. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    20.  
    21. push 0B800h
    22. pop es
    23. mov ah,31
    24. mov al,1
    25. mov di,0
    26. mov es:[di],ax
    27.  
    28. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    29.  
    30. pop ds
    31. pop es
    32. popa
    33. popf
    34.  
    35. db 0EAh ; jmp far
    36. o_int_9 dw ?
    37. s_int_9 dw ?
    38.  
    39. int_9 ENDP
    40.  
    41. RES_END:
    42.  
    43. main:
    44.  
    45. push cs
    46. pop ds
    47.  
    48. cli
    49. push 0
    50. pop es
    51. mov dx,es:[09h*4]
    52. mov bx,es:[09h*4+2]
    53. mov s_int_9,bx
    54. mov o_int_9,dx
    55. sti
    56.  
    57. cli
    58. push cs
    59. pop ds    
    60. mov ax,0h
    61. mov es,ax
    62. mov dx,offset int_9
    63. mov es:[09h*4],dx
    64. mov es:[09h*4+2],ds
    65.  
    66. sti
    67.  
    68. mov dx,offset RES_END
    69. int 27h
    70.  
    71. CSEG ends
    72. end begin
     
  15. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    lukash дык а где здесь программный вызов обработчика?
    Это просто замена вектора на свой.
    Вот простейший код для просграммного вызова обработчика прерывания IntN.
    Код (Text):
    1. xor   ax,ax
    2. mov   ds,ax
    3. pushf
    4. call  far ds:[IntN*4]
     
  16. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    cppasm

    Я привел код, который заменяет вектор на свой, но ведь в обработчике прерывания я вызываю старый обработчик, что и надо было сделать (только через call а не jmp)

    Код (Text):
    1. db 0EAh ; jmp far
    2. o_int_9 dw ?
    3. s_int_9 dw ?
    но перед этим сохраняю значение сегмент/смещение

    Код (Text):
    1. cli
    2. push 0
    3. pop es
    4. mov dx,es:[09h*4]
    5. mov bx,es:[09h*4+2]
    6. mov s_int_9,bx
    7. mov o_int_9,dx
    8. sti
    Это то же, что и преведеный выше твой код, просто после jmp в обработчик уже не попадаем.

    Да, я немного не то написал, просто название топика

     
  17. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Да я согласен :)
    Просто смотря что автору топика надо.
    Если вызвать старый обработчик из своего - то тогда оба варианта подойдут.
    А если вызвать обработчик из своего кода, т.е. просто заменить int xx то твой вариант не подойдёт.
     
  18. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    Надо просто заменить int xx
    Но все впринцепе я разобрался, осталась одна проблемка, надо сделать чтобы он переходил по на прерывание которое в cx, но не могу написать call ds:cx скажите как надо.
     
  19. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    каэшн, это в протектед моде можно юзать для адресации любые регистры.
    в 16 битном режиме адресация косвенная жестко фиксирована, в смысле какие регистры и как в ней можно использовать.
    насколько я помню, это
    [ bx/bp + si/di + OFFSET ]
     
  20. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    В cx надо номер прерывание, как можно енто уменьшить, а то помоему както огромно :dntknw:
    Код (Text):
    1. inter:
    2.          push ds
    3.          xor   bx,bx
    4.          mov   ds,bx
    5.          pushf
    6.          push ax
    7.          mov ax,cx
    8.          mov bx,4
    9.          mul bx
    10.          mov bx,ax
    11.          pop ax
    12.          call far [ds:bx]
    13.          pop ds
    14.          ret