29.10.2011, 21:15
общий
это ответ
Здравствуйте, Федрычев Даниил Сергеевич!
Использовать обычный запуск ax=4b00h не получится, т.к.
при завершении программы все открытые файлы закрываются.
В результате чего, нельзя получить из дочерней программы handle файла...
Можно реализовать, используя механизм оверлеев.
Итак, вот, что у меня получилось...
Handle передаю через регистр AX, т.к. в случае оверлеев имеем, фактически,
одну многосегментную программу.
Родительская программа ma.asm
[code h=207];Родительская программа MA.ASM
_code segment 'CODE'
assume cs:_code, ds:_data, ss:_stack
main proc
mov ax, _data
mov ds,ax
mov ah, 40h
mov bx, 1
mov cx, lStart ;Старт родительской программы
mov dx, offset sStart
int 21h
mov ax, zzz
mov dx, es ;Освобождение
sub ax, dx ;лишней памяти
mov bx, ax
mov ah, 4ah
int 21h
;Выделение памяти для оверлеев
mov ah, 48h ;
mov bx, 1000h ;запросим 64 кбайт
int 21h
jnc NoErrMem
jmp errmem ;переход, если произошла ошибка
NoErrMem:
mov EPB, ax ;сохранение адреса памяти
mov EPB+2, ax ;для настройки адресов при загрузки оверлеев
mov run_seg, ax ;сегмент оверлея в длинном вызове
mov ax, ds
mov es, ax
;Загрузка первого оверлея
mov bx, offset EPB ;блок EXEC Parameter Block
mov dx, offset chname1 ;имя файла в ASCIIZ
mov ax, 4B03h ;функция загрузки оверлея
int 21h
jnc NoErrOvr
jmp errexec ;переход, если произошла ошибка
NoErrOvr:
;Вызов оверлея
push ds
push es
mov cs:save_ss, ss
mov cs:save_sp, sp
call dword ptr run_adr ;длинный вызов оверлея
mov sp, cs:save_sp
mov ss, cs:save_ss
pop es
pop ds
mov handle, ax ;сохраним handle файла!
test ax, ax
jz errchild
mov ah, 40h
mov bx, 1
mov cx, lOk ;Оверлей отработал
mov dx, offset sOk
int 21h
;Загрузка второго оверлея
mov bx, offset EPB ;блок EXEC Parameter Block
mov dx, offset chname2 ;имя файла в ASCIIZ
mov ax, 4B03h ;функция загрузки оверлея
int 21h
jc errexec ;переход, если произошла ошибка
;Вызов оверлея
push ds
push es
mov cs:save_ss, ss
mov cs:save_sp, sp
mov ax, handle
call dword ptr run_adr ;длинный вызов оверлея
mov sp, cs:save_sp
mov ss, cs:save_ss
pop es
pop ds
test ax, ax
jz errchild
mov ah, 40h
mov bx, 1
mov cx, lOk ;Оверлей отработал
mov dx, offset sOk
int 21h
;Освобождение памяти, которая использована для оверлея
finish:
mov ah, 49h ;функция освобождения памяти
mov es, EPB ;получение адреса блока памяти
int 21h ;вызов MS-DOS
jc errmem ;переход, если произошла ошибка
outprog:
mov ax, 4c00h ;Завершение
int 21h ;программы
errmem:
mov ah, 40h
mov bx, 1
mov cx, lErrMem ;Ошибка менеджера памяти
mov dx, offset sErrMem
int 21h
jmp outprog
errchild:
mov ah, 40h
mov bx, 1 ;Вывод третьего
mov cx, lErrCh ;сообщения
mov dx, offset sErrCh
int 21h
jmp outprog
errexec:
mov ah, 40h
mov bx, 1
mov cx, lErrOvr ;Ошибка загрузки оверлея
mov dx, offset sErrOvr
int 21h
jmp outprog
save_sp dw ?
save_ss dw ?
main endp
_code ends
;Сегмент данных
_data segment 'DATA'
EPB dw ? ;адрес загрузки
dw 0 ;значение настройки
run_adr dw 0 ;новый указатель инструкции
run_seg dw ? ;новое значение кодового сегмента
chname1 db "DO.EXE",0 ;Имя дочерней программы
chname2 db "Close.EXE",0 ;Имя дочерней программы
handle dw 0
sStart db "Родительский процесс запущен",10,13
lStart equ $-sStart
sOk db "Дочерний процесс отработал",10,13
lOk equ $-sOk
sErrOvr db "Дочерний процесс не активизирован",10,13
lErrOvr equ $-sErrOvr
sErrCh db "Дочерний процесс вернул ошибку",10,13
lErrCh equ $-sErrCh
sErrMem db "Ошибка работы с памятью",10,13
lErrMem equ $-sErrMem
_data ends
;Сегмент стека
_stack segment stack 'STACK'
dw 100h dup(?)
_stack ends
zzz segment
zzz ends
end main
[/code]
Оверлей do.asm (открывает файл)
[code h=207];Дочерняя программа do.asm
.286
assume cs:_code, ds:_data, ss:_stack
_code segment 'code'
main proc
mov ax, _data
mov ds, ax
mov ah, 40h
mov bx, 1
mov cx, lStart ;Начало оверлея
mov dx, offset sStart
int 21h
mov ah, 3dh ;Открытие файла
mov al, 0 ;для чтения
mov dx, offset fname
int 21h
jnc ok
mov ah, 40h
mov bx, 1
mov cx, lErrOp ;Ошибка открытия файла
mov dx, offset sErrOp
int 21h
xor ax, ax ;возврящаем 0, как ошибку
jmp finend
ok:
push ax
mov ah, 40h
mov bx, 1
mov cx, lOk ;файл открылся
mov dx, offset sOk
int 21h
pop ax ;возвращаем handle
finend:
retf
main endp
_code ends
;Сегмент данных
_data segment 'data'
sStart db 'Дочерний процесс запущен',10,13
lStart equ $-sStart
sErrOp db 'Фаил не открылся !',10,13
lErrOp equ $-sErrOp
sOk db 'Фаил открылся',10,13
lOk equ $-sOk
fname db 'FILE.txt',0
_data ends
;Сегмент стека
_stack segment stack 'Stack'
dw 100h dup(?)
_stack ends
end main
[/code]
Оверлей close.asm (закрывает файл)
[code h=207];Дочерняя программа close.asm
assume cs:_code, ds:_data, ss:_stack
_code segment 'code'
main proc
push ax ;handle
mov ax, _data
mov ds, ax
mov ah, 40h ;Вывод первого
mov bx, 1 ;сообщения
mov cx, lStart
mov dx, offset sStart
int 21h
pop bx ;handle файла
mov ah, 3eh ;Закрываем файл
int 21h
jnc ok
mov ah, 40h
mov bx, 1
mov cx, lErrCl ;ошибка закрытия файла
mov dx, offset sErrCl
int 21h
xor ax, ax ;пометим ошибку
jmp finend
ok:
mov ah, 40h
mov bx, 1
mov cx, lOk ;файл закрылся
mov dx, offset sOk
int 21h
mov ax, 1 ;все ок
finend:
retf
main endp
_code ends
;Сегмент данных
_data segment 'data'
sStart db 'Второй дочерний процесс запущен',10,13
lStart equ $-sStart
sErrCl db 'Фаил не закрылся !',10,13
lErrCl equ $-sErrCl
sOk db 'Фаил закрылся',10,13
lOk equ $-sOk
_data ends
;Сегмент стека
_stack segment stack 'Stack'
dw 100h dup(?)
_stack ends
end main
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен