При загрузке EXE модуля выполняются следующие действия:
- в свободной области ОЗУ строится MCB (Memory Control Block) размером в
один параграф (16 байт).
Структура MCB блока.
===================
------T-------T----------¬
¦Смещ.¦Длина ¦Содержимое¦
+-----+-------+----------+ -'M'(4DH) - блок MCB не последний
¦ 0 ¦ 1байт¦ Тип блока¦----¦-Z'(5AH) - блок является последним
+-----+-------+----------+
¦ 1 ¦ 2байт¦ Владелец ¦ сегмент владельца MCB (0 - OS)
+-----+-------+----------+
¦ 3 ¦ 2байт¦ Размер ¦ число параграфов в этом блоке распределения
+-----+-------+----------+
- далее загружается программа с PSP (Programm Segment Prefix) размером 256
байт. Реально перед загрузкой программы строятся 2 MCB блока.Адрес первого
MCB блока размещается перед началом векторной таблицы DOS минус 2 байта. Для
того, чтобы получить адрес векторной таблицы DOS необходимо выполнить:
mov ax,5200h ;функция 52h прерывания 21h
int 21h
после выполнения прерывания адрес таблицы находится в паре регистров ES:BX.
Исходный текст программы пребегающей по MCB:
Код на ASM .286 .model small .data memes dw 0 membx dw 0 upline db '----------T-----------------------T--------¬', 10, 13, '$' dnline db 'L---------+-----------------------+---------', 10, 13, '$' hline db '¦0000:0000¦00 00 00 00 00 00 00 00¦AAAAAAAA¦', 10, 13, '$' mes1 db 'Адрес таблицы векторов: ' h1 db '0000:0000', 10, 13, '$' mes2 db 10, 13, 'Адрес MCB блока: ' h2 db '0000:0000', 10, 13, '$' mes3 db 'Адрес следующего MCB блока: ' h3 db '0000:0000', 10, 13, '$' mes4 db 'Для продолжения нажмите любую клавишу (ESC - выход)...', 10, 13, '$' .code start: mov ax, @data call ClrScr mov ds, ax mov ax, 5200h int 21h mov memes, es mov membx, bx mov ax, es mov bx, offset h1 mov cx, 1 call ToHex mov ax, membx mov bx, offset h1+5 mov cx, 1 call ToHex mov dx, offset mes1 call PrnStr mov bx, membx sub bx, 2 mov ax, es:[bx] mov memes, ax s10: mov es, memes call PrnDump mov dx, offset mes4 call PrnStr s20: xor ax, ax int 16h cmp ah, 01h jz exit mov al, es:[0] cmp al, 'M' jz s10 exit: mov ax, 4c00h int 21h PrnDump proc mov ax, es mov bx, offset h2 mov cx, 1 call ToHex mov dx, offset mes2 call PrnStr mov dx, offset upline call PrnStr xor si, si xor dx, dx mov cx, 4 d10: push cx mov ax, es mov bx, offset hline+1 mov cx, 1 call ToHex mov ax, dx add bx, 5 mov cx, 1 call ToHex add dx, 8 mov cx, 8 add bx, 5 mov di, offset hline+35 xor ah, ah d20: push cx mov al, es:[si] mov cx, 0 call ToHex cmp al, 32 jb d30 cmp al, 127 jb d40 cmp al, 128 jb d30 cmp al, 242 jb d40 d30: mov al, '.' d40: mov [di], al add bx, 3 inc si inc di pop cx loop d20 push dx mov dx, offset hline call PrnStr pop dx pop cx loop d10 mov dx, offset dnline call PrnStr mov ax, es:[0003] mov bx, es add ax, bx inc ax mov memes, ax mov bx, offset h3 mov cx, 1 call ToHex mov dx, offset mes3 call PrnStr ret endp ToHex proc near pusha inc bx cmp cx, 0 jz th05 add bx, 2 th05: push ax and al, 0Fh cmp al, 09h ja th10 add al, '0' jmp th20 th10: add al, 55 th20: mov [bx], al pop ax dec bx shr al, 4 cmp al, 09h ja th30 add al, '0' jmp th40 th30: add al, 55 th40: mov [bx], al cmp cx, 0 jz th50 dec cx dec bx mov al, ah jmp th05 th50: popa ret ToHex endp PrnStr proc near pusha mov ah, 09h int 21h popa ret PrnStr endp ClrScr proc near pusha mov ax, 0600h mov bh, 07h mov cx, 0 mov dx, 184fh int 10h popa ret ClrScr endp .stack db 100h dup(?) end start
|