Консультация № 184342
28.10.2011, 23:51
65.51 руб.
0 3 1
Здравствуйте! Нужна помощь по ассемблеру - имеется родительская и дочерняя программы, листинги программ прилагаю. Необходимо, чтобы родительская программа запускала по очереди 2 дочерних процесса, при этом чтобы один процесс открывал файл FILE.txt, а другой закрывал его. Заранее спасибо за ответ.

Приложение:
[/code] ;Родительская программа 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,len1 ;сообщения
mov dx,offset mes1
int 21h
mov ax,zzz
mov dx,es ;Освобождение
sub ax,dx ;лишней памяти
mov bx,ax
mov ah,4ah
int 21h
mov ax,_data
mov es,ax
mov ah,4bh ;Попытка запуска
mov al,0 ;дочернего процесса
mov bx,offset parmblk
mov dx,offset chname
int 21h
jc errexec
mov ah,4dh
int 21h ;Получение и анализ
cmp al,1 ;кода возврата
je errchild

mov ah,40h
mov bx,1 ;Вывод второго
mov cx,len2 ; сообщения
mov dx,offset mes2
int 21h

outprog:
mov ax,4c00h ;Завершение
int 21h ;программы

errchild:
mov ah,40h
mov bx,1 ;Вывод третьего
mov cx,len3 ;сообщения
mov dx,offset mes3
int 21h
jmp outprog

errexec:
mov ah,40h
mov bx,1 ;Вывод четвертого
mov cx,len4 ;сообщения
mov dx,offset mes4
int 21h
jmp outprog
main endp
_code ends

;Сегмент данных
_data segment 'DATA'
parm dw 7 dup(0)
comand db "c:\command.com",0

parmblk dw 7 dup(0)
chname db "DO.EXE",0 ;Имя дочерней программы
mes1 db "Родительский процесс запущен",10,13
len1 equ $-mes1
mes2 db "Дочерний процесс отработал",10,13
len2 equ $-mes2
mes3 db "Дочерний процесс завершился с ошибкой",10,13
len3 equ $-mes3
mes4 db "Дочерний процесс не активизирован",10,13
len4 equ $-mes4
_data ends

;Сегмент стека
_stack segment stack 'STACK'
db 100 dup(0)
_stack ends
zzz segment
zzz ends
end main
[/code]

[code];Дочерняя программа do.asm

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,len1
mov dx,offset mes1
int 21h

mov ah,3dh ;Открытие файла
mov al,0 ;для чтения
mov dx,offset fname
int 21h
jnc ok
mov errcode,1
mov ah,40h
mov bx,1 ;Вывод второго
mov cx,len2 ;сообщения
mov dx,offset mes2
int 21h
jmp finend
ok:
mov errcode,0
mov ah,40h ;Вывод третьего
mov bx,1 ;сообщения
mov cx,len3
mov dx,offset mes3
int 21h
finend:
mov ah,4ch ;Функция завершения
mov al,errcode ;Код возврата
int 21h
main endp
_code ends

;Сегмент данных
_data segment 'data'
mes1 db 'Дочерний процесс запущен',10,13
len1 equ $-mes1
mes2 db 'Фаил не открылся !',10,13
len2 equ $-mes2
mes3 db 'Фаил открылся',10,13
len3 equ $-mes3
fname db 'FILE.txt',0
errcode db 0
_data ends

;Сегмент стека
_stack segment stack 'Stack'
dw 100 dup(?)
_stack ends
end main
[code]

Обсуждение

давно
Посетитель
7438
7205
29.10.2011, 16:04
общий
Запустить-то не проблема...
Проблема в том, что при завершении дочернего процесса, закрываются все открытые файлы,
а посему, в Вашем случае, невозможно получить описатель открытого файла из первого дочернего процесса...
Но, выход всегда есть! Я предлагаю реализовать взаимосвязь посредством загрузки оверлеев. Делаем?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
29.10.2011, 17:48
общий
Да запустить то и правда несложно, у меня и осталась проблема с закрытием файла. Можно попробовать последовать вашему совету...
давно
Посетитель
7438
7205
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]

5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа