
;              4BH-2.ASM - программа к Главе № 29

; (С) Авторские права на файлы-приложения принадлежат автору книги
; "Ассемблер? Это просто! Учимся программировать под MS-DOS"
; Автор: Калашников Олег Александрович (e-mail: Assembler@Kalashnikoff.ru)
;	 http://www.Kalashnikoff.ru

; --- Ассемблирование (получение *.com файла) ---
;При использовании MASM 6.11 - 6.13:
;ML.EXE 4BH-2.asm /AT

;При использовании TASM:
;TASM.EXE 4BH-2.asm
;TLINK.EXE 4BH-2.obj /t/x


;__________________________________________________________________________
;
;!!! ВНИМАНИЕ! Сперва прочтите Главу 29, иначе ничего не будет понятно !!!
;__________________________________________________________________________


;Программа загружает файл (File) используя COMMAND.COM с командной строкой
;(Comm_param) 'abc'.

.186
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h

Start:
      mov bx,offset Finish
      shr bx,4
      inc bx
      mov ah,4Ah
      int 21h    ;Ужимаем размер отведенной памяти до метки Finish

;Ужимаем стек, т.к. он находится в "хвосте" сегмента, на место которого
;будет загружена программа
      mov sp,0FFh

; --- Готовим EPB ---
      mov bx,offset EPB
      mov C_F,cs ;Сегмент командной строки (смещение уже занесено! См. ниже)

; --- Сохраняем ВСЕ регистры, т.к. они будут разрушены!!! ---
      pusha
      push ds
      push es
      mov SS_Seg,ss
      mov SP_Seg,sp

; --- Запускаем программу ---
      mov ah,4Bh  ;Функция EXEC (EXECute - запус программы)
      mov dx,offset File ;Имя файла для запуска
      mov al,0    ;Загрузка и запуск
      int 21h

; --- Восстанавливаем регистры ---
      mov ss,cs:SS_Seg
      mov sp,cs:SP_Seg
      pop es
      pop ds
      popa

      mov ah,9
      jnc OK      ;Не было ошибок - сообщаем 


;ОШИБКА ПРИ ЗАПУСКЕ!
      mov dx,offset Mess_Error
      int 21h
      int 20h

;Успешная загрузка программы
OK:
      mov dx,offset Mess_OK
      int 21h
      int 20h

;Вот, что мы получим, если с помощью данной программы мы загрузим DN,
;а из DN - Volcov Commander (вырезка из VC) (сравните с 4BH-1.com):

; Размер   Программа      Перехватываемые прерывания
;────────────────────────────────────────────────────
;53 776   DOS 7.10       01 02 03 04 0E
;    64   system         19
; 6 928   KEYB           09 E0
; 3 824   WIN            EA F5
; 3 120   vmm32          33 67
; 1 280   DN.COM         FF              <==== Из DN загружаю 4BH-2.COM
; 7 456   COMMAND        2E              <==== Первым грузится Command.com
;   880   4BH-2.COM                      <==== Потом только 4BH-2.COM
; 7 264   command                        <==== 4BH-2 загружает COMMAND.COM!
; 1 296   DN.COM         2F              <==== И только потом DN.COM
; 7 280   COMMAND        22              <==== И т.д. (как из прошлого примера)
;76 096   VC.COM         00 1B 21 23 24


;Файл, который будем загружать
File db 'c:\command.com',0

;Командная строка здесь должна содержать (см. ниже):
;1. Длина командной строки (до 256 байт) (Comm_size)
;2. "/С ", указывающий COMMAND.COM, что нужно загрузить, выполнить и выйти
;   из COMMAND.COM (Comm_switch)
;3. Имя файла для загрузки (Comm_file)
;4. Командная строка для загружаемого из COMMAND.COM файла (Comm_param)
Comm_line:
Comm_size   db 21      ;!!! НЕ ЗАБЫВАЙТЕ ИЗМЕНЯТЬ ДЛИНУ КОММАНДНОЙ СТРОКИ !!!
Comm_switch db ' /C '
Comm_file   db 'c:\dn\dn.com'
  ;Comm_file   db 'test(1)'  ;Запустит test(1).com (exe или bat), если
			     ;таковой имеется в текущем каталоге или
			     ;путь к нему указан в переменной PATH.

  ;Comm_file   db 'dir /p'   ;Выполнит указанную команду.

;Если программа загружается с использованием COMMAND.COM, то расширение
;указывать не обязательно. Командный интерпретатор (COMMAND.COM) никогда
;не позволит запустить программу, расширение которой не COM, EXE или BAT!

Comm_param  db ' abc'
Comm_last   db 0Dh

;ВНИМАНИЕ! Через COMMAND.COM можно выполнять также ЛЮБЫЕ внутренние
;команды DOS, как то: DIR, CLS, TYPE и пр (см. выше "dir /p").


; === Exec Parameter Block (EPB) для функции 4Bh ===
EPB:
Env dw 0   ;Сегмент среды (окружения DOS) для загружаемой программы
C_O dw offset Comm_line ;Смещение командной строки +
C_F dw 0   ;+ сегмент командной строки
    dd 0   ;FCB (не используется)
    dd 0   ;FCB (не используется)
Len dw $-EPB  ;Длина EPB


Mess_OK db 0Dh,0Ah,0Ah, 'Сообщение от 4Bh-2.com: Программа была успешно загружена и выполнена!',0Ah,0Dh,0Ah,0Ah,'$'
Mess_Error db 0Dh,0Ah,0Ah, 'Сообщение от 4Bh-2.com: Файл не найден!',0Ah,0Dh,0Ah,0Ah,'$'

; Переменные для хранения сегментных регистров
SS_Seg dw ?
SP_Seg dw ?

; Метка конца программы (урезаем память до этой метки)
Finish equ $

CSEG ends
end Start