Продолжу тему со структурами MS DOS, в этой теме рассмотрю блоки управления памятью, а также напишу программу для вывода на экран всех блоков управления памятью в операционной системе.
MCB (Memory control block) - область памяти, которая описывает сегменты, определённые в MS DOS, для каждого сегмента существует свой MCB, эти структуры заполняются операционной системой во время загрузки программ в оперативную память.
Структура блока управления памятью:
(0) db type тип блока MCB (M или Z), M - промежуточный блок, Z - последний блок управления памятью
(+1)dw owner параграф владельца блока (если 0, то блок описывает сам себя)
(+3)dw size число параграфов в этом блоке (один параграф имеет размер 16 байт)
(+5)11d reserve зарезервировано
При загрузке исполняемого файла com в память, ОС выделяет несколько блоков управления памяти, в оперативной памяти они расположены в такой последовательности:
- MCB для блока переменных среды;
- Блок памяти переменных среды;
- MCB для префикса программного сегмента;
- Префикс программного сегмента;
- Программа.
Теперь напишу программу, которая выведет на экран все активные MCB в операционной системе:
Код: Выделить всё
.model tiny
.286
code segment
org 100h
start:
;Get first MCB
mov ah, 52h
int 21h
push word ptr es:[bx-2]
pop es
xor bx, bx
;Display header of table
mov ah, 9d
lea dx, msg
int 21h
;Get info from MCB and display it
get_inf:
;Write segment of mcb in hex ascii in structure
push es
push offset display.addr_
call hex_ascii
;Write type of mcb in hex ascii in structure
mov al, byte ptr es:[bx]
mov display.type_+3, al
;Write owner of mcb in hex ascii in structure
push word ptr es:[bx+1]
push offset display.owner
call hex_ascii
;Write size in hex ascii in structure
push word ptr es:[bx+3]
push offset display.size_
call hex_ascii
;Display string
mov ah, 9d
lea dx, display
int 21h
cmp byte ptr es:[bx], 'Z'
jz exit
;Go to next MCB
mov ax, es
add ax, word ptr es:[bx+3]
inc ax
mov es, ax
jmp get_inf
exit:
mov ax, 4c00h
int 21h
;-------------------------------------------------
;TRANSFORMATE HEX NUMBER IN ASCII CODE PROCEDURE.
;PARAMETERS(STACK):
;- NUMBER;
;- OFFSET;
hex_ascii proc uses ax di cx bp bx
mov bp, sp
mov ax, word ptr ss:[bp+14]
mov di, word ptr ss:[bp+12]
push ax
mov bp, sp
mov cx, 4d
transform:
rol ax, cl
mov bx, ax
and ax, 0Fh
cmp al, 9d
ja letter
or al, 30h
jmp continue
letter:
add al, 37h
continue:
mov byte ptr[di], al
cmp word ptr ss:[bp], bx
jz exit_proc
mov ax, word ptr ss:[bp]
inc di
add cl, 4d
jmp transform
exit_proc:
pop ax
ret 4
hex_ascii endp
msg db 'SEG ', 'TYPE '
db 'OWNER ', 'SIZE', 0Ah, 0Dh, 24h
display_ struc
addr_ db 4d dup(0), 9d
type_ db 4d dup(0), 9d
owner db 4d dup(0), 9d
size_ db 4d dup(0), 9d, 0Ah, 0Dh, 24h
display_ ends
display display_ <>
code ends
end start
Таким образом, мы видим, как операционная система "понимает" в какую область памяти загружать программы, для этого и существует структура MCB. MS DOS проверяет наличие свободных блоков памяти, проверяет их размер, если есть блок памяти соответствующего размера, то наша программа будет загружена и выполнена.
Была использована версия компилятора MASM 6.11 в контексте операционной системы MS DOS 6.22!
Спасибо за внимание!
С уважением, push0ret!