текст программы (1071547), страница 3
Текст из файла (страница 3)
1 532 ;командной строки строки с текущим символом параметра ( символ параметра
1 533 ;не изменился )
1 534 0407 4E dec si
1 535 0408 EB F4 jmp @@Compare_Again
1 536
1 537 040A @@Match_Found:
1 538 ;Если текущие символы в сравниваемых строках совпадают
1 539 ;проверяем, а не кончилась ли строка с параметром
1 540 040A 80 3C 00 cmp [ BYTE PTR ds:si ], 00h
1 541 040D 75 1D jne @@Check_Command_Line_End ; если не конец параметра, то проверяем
1 542 ; конец командной строки
1 543 ;Да - параметр закончился
1 544 ;Теперь дополнительно проверяем командную строку, чтобы убедиться, что то,
1 545 ;что мы нашли является отдельным словом ( те например " /U VANO" ),а не частью
1 546 ;какого-то другого параметра ( например "/UNINSTALL VANO" )
1 547 040F 26: 80 3D 20 cmp [ BYTE PTR es:di ], ' ' ;<-пробел
1 548 0413 74 22 je @@Parameter_Found
1 549 0415 26: 80 3D 2F cmp [ BYTE PTR es:di ], '/' ;<-начало следующего параметра
1 550 0419 74 1C je @@Parameter_Found
1 551 041B 26: 80 3D 2D cmp [ BYTE PTR es:di ], '-' ;<-начало следующего параметра( возможно )
1 552 041F 74 16 je @@Parameter_Found
1 553 0421 26: 80 3D 00 cmp [ BYTE PTR es:di ], 00h ;<-конец командной строки
1 554 0425 74 10 je @@Parameter_Found
1 555
1 556 ;Если мы дошли до этого места => найденный нами параметр на самом деле
1 557 ;является частью какого другого параметра, что эквивалентно тому, что
1 558 ;мы пока не нашли нужного нам параметра => продолжаем поиск.
1 559 ;Устанавливаем указатель снова на первую букву строки с параметром.
1 560 0427 BE 02A8r mov si, OFFSET Parameter_Copy
1 561 042A EB D2 jmp @@Compare_Again
1 562
1 563 ;это второй вариант ( более простой )|je @@Parameter_Found ; так оно и есть => мы нашли в +
564 командной строке
1 565 ;проверки того, что мы нашли параметр| ; наш искомый параметр целиком => +
566 выход и.т.д.
1 567 042C @@Check_Command_Line_End:
1 568 ;проверяем, а не кончилась ли командная строка
1 569 042C 26: 80 3D 00 cmp [ BYTE PTR es:di ], 00h
1 570 0430 74 02 je @@Parameter_Not_Found ; в данном случае получается, что командная строка
1 571 ; оказалась короче параметра и => мы его в ней никак
1 572 ; не найдем => выход
1 573 ;ни одна строка не кончилась => переходим к сравнению следующего символу
1 574 ;командной строки и следующего символа параметра
1 575 0432 EB CA jmp @@Compare_Again
1 576
1 577 0434 @@Parameter_Not_Found:
1 578 ;устанавливаем флаг того, что параметр не найден
1 579 0434 F8 clc
1 580 0435 EB 01 jmp @@Finish_Procedure
1 581 0437 @@Parameter_Found:
1 582 ;устанавливаем флаг того, что параметр найден
1 583 0437 F9 stc
1 584 0438 @@Finish_Procedure:
1 585 ;восстанавливаем все регистры
1 586 0438 07 pop es
1 587 0439 1F pop ds
1 588 043A 61 popa
1 589 ;завершаем процедуру
1 590 043B C3 ret
1 591 043C ENDP IsParameter
1 592
1 593 ;------------------------------------------------------------------------------
1 594
1 595 043C PROC UnloadProgramFromMemory
1 596 ;Сравниваем адрес нашей процедуры обработки прерывания 1Ch и тот, который
1 597 ;возвращается DOS
1 598 ;получаем адрес нашей процедуры обработки прерывания 1Ch
1 599 043C B8 BD01 mov ax, 0BD01h ; для варианта с
1 600 043F CD 2F int MUX_INT ; использованием 2Fh
1 601 0441 55 push bp ; в BP хранится адрес сегмента PSP резидентной части
1 602 ; после вызова функции IsProgramInMemoryAlready
1 603 0442 1F pop ds
1 604 0443 BA 017Fr mov dx, OFFSET New_1C_Vector
1 605 ;получаем обработчик прерывания 1Ch
1 606 0446 B8 351C mov ax, GET_INT_VECTOR + 1Ch
1 607 0449 CD 21 int DOS_INT
1 608 ;сравниваем адрес обработчиков
1 609 044B 3B D3 cmp dx, bx ; сравниваем смещения
1 610 044D 75 78 jne @@Memory_Configuration_Changed ;несовпадение => завершение программы
1 611 044F 1E push ds
1 612 0450 5A pop dx
1 613 0451 06 push es
1 614 0452 5B pop bx
1 615 0453 3B D3 cmp dx, bx ; сравниваем сегменты
1 616 0455 75 70 jne @@Memory_Configuration_Changed ;несовпадение => завершение программы
1 617
1 618 ;Сравниваем адрес нашей процедуры обработки прерывания 2Fh и тот, который
1 619 ;возвращается DOS
1 620 ;получаем адрес нашей процедуры обработки прерывания 2Fh
1 621 0457 55 push bp ; в BP хранится адрес сегмента PSP резидентной части
1 622 ; после вызова функции IsProgramInMemoryAlready
1 623 0458 1F pop ds
1 624 0459 BA 021Dr mov dx, OFFSET New_2F_Vector
1 625 ;получаем обработчик прерывания 2Fh
1 626 045C B8 352F mov ax, GET_INT_VECTOR + 2Fh
1 627 045F CD 21 int DOS_INT
1 628 ;сравниваем адрес обработчиков
1 629 0461 3B D3 cmp dx, bx ; сравниваем смещения
1 630 0463 75 62 jne @@Memory_Configuration_Changed ;несовпадение => завершение программы
1 631 0465 1E push ds
1 632 0466 5A pop dx
1 633 0467 06 push es
1 634 0468 5B pop bx
1 635 0469 3B D3 cmp dx, bx ; сравниваем сегменты
1 636 046B 75 5A jne @@Memory_Configuration_Changed ;несовпадение => завершение программы
1 637
1 638 ;Сравниваем адрес нашей процедуры обработки прерывания 09h и тот, который
1 639 ;возвращается DOS
1 640 ;получаем адрес нашей процедуры обработки прерывания 09h
1 641 046D 55 push bp ; в BP хранится адрес сегмента PSP резидентной части
1 642 ; после вызова функции IsProgramInMemoryAlready
1 643 046E 1F pop ds
1 644 046F BA 0130r mov dx, OFFSET New_09_Vector
1 645 ;получаем обработчик прерывания 09h
1 646 0472 B8 3509 mov ax, GET_INT_VECTOR + 09h
1 647 0475 CD 21 int DOS_INT
1 648 ;сравниваем адрес обработчиков
1 649 0477 3B D3 cmp dx, bx ; сравниваем смещения
1 650 0479 75 4C jne @@Memory_Configuration_Changed ;несовпадение => завершение программы
1 651 047B 1E push ds
1 652 047C 5A pop dx
1 653 047D 06 push es
1 654 047E 5B pop bx
1 655 047F 3B D3 cmp dx, bx ; сравниваем сегменты
1 656 0481 75 44 jne @@Memory_Configuration_Changed ;несовпадение => завершение программы
1 657
1 658 ;Восстанавливаем обработчик 1Ch прерывания
1 659 0483 55 push bp
1 660 0484 07 pop es
1 661 0485 26: A1 0127r mov ax, [ WORD PTR es:Old_1C_Vector + 2 ]
1 662 0489 50 push ax
1 663 048A 1F pop ds
1 664 048B 26: 8B 16 0125r mov dx, [ WORD PTR es:Old_1C_Vector ]
1 665 0490 B8 251C mov ax, SET_INT_VECTOR + 1Ch
1 666 0493 CD 21 int DOS_INT
1 667
1 668 ;Восстанавливаем обработчик 2Fh прерывания
1 669 0495 26: A1 012Br mov ax, [ WORD PTR es:Old_2F_Vector + 2 ]
1 670 0499 50 push ax
1 671 049A 1F pop ds
1 672 049B 26: 8B 16 0129r mov dx, [ WORD PTR es:Old_2F_Vector ]
1 673 04A0 B8 252F mov ax, SET_INT_VECTOR + 2Fh
1 674 04A3 CD 21 int DOS_INT
1 675
1 676 ;Восстанавливаем обработчик 09h прерывания
1 677 04A5 26: A1 0123r mov ax, [ WORD PTR es:Old_09_Vector + 2 ]
1 678 04A9 50 push ax
1 679 04AA 1F pop ds
1 680 04AB 26: 8B 16 0121r mov dx, [ WORD PTR es:Old_09_Vector ]
1 681 04B0 B8 2509 mov ax, SET_INT_VECTOR + 09h
1 682 04B3 CD 21 int DOS_INT
1 683
1 684 ;высвобождаем память, выделенную под резидентную часть
1 685 04B5 55 push bp
1 686 04B6 07 pop es
1 687 04B7 B8 4900 mov ax, FREE_MEMORY
1 688 04BA CD 21 int DOS_INT
1 689 ;печатаем соообщение об освобождении памяти
1 690 04BC 0E push cs
1 691 04BD 1F pop ds
1 692 04BE BA 05D2r mov dx, OFFSET MemoryIsFreeMessage
1 693 04C1 B8 0900 mov ax, PRINT_STRING
1 694 04C4 CD 21 int DOS_INT
1 695 ;возвращаемся из процедуры
1 696 04C6 C3 ret
1 697 04C7 @@Memory_Configuration_Changed:
1 698 ;печатаем сообщение о невозможности освобождения памяти
1 699 04C7 0E push cs
1 700 04C8 1F pop ds
1 701 04C9 BA 0625r mov dx, OFFSET CannotUnloadProgramMessage
1 702 04CC B8 0900 mov ax, PRINT_STRING
1 703 04CF CD 21 int DOS_INT
1 704 ;возвращаемся из процедуры
1 705 04D1 C3 ret
1 706 04D2 ENDP UnloadProgramFromMemory
1 707
1 708 ;------------------------------------------------------------------------------
1 709
1 710 ;процедура завершения программы
1 711 04D2 PROC FinishProgram
1 712 04D2 B8 4C00 mov ax, FINISH_PROGRAM
1 713 04D5 2E: 0A 06 012Dr or al, [cs:Exit_Code]
1 714 04DA CD 21 int DOS_INT
1 715 04DC ENDP FinishProgram
1 716
1 717 ;------------------------------------------------------------------------------
1 718
1 719 ;процедура оставления в памяти программы как резидента
1 720 04DC PROC KeepProgram
1 721 04DC B8 3100 mov ax, TSR
1 722 04DF 2E: 0A 06 012Dr or al, [cs:Exit_Code]
1 723 04E4 CD 21 int DOS_INT
1 724 04E6 ENDP KeepProgram
1 725
1 726 ;------------------------------------------------------------------------------
1 727
1 728 ;процедура установки нового обработчика прерывания 1Ch
1 729 04E6 PROC Install_New_1C_Handler
1 730 ;получаем адрес старого обработчика прерывания
1 731 04E6 0E push cs
1 732 04E7 1F pop ds
1 733 04E8 B8 351C mov ax, GET_INT_VECTOR + 1Ch
1 734 04EB CD 21 int DOS_INT
1 735 ;запоминаем адрес старого обработчика прерывания
1 736 04ED 2E: 89 1E 0125r mov [ WORD PTR Old_1C_Vector ], bx
1 737 04F2 2E: 8C 06 0127r mov [ WORD PTR Old_1C_Vector+2 ], es
1 738 ;устанавливаем новый обработчик прерывания
1 739 04F7 BA 017Fr mov dx, OFFSET New_1C_Vector
1 740 04FA B8 251C mov ax, SET_INT_VECTOR + 1Ch
1 741 04FD CD 21 int DOS_INT
1 742 ;возвращаемся из процедуры
1 743 04FF C3 ret
1 744 0500 ENDP Install_New_1C_Handler
1 745
1 746 ;------------------------------------------------------------------------------
1 747
1 748 ;процедура установки нового обработчика прерывания 09h
1 749 0500 PROC Install_New_09_Handler
1 750 ;получаем адрес старого обработчика прерывания
1 751 0500 0E push cs
1 752 0501 1F pop ds
1 753 0502 B8 3509 mov ax, GET_INT_VECTOR + 09h
1 754 0505 CD 21 int DOS_INT
1 755 ;запоминаем адрес старого обработчика прерывания
1 756 0507 2E: 89 1E 0121r mov [ WORD PTR Old_09_Vector ], bx
1 757 050C 2E: 8C 06 0123r mov [ WORD PTR Old_09_Vector+2 ], es
1 758 ;устанавливаем новый обработчик прерывания
1 759 0511 BA 0130r mov dx, OFFSET New_09_Vector
1 760 0514 B8 2509 mov ax, SET_INT_VECTOR + 09h
1 761 0517 CD 21 int DOS_INT
1 762 ;возвращаемся из процедуры
1 763 0519 C3 ret
1 764 051A ENDP Install_New_09_Handler
1 765
1 766 ;------------------------------------------------------------------------------
1 767
1 768 ;процедура установки нового обработчика прерывания 2Fh
1 769 051A PROC Install_New_2F_Handler
1 770 ;получаем адрес старого обработчика прерывания
1 771 051A 0E push cs
1 772 051B 1F pop ds
1 773 051C B8 352F mov ax, GET_INT_VECTOR + 2Fh
1 774 051F CD 21 int DOS_INT
1 775 ;запоминаем адрес старого обработчика прерывания
1 776 0521 2E: 89 1E 0129r mov [ WORD PTR Old_2F_Vector ], bx
1 777 0526 2E: 8C 06 012Br mov [ WORD PTR Old_2F_Vector+2 ], es
1 778 ;устанавливаем новый обработчик прерывания
1 779 052B BA 021Dr mov dx, OFFSET New_2F_Vector
1 780 052E B8 252F mov ax, SET_INT_VECTOR + 2Fh
1 781 0531 CD 21 int DOS_INT
1 782 ;возвращаемся из процедуры
1 783 0533 C3 ret
1 784 0534 ENDP Install_New_2F_Handler
1 785
1 786 ;------------------------------------------------------------------------------
1 787
788
789 ;данные не используемые в резидентной части программы
790 0534 8F E0 AE A3 E0 A0 AC+ ProgramAlreadyLoadedMessage DB 'Программа "Резидентные часы" уже загружена в память.',13,10
791 AC A0 20 22 90 A5 A7+
792 A8 A4 A5 AD E2 AD EB+
793 A5 20 E7 A0 E1 EB 22+
794 20 E3 A6 A5 20 A7 A0+
795 A3 E0 E3 A6 A5 AD A0+
796 20 A2 20 AF A0 AC EF+
797 E2 EC 2E 0D 0A
798 056A 91 AF A0 E1 A8 A1 AE+ DB 'Спасибо за внимание.',13,10,'$'
799 20 A7 A0 20 A2 AD A8+
800 AC A0 AD A8 A5 2E 0D+
801 0A 24
802 0581 8F E0 AE A3 E0 A0 AC+ ProgramLoadedMessage DB 'Программа "Резидентные часы" успешно загружена в память.',+
803 AC A0 20 22 90 A5 A7+ 13,10
804 A8 A4 A5 AD E2 AD EB+
805 A5 20 E7 A0 E1 EB 22+
806 20 E3 E1 AF A5 E8 AD+
807 AE 20 A7 A0 A3 E0 E3+
808 A6 A5 AD A0 20 A2 20+
809 AF A0 AC EF E2 EC 2E+
810 0D 0A
811 05BB 91 AF A0 E1 A8 A1 AE+ DB 'Спасибо за внимание.',13,10,'$'
812 20 A7 A0 20 A2 AD A8+