Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 27.04.2020
Сообщений: 1
TASM

TSR - по нажатию комбинации клавиш открывает файл и выводит содержимое на экран

27.04.2020, 21:51. Показов 793. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужно написать TSR программу под DOS, которая по нажатию комбинации клавиш открывает файл и выводит содержимое на экран. Адрес файла задаётся через DOS. Строка, которую предварительно я считал с DOS, если обратиться к ней во время перехвата прерывания 09h, выглядит так, будто считывания и не было. Как это решить? Я только начинаю изучать ассемблер, не закидывайте камнями, пожалуйста

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
 
;Кодировка input файла windows-866
code_seg segment
    assume cs:code_seg,ds:code_seg,ss:code_seg
    org 100h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
jmp begin
 
get_vector  macro   vector, DD_for_save_vector    
    mov AX,35&vector                      ;   получить
                                      ;   вектор
    int 21h                           ;   прерывания  2Fh
    mov word ptr DD_for_save_vector,BX    ;   ES:BX - вектор
    mov word ptr DD_for_save_vector+2,ES  ;
;
endm
;   
set_vector  macro   vector, handler
    mov DX,offset handler           ;   получить смещение точки входа в новый
;                                    ;   обработчик на DX
    mov AX,25&vector                    ;   функция установки прерывания
;                                    ;   изменить вектор 2Fh
    int 21h  ; AL - номер прерыв. DS:DX - указатель программы обработки прер.
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;----------------------------------------------------------------------------
;flag        DB  0
high_Y      DB  0
left_X      DB  0
low_Y       DB  23
right_X     DB  80
;
page_num    DB  0
coord_Y     DB  11
coord_X     DB  57
st_coord_Y  DB  24
st_coord_X  DB  5
;============================================================================
;----------------------------------------------------------------------------
int_2Fh_vector  DD  ?
old_09h         DD  ?
 
FileName        DB  14,0,14 dup ('$')
handle          DW ?                    ;ячейка для дескриптора
 
new_09h proc near
    push ax
    
    in AL,60h      ; Введем scan-code
    cmp AL, 11h
    je hotkey
    cmp AL, 1Fh
    je hotkey
    
    mov combo_key, 0
go_out:
    pop ax
    jmp CS:old_09h  ; В системный обработчик без возврата
hotkey:
    cmp combo_key, AL
    je go_out
    
    cmp combo_key, 0
    mov combo_key, AL
    je go_out
    
    sti                 ; Не будем мешать таймеру
    in      AL,61h      ; Введем содержимое порта B
    or      AL,80h      ; Установим старший бит
    out     61h,AL      ; и вернем в порт B.
    and     AL,7Fh      ; Снова разрешим работу клавиатуры,
    out     61h,AL      ; сбросив старший бит порта B.
    
    ;
;-------------------- Вывод окна средствами BIOS ---------------------------
    ;inc     CS:flag        ; Признак вывода окна
            push    BX
            push    CX
            push    DX
        
 
        lea DX, CS:FileName + 2
        mov AX, 3D02h       ; Open file for read/write
        int 21h
        mov err_code, AL
            
        mov     AX, 0600h      ; Задание окна
        mov     BH, 70h        ; Атрибут черный по серому
        mov     CH, CS:high_Y     ; Ко-
        mov     CL, CS:left_X     ;    ор-
        mov     DH, CS:low_Y      ;       ди-
        mov     DL, CS:right_X    ;          наты окна
        int 10h
;----------------------------------------------------------------------------
; ------------------------ Позиционируем курсор -----------------------------
        mov AH, 03h
        mov BH,CS:page_num
        int 10h
        mov st_coord_Y, DH
        mov st_coord_X, DL
 
        mov     AH,02h          ; Функция позиционирования
        mov     BH,CS:page_num  ; Видеостраница
        mov     DH,CS:coord_Y   ; Строка
        mov     DL,CS:coord_X   ; Столбец
        int 10h
; Выведем в окно строку символов без задания атрибутов (с атрибутами окна)
        xor CX, CX
        mov     CL,6              ; Длина строки
        mov     BX, offset CS:FileName + 2      ; Адрес строки
        mov     AH,0Eh              ; Функция вывода одного символа
        add err_code, '0'
        mov     AL, err_code
        int 10h
next_sym:
        mov     AL,CS:[BX]          ; Символ в AL
        inc     BX                  ; Сдвиг по строке
        int     10h                 ;
        loop    next_sym            ; Цикл по строкеs
        
        mov     AH,02h          ; Функция позиционирования
        mov     BH,CS:page_num  ; Видеостраница
        mov     DH,CS:st_coord_Y   ; Строка
        mov     DL,CS:st_coord_X   ; Столбец
        int 10h
;============================================================================
;
        pop     DX
        pop     CX
        pop     BX
