2016-05-29 10 views
1

Я хотел бы написать небольшую программу DOS (мой первый), и я немного неопытен.Как я могу получить дополнительный сегмент в DOS?

Для программы мне требуется более 64 килобайт (обычной) памяти. Как я могу получить дополнительную память? В идеале, я хотел бы иметь два дополнительных 64-килобайтных блока памяти для программы. Могу ли я начать записывать данные где-то в адресное пространство или мне нужно запросить дополнительную память?

+0

Какой ассемблер вы используете? –

+0

@RossRidge Я использую сборщик GNU, потому что я знаком с синтаксисом. – fuz

+0

Ах, это несчастливо. Ассемблер GNU неправильно поддерживает сегменты и не может использоваться для создания MS-DOS EXE. В противном случае вы могли бы просто определить два 64 тыс. Блоков памяти в исходном коде. –

ответ

3

В DOS, да, вы можете просто начать использовать другой сегмент памяти. Однако есть важная осторожность!

Посмотрите карту памяти для версии DOS, которую вы используете. Вы хотите быть уверены, что вы не выбираете область памяти, которая фактически зарезервирована для другой цели. Вот один из Dr. Dobb's Journal:

Address (Hex)     Memory Usage 

0000:0000    Interupt vector table 
0040:0000    ROM BIOS data area 
0050:0000    DOS parameter area 
0070:0000    IBMBIO.COM/IO.SYS * 
mmmm:mmmm    BMDOS.COM/MSDOS.SYS * 
mmmm:mmmm    CONFIG.SYS - specified information 
         (device drivers and internal buffers 
mmmm:mmmm    Resident COMMAND.COM 
mmmm:mmmm    Master environment 
mmmm:mmmm    Environment block #1 
mmmm:mmmm    Application program #1 
    .      .  .      .  .      . 
mmmm.mmmm    Environment block #n 
mmmm:mmmm    Application #n 
xxxx:xxxx    Transient COMMAND.COM 
A000:0000    Video buffers and ROM 
FFFF:000F    Top of 8086/88 address space 

«Официальный» механизм распределения памяти через управление памятью блоки (МПБ) и DOS прерывания 0x21 с помощью 0х48 выделить и 0x49, чтобы освободить память. Хорошее обсуждение этого можно найти в этом Microsoft support document.

Для документации на прерывание подхода, you might look here.

+0

Есть ли регион, который будет доступен во всех версиях DOS? – fuz

+1

Я добавил немного более подробно для использования прерываний DOS для выделения памяти.Я честно не могу вспомнить ничего, кроме нулевой страницы и видеопамяти с точки зрения того, что находится под DOS. :) –

+2

Для будущих читателей: вам разрешено перезаписывать область «Transient COMMAND.COM». Область перезагружается DOS, когда она перезаписывается пользовательским процессом. Это означает, что вы можете использовать всю память с CS: 0000 до A000: 0000, исключительную для вашего процесса. – fuz

2

Если мы начнем программу DOS выкладываться свободной памяти программы, и поэтому мы должны дать его обратно в DOS, прежде чем мы можем запросить новую память. Первым шагом является вычисление необходимой памяти нашей программы и возвращение остальных в DOS. Эта часть, которую мы должны разместить в начале нашей программы, до того, как будут обработаны SS, SP и ES.

mov  bx, ss 
mov  ax, es 
sub  bx, ax 
mov  ax, sp 
add  ax, 0Fh 
shr  ax, 4 
add  bx, ax 
mov  ah, 4Ah 
int 21h 

Следующий шаг - запросить новую память.

mov  bx, 2000h ; 128 KB 
mov  ah, 48h 
int 21h 
jc NOSPACE 
; AX = segment address 
+0

Благодарим вас за ответ. В программе COM, 'cs = ds = es = ss' при запуске, так нужен первый фрагмент? – fuz

+0

@FUZxxl: В программе '.COM' ** нет **, потому что программа' .COM' - это только один сегмент по умолчанию. Только программы .EXE могут иметь несколько сегментов. Таким образом, '.COM' ограничен до 64 КБ. – zx485

+0

Расчет для файла * .exe (MZ), который содержит разные адреса сегментов для кода, данных и для сегмента стека при запуске. Но также для COM-программы мы должны вернуть остальную память, прежде чем мы сможем запросить новую память. –

0

Вы можете получить любой сегмент, который вы хотите, установив один из регистров сегмента в нужное значение. Но имейте в виду, что

  • каждый сегмент начинается на границе 16 байт означает, что сегмент 0400 (смещение: 0000) был бы равен сегменту 0040 (смещение: 3c00) и еще один из 0000 (смещение: 4000) и т. д.
  • эти диапазоны перекрываются, это означает, что увеличение одного в регистре сегментов увеличивает абсолютный адрес памяти на 16.
  • , которые заданы и используются BIOS или других периферийных устройств в другом ответе от David Hoelzer
  • убедитесь, что ваш сегмент имеет размер 64 КБ и не перекрывается с другими сегментами