Выгрузка резидентной программы - Assembler

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

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

помогите написать выгрузку программы(код представлен), обычные часы.. надо сделать чтоб или от клавиши или от повторного запуска файла она выключалась..
code    segment                          ; определение кодового сегмента
        assume  cs:code,ds:code          ; CS и DS указывают на сегмент кода
        org     100h                     ; размер PSP для COM программы
start:  jmp     load                     ; переход на нерезидентную часть
        old     dd  0                    ; адрес старого обработчика 
        buf     db  ' 00:00:00 ',0       ; шаблон для вывода текущего времени
 
decode  proc                             ; процедура заполнения шаблона
        mov     ah,  al                  ; преобразование двоично-десятичного 
        and     al,  15                  ; числа в регистре AL
        shr     ah,  4                   ; в пару ASCII символов
        add     al,  '0'
        add     ah,  '0'
        mov     buf[bx + 1],  ah         ; запись ASCII символов
        mov     buf[bx + 2],  al         ; в шаблон
        add     bx,  3      
        ret                              ; возврат из процедуры
decode  endp                             ; конец процедуры 
 
clock   proc                             ; процедура обработчика прерываний от таймера
        pushf                            ; создание в стеке структуры для IRET
        call    cs:old                   ; вызов старого обработчика прерываний
        push    ds                       ; сохранение модифицируемых регистров
        push    es
    push    ax
    push    bx
        push    cx
        push    dx
    push    di
        push    cs
        pop     ds
 
        mov     ah,  2                   ; функция BIOS для получения текущего времени
        int     1Ah                      ; прерывание BIOS
 
        xor     bx,  bx                  ; настройка BX на начало шаблона
        mov     al,  ch                  ; в AL - часы
        call    decode                   ; вызов процедуры заполнения шаблона - часы
        mov     al,  cl                  ; в AL - минуты
        call    decode                   ; вызов процедуры заполнения шаблона - минуты
        mov     al,  dh                  ; в AL - секунды
        call    decode                   ; вызов процедуры заполнения шаблона - секунды 
 
        mov     ax,  0B800h              ; настройка AX на сегмент видеопамяти
        mov     es,  ax                  ; запись в ES значения сегмента видеопамяти
        xor     di,  di                  ; настройка DI на начало сегмента видеопамяти
        xor     bx,  bx                  ; настройка BX на начало шаблона
        mov     ah,  1Bh                 ; атрибут выводимых символов
@@1:    mov     al,  buf[bx]             ; цикл для записи символов шаблона в видеопамять
        stosw                            ; запись очередного символа и атрибута
        inc     bx                       ; инкремент указателя на символ шаблона
        cmp     buf[bx],  0              ; пока не конец шаблона,
        jnz     @@1                      ; продолжать запись символов
 
@@5:    pop     di                       ; восстановление модифицируемых регистров
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        pop     es
        pop     ds
        iret                             ; возврат из обработчика
clock   endp                             ; конец процедуры обработчика
end_clock:                               ; метка для определения размера резидентной
                                         ; части программы
load:   mov     ax,  351Ch               ; получение адреса старого обработчика
        int     21h                      ; прерываний от таймера
        mov     word ptr old,  bx        ; сохранение смещения обработчика
        mov     word ptr old + 2,  es    ; сохранение сегмента обработчика
        mov     ax,  251Ch               ; установка адреса нашего обработчика
        mov     dx,  offset clock        ; указание смещения нашего обработчика
        int     21h                      ; вызов DOS
        mov     ax,  3100h               ; функция DOS завершения резидентной программы
        mov     dx, (end_clock - start + 10Fh) / 16 ; определение размера резидентной
                                                    ; части программы в параграфах
        int     21h                      ; вызов DOS
code    ends                             ; конец кодового сегмента
        end     start                    ; конец программы

Решение задачи: «Выгрузка резидентной программы»

textual
Листинг программы
code    segment                          ; определение кодового сегмента
        assume  cs:code,ds:code          ; CS и DS указывают на сегмент кода
        org     100h                     ; размер PSP для COM программы
.386    ;для команды shr ah,4
start:  jmp     load                     ; переход на нерезидентную часть
        old     dd  0                    ; адрес старого обработчика 
        buf     db  ' 00:00:00 ',0       ; шаблон для вывода текущего времени
 
decode  proc                             ; процедура заполнения шаблона
        mov     ah,  al                  ; преобразование двоично-десятичного 
        and     al,  15                  ; числа в регистре AL
        shr     ah,  4                   ; в пару ASCII символов
        add     al,  '0'
        add     ah,  '0'
        mov     buf[bx + 1],  ah         ; запись ASCII символов
        mov     buf[bx + 2],  al         ; в шаблон
        add     bx,  3      
        ret                              ; возврат из процедуры
decode  endp                             ; конец процедуры 
 
clock   proc                             ; процедура обработчика прерываний от таймера
        pushf                            ; создание в стеке структуры для IRET
        call    cs:old                   ; вызов старого обработчика прерываний
 
        push    ds                       ; сохранение модифицируемых регистров
        push    es
;        push    ax
        push    bx
        push    cx
        push    dx
        push    di
 
        push    cs
        pop     ds
 
    cmp ah,33h      ;был ли вызов из программы установки обработчика
    jnz short noExit
 
    lds dx,old      ;вернуть старое прерывание
    mov ax,251Ch
    int 21h
 
    push cs         ;выгрузить из памяти наше прерывание
    pop es
    mov ah,49h
    int 21h
    mov ah,55h      ;сообщить, что обработчик выгружен
    jmp short exit
noExit:
        mov     ah,  2                   ; функция BIOS для получения текущего времени
        int     1Ah                      ; прерывание BIOS
 
        xor     bx,  bx                  ; настройка BX на начало шаблона
        mov     al,  ch                  ; в AL - часы
        call    decode                   ; вызов процедуры заполнения шаблона - часы
        mov     al,  cl                  ; в AL - минуты
        call    decode                   ; вызов процедуры заполнения шаблона - минуты
        mov     al,  dh                  ; в AL - секунды
        call    decode                   ; вызов процедуры заполнения шаблона - секунды 
 
        mov     ax,  0B800h              ; настройка AX на сегмент видеопамяти
        mov     es,  ax                  ; запись в ES значения сегмента видеопамяти
        xor     di,  di                  ; настройка DI на начало сегмента видеопамяти
        xor     bx,  bx                  ; настройка BX на начало шаблона
        mov     ah,  1Bh                 ; атрибут выводимых символов
@@1:    mov     al,  buf[bx]             ; цикл для записи символов шаблона в видеопамять
        stosw                            ; запись очередного символа и атрибута
        inc     bx                       ; инкремент указателя на символ шаблона
        cmp     buf[bx],  0              ; пока не конец шаблона,
        jnz     @@1                      ; продолжать запись символов
 
exit:
@@5:    pop     di                       ; восстановление модифицируемых регистров
        pop     dx
        pop     cx
        pop     bx
;        pop     ax
        pop     es
        pop     ds
        iret                             ; возврат из обработчика
clock   endp                             ; конец процедуры обработчика
end_clock:                               ; метка для определения размера резидентной
                                         ; части программы
load:
    mov ah,33h  ;наша функция проверки установки и выгрузки
    int 1Ch     ;нашего обработчика
    cmp ah,55h  ;наш обработчик уже был установлен
    jz short exit1
 
        mov     ax,  351Ch               ; получение адреса старого обработчика
        int     21h                      ; прерываний от таймера
        mov     word ptr old,bx          ; сохранение смещения обработчика
        mov     word ptr old + 2,es      ; сохранение сегмента обработчика
        mov     ax,  251Ch               ; установка адреса нашего обработчика
        mov     dx,  offset clock        ; указание смещения нашего обработчика
        int     21h                      ; вызов DOS
        mov     ax,  3100h               ; функция DOS завершения резидентной программы
        mov     dx, (end_clock - start + 10Fh) / 16 ; определение размера резидентной
                                                    ; части программы в параграфах
        int     21h                      ; вызов DOS
exit1:
    ret     ;выход из программы
code    ends                             ; конец кодового сегмента
        end     start                    ; конец программы

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

  1. Переменные:
    • old: адрес старого обработчика
    • buf: шаблон для вывода текущего времени (00:00:00)
  2. Код процедуры decode:
    • ah: 10 (для двоично-десятичного числа в регистре AL)
    • al: 15 (для двоично-десятичного числа в регистре AL)
    • shl ah, 4: сегментный регистр AL содержит пару ASCII символов
    • add al, '0': добавляем '0' к ASCII символу в регистре AL
    • add ah, '0': добавляем '0' к ASCII символу в регистре AH
    • mov buf[bx + 1], ah: записываем ASCII символ из регистра AH в шаблон
    • mov buf[bx + 2], al: записываем ASCII символ из регистра AL в шаблон
    • add bx, 3: инкремент указателя на символ шаблона
  3. Код процедуры clock:
    • old: адрес старого обработчика
    • bx: используется для указания на символ шаблона
    • сегментный регистр ES содержит сегмент видеопамяти
    • сегментный регистр DI содержит начальный адрес сегмента видеопамяти
    • атрибут выводимых символов: 1Bh
    • цикл для записи символов шаблона в видеопамять:
      • mov al, buf[bx]:
      • stosw: записывает очередной символ и атрибут
      • inc bx: инкремент указателя на символ шаблона
      • jnz @@1: пока не конец шаблона, повторять запись символов
    • выгрузка обработчика:
      • mov ax, 351Ch: получение адреса старого обработчика
      • int 21h: вызов DOS
      • mov ax, 3100h: функция DOS завершения резидентной программы
      • mov dx, (end_clock - start + 10Fh) / 16: определение размера резидентной части программы в параграфах
      • int 21h: вызов DOS
  4. Код процедуры load:
    • проверка установки и выгрузка обработчика:
      • mov ah, 33h:
      • int 1Ch:
      • cmp ah, 55h:
      • jz short exit1:
    • сохранение адреса старого обработчика:
      • mov bx, ax:
      • int 21h:
    • установка адреса нового обработчика:
      • mov ax, 251Ch:
      • mov dx, offset clock:
      • int 21h:
    • вызов DOS для завершения резидентной программы:
      • mov ax, 3100h:
      • mov dx, (end_clock - start + 10Fh) / 16:
      • int 21h:

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


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

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

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