;--------------------------------------------------------------------------
    
    cli
    mov     AL, 20h      ; Пошлем
    out     20h,AL       ; приказ EOI
    
    pop ax
    iret
new_09h     endp
 
;==================================================================================
;
int_2Fh proc far
    cmp     AH,0C7h         ; Наш номер?
    jne     Pass_2Fh        ; Нет, на выход
    cmp     AL,00h          ; Подфункция проверки на повторную установку?
    je      inst            ; Программа уже установлена
    cmp     AL,01h          ; Подфункция выгрузки?
    je      unins           ; Да, на выгрузку
    jmp     short Pass_2Fh  ; Неизвестная подфункция - на выход
inst:
    mov     AL,0FFh         ; Сообщим о невозможности повторной установки
    iret
Pass_2Fh:
    jmp dword PTR CS:[int_2Fh_vector]
;
; -------------- Проверка - возможна ли выгрузка программы из памяти ? ------
unins:
    push    BX
    push    CX
    push    DX
    push    ES
;
    mov     CX,CS   ; Пригодится для сравнения, т.к. с CS сравнивать нельзя
    mov     AX,3509h    ; Проверить вектор 09h
    int     21h ; Функция 35h в AL - номер прерывания. Возврат-вектор в ES:BX
;
    mov     DX,ES
    cmp     CX,DX
    jne     Not_remove
;
    cmp     BX, offset CS:new_09h
    jne     Not_remove
;
    mov     AX,352Fh    ; Проверить вектор 2Fh
    int     21h ; Функция 35h в AL - номер прерывания. Возврат-вектор в ES:BX
;
    mov     DX,ES
    cmp     CX,DX
    jne     Not_remove
;
    cmp     BX, offset CS:int_2Fh
    jne     Not_remove
; ---------------------- Выгрузка программы из памяти ---------------------
;
    push    DS
;
    lds     DX, CS:old_09h   ; Эта команда эквивалентна следующим двум
;    mov     DX, word ptr old_09h
;    mov     DS, word ptr old_09h+2
    mov     AX,2509h        ; Заполнение вектора старым содержимым
    int     21h
;
    lds     DX, CS:int_2Fh_vector   ; Эта команда эквивалентна следующим двум
;    mov     DX, word ptr int_2Fh_vector
;    mov     DS, word ptr int_2Fh_vector+2
    mov     AX,252Fh
    int     21h
;
    pop     DS
;
    mov     ES,CS:2Ch       ; ES -> окружение
    mov     AH, 49h         ; Функция освобождения блока памяти
    int     21h
;
    mov     AX, CS
    mov     ES, AX          ; ES -> PSP выгрузим саму программу
    mov     AH, 49h         ; Функция освобождения блока памяти
    int     21h
;
    mov     AL,0Fh          ; Признак успешной выгрузки
    jmp     short pop_ret
Not_remove:
    mov     AL,0F0h          ; Признак - выгружать нельзя
pop_ret:
    pop     ES
    pop     DX
    pop     CX
    pop     BX
;
    iret
int_2Fh endp
;============================================================================
begin:
        mov CL,ES:80h       ; Длина хвоста в PSP
        cmp CL,0            ; Длина хвоста=0?
        je  check_install   ; Да, программа запущена без параметров,
                            ; попробуем установить
        xor CH,CH       ; CX=CL= длина хвоста
        cld             ; DF=0 - флаг направления вперед
        mov DI, 81h     ; ES:DI-> начало хвоста в PSP
        mov AL,' '          ; Уберем пробелы из начала хвоста
repe    scasb   ; Сканируем хвост пока пробелы
                ; AL - (ES:DI) -> флаги процессора
                ; повторять пока элементы равны
        dec DI          ; DI-> на первый символ после пробелов
        mov console_com, DI
        
        mov SI, offset key3
        mov CX, 7
repe    cmpsb
        jne check_key2
        
    ;---------------------------------------------------------------
        lea DX, CS:FileName
        mov BX,DX
        mov AL,51
        mov [BX], AL
        mov AH, 0Ah
        int 21h
    
        xor bx, bx
        mov BL, CS:FileName[1]
        mov CS:FileName[bx+2], 0
    
    lea DX, CS:FileName + 2
    mov AX, 3D02h       ; Open file for read/write
    int 21h
    jc  file_error
    
    
    mov bx, ax
    mov AX, 3E00h
    int 21h
    
    lea DX, msg_success
    call print
    
    int 20h
    
check_key2:
        mov DI, console_com
        mov SI, offset key2
        mov CX, 5
repe    cmpsb
        jne check_key
        
        lea DX, msg_help
        call print
        ;lea DX, CS:FileName + 2
        ;call print
        
        int 20h
check_key:
        mov DI, console_com
        mov SI,offset key   ; DS:SI-> поле key
        mov CX, 4       ; ожидаемая длина команды
repe    cmpsb   ; Сравниваем введенный хвост с ожидаемым
                ; (DS:SI)-(ES:DI) -> флаги процессора
        jne check_install ; Неизвестная команда - попробуем установить
        inc flag_off
; Проверим, не установлена ли уже эта программа
check_install:
        mov AX,0C700h   ; AH=0C7h номер процесса C7h
                        ; AL=00h -дать статус установки процесса
        int 2Fh         ; мультиплексное прерывание
        cmp AL,0FFh
        je  already_ins ; возвращает AL=0FFh если установлена
;----------------------------------------------------------------------------
    cmp flag_off,1
    je  xm_stranno
    jmp vectors
;-----------------------------------------------------------------------------
file_error:
    lea DX, msg_error
    call print
    int 20h
vectors:
    get_vector  2Fh,    int_2Fh_vector
    set_vector  2Fh,    int_2Fh
    
    get_vector  09h,    old_09h
    set_vector  09h,    new_09h
    
    
mov DX,offset   begin           ;   оставить программу ...
int 27h                         ;   ... резидентной и выйти
;============================================================================
already_ins:
        cmp flag_off,1      ; Запрос на выгрузку установлен?
        je  uninstall       ; Да, на выгрузку
        lea DX,msg          ; Вывод на экран сообщения: already installed!
        call    print
        int 20h
; ------------------ Выгрузка -----------------------------------------------
uninstall:
        mov AX,0C701h  ; AH=0C7h номер процесса C7h, подфункция 01h-выгрузка
        int 2Fh             ; мультиплексное прерывание
        cmp AL,0F0h
        je  not_sucsess
        cmp AL,0Fh
        jne not_sucsess
        mov DX,offset msg2  ; Сообщение о выгрузке
        call    print
        int 20h
not_sucsess:
        mov DX,offset msg3  ; Сообщение, что выгрузка невозможна
        call    print
        int 20h
xm_stranno:
        mov DX,offset msg4  ; Сообщение, программы нет, а пользователь
        call    print       ; дает команду выгрузки
        int 20h
;----------------------------------------------------------------------------
key         DB  '/off'
key2        DB  '/help'
key3        DB  '/update'
flag_off    DB  0
msg         DB  'already '
msg1        DB  'installed',13,10,'$'
msg4        DB  'just '
msg3        DB  'not '
msg2        DB  'uninstalled',13,10,'$'
;msg_help   DB  '/off to uninstall',13,10
;msg_help1  DB  '/update to update file',13,10
msg_help    DB  'S+W to show file',13,10,'$'
msg_error   DB  'File ERROR',13,10,'$'
msg_success DB  'File successfully added',13,10,'$'
;============================================================================
PRINT       PROC NEAR
    MOV AH,09H
    INT 21H
    RET
PRINT       ENDP
;;============================================================================
 
;FileName       DB '  in.txt',0
buf             DB 1000 dup('$')
err_code        DB 0
combo_key       DB ?
console_com     DW ?
code_seg ends
    end start
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
27.04.2020, 21:51
Ответы с готовыми решениями:

Резидент, который по нажатию комбинации клавиш создает файл, в который записывается изображение на экране
Создать резидентный обработчик прерывания, который по нажатию комбинации клавиш (любой) создает файл, в который записывается изображение на...

Выполнение батника по нажатию комбинации клавиш
Здравствуйте, с помощью чего выполнить данную схему? - Когда на клавиатуре зажимаются клавиши "Ctrl" + "C", нужно...

По нажатию комбинации клавиш запускать код
Приветствую! Совсем недавно я перебрался с Windows на Linux... Всё прекрасно, полёт нормальный, но душа требует кодинга... До...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.04.2020, 21:51
Помогаю со студенческими работами здесь

Написать программу, которая выводит на экран и записывает в файл все комбинации цифр
Написать программу, которая выводит на экран и записывает в файл все комбинации цифр, которые могут выпасть при бросании трех шестигранных...

Вызов приложения по нажатию определенной комбинации клавиш
Всем привет! у меня есть приложение, его необходимо запустить при помощи нажатия комбинации клавиш. То есть у нас есть рабочий стол и при...

Как можно запутить макрос по нажатию комбинации клавиш
Создал наипростейший макрос abc. Как его можно запутить по нажатию комбинации клавиш? Комбинации надо установить в процедуре...

Вызов события по нажатию комбинации клавиш в событии OnKeyPress оператором case
Здравствуйте! Для обработки события нажатия на клавишу клавиатуры существует событие OnKeyPress. Например, в блокноте, вызов действия путём...

Добавить обработку комбинации клавиш Alt+7, по нажатию которой заголовок будет менять свое местоположение
Доброе утро! Необходимо добавить обработку комбинации клавиш Alt+7, по нажатию которой заголовок будет менять свое местоположение, никак не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при создании или изменении элементов справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи электронной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru