Написать собственное прерывание - Assembler

Узнай цену своей работы

Формулировка задачи:

Здравствуйте! Задание такое: Нужно написать своё прерывание, генерируемое при нажатии клавиши Control+C. Программа при нажатии должна напечатать сообщение на экране. Я вроде программу написал, но она уходит в бесконечный цикл и не реагирует на ctrl+c; В чем может быть проблема? Заранее спасибо!
Листинг программы
  1. Stk SEGMENT STACK
  2. DB 256 DUP(?)
  3. Stk ENDS
  4. DATA SEGMENT
  5. KEEP_CS DW 0 ; для хранения сегмента
  6. KEEP_IP DW 0 ; и смещения прерывания
  7. schet dw 0
  8. message db 'hello',10,13,'$'
  9. Message2 db 'prerivanie',10,13,'$' ;строка для сообщения
  10. DATA ENDS
  11. CODE SEGMENT
  12. ASSUME CS:CODE, DS:DATA, SS:Stk
  13. rout proc far ;начало процедуры
  14. push ax ;сохраняем все изменяемые регистры
  15. push dx ;сохраняем все изменяемые регистры
  16. mov ah,9h ;функция установки вектора
  17. mov dx,offset message2 dx загружаем адрес сообщения Message2
  18. int 21h ;вывод строки на экран
  19. INC schet
  20. pop dx ;восстанавливаем регистры
  21. pop ax ;восстанавливаем регистры
  22. mov al,20h
  23. out 20h,al
  24. iret ;конец прерывания
  25. rout endp ;конец процедуры
  26.  
  27. main proc far
  28. push ds
  29. sub ax,ax
  30. push ax
  31. mov ax,data
  32. mov ds,ax
  33.  
  34. MOV AH, 35H ; функция получения вектора
  35. MOV AL, 23H ; номер вектора
  36. INT 21H
  37. MOV KEEP_IP, BX ; запоминание смещения
  38. MOV KEEP_CS, ES ; и сегмента
  39.  
  40. push ds
  41. mov dx,offset rout ;смещение для процедуры в DX
  42. mov ax,seg rout ;cs ;сегмент процедуры
  43. mov ds,ax ;помещаем в ds
  44. mov ah,25h ;функция установки вектора
  45. mov al,23h ;номер вектора
  46. int 21h ;меняем прерывание
  47. pop ds ;восстанавливаем ds
  48. cickl_m:
  49. mov dx, offset message
  50. mov ah, 9
  51. int 21h
  52. cmp schet, 05h
  53. jb cickl_m
  54. CLI
  55. PUSH DS ;DS будет разрушен
  56. MOV DX,KEEP_IP;подготовка к восстановлению
  57. MOV AX,KEEP_CS ;
  58. MOV DS,AX ;подготовка к восстановлению
  59. MOV AH,25h ;функция установки вектора
  60. MOV AL,23h ;номер вектора
  61. INT 21h ;восстанавливаем вектор
  62. POP DS ;восстанавливаем DS
  63. STI
  64. ret
  65. Main endp
  66. code ends
  67. end Main

Решение задачи: «Написать собственное прерывание»

textual
Листинг программы
  1. ;FASM-code
  2. ;обработка CTRL+C
  3. ;------------------------
  4. org 100h
  5. jmp start
  6.  
  7. mes1   db    13,10,'CTRL+C..',13,10
  8.  
  9. start: mov   ax,3301h       ;включить CTRL+C
  10.        mov   dl,1           ;
  11.        int   21h            ;
  12.        mov   ax,2523h       ;перехват его
  13.        mov   dx,new23       ;
  14.        int   21h            ;
  15.  
  16. @inp:  mov   ah,1           ;считать/вывести символ с клавы..
  17.        int   21h            ;
  18.        cmp   al,27          ;ESC?
  19.        jne   @next          ;нет
  20.        ret                  ;да
  21. @next: jmp   @inp           ;продлжить, если не ESC и не CTRL+С..
  22.  
  23. new23: mov   si,mes1        ;иначе: обработчик INT-23h
  24.        mov   cx,12          ;
  25. @23:   lodsb                ;..просто выводит мессагу
  26.        int   29h            ;
  27.        loop  @23            ;
  28.        iret                 ;выход из прерывания

Объяснение кода листинга программы

Список элементов кода на языке Assembler:

  1. org 100h - установка точки входа в программу
  2. jmp start - переход к метке start
  3. mes1 db 13,10,'CTRL+C..',13,10 - определение строки с сообщением
  4. start: mov ax,3301h - установка флага для обработки CTRL+C
  5. mov dl,1 - установка регистра dl в 1
  6. int 21h - вызов функции обработки прерывания
  7. mov ax,2523h - установка флага для перехвата прерывания
  8. mov dx,new23 - установка регистра dx для обращения к новому прерыванию
  9. int 21h - вызов функции обработки прерывания
  10. @inp: mov ah,1 - подготовка к чтению символа с клавиатуры
  11. int 21h - вызов функции обработки прерывания
  12. cmp al,27 - сравнение символа с клавишей ESC
  13. jne @next - если символ не равен ESC, перейти к следующей инструкции
  14. ret - выход из функции обработки прерывания
  15. @next: jmp @inp - повторение цикла, если символ не является ESC или CTRL+C
  16. new23: mov si,mes1 - установка регистра si для обращения к строке с сообщением
  17. mov cx,12 - установка регистра cx для подсчета количества выводимых символов
  18. @23: lodsb - чтение следующего символа из строки
  19. int 29h - вызов функции обработки прерывания для вывода символа
  20. loop @23 - повторение цикла до тех пор, пока не будет достигнут конец строки
  21. iret - выход из прерывания

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4.8 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы