Ассемблер Это просто! Учимся программировать


Сегментация памяти в DOS - часть 3


  • CSEG (даем имя сегменту) segment (оператор Ассемблера, указывающий, что имя CSEG - это название сегмента);
  • CSEG ends (END Segment - конец сегмента) указывает Ассемблеру на конец сегмента.
  • Строка (02) сообщает, что код программы (как и смещения внутри сегмента CSEG) необходимо отсчитывать с 100h. По этому адресу в память всегда загружаются программы типа *.com.

    Запускаем программу из Примера № 3 в отладчике. Допустим, она загрузилась в свободный сегмент 1234h. Первая команда в строке (04) будет располагаться по такому адресу:

    1234h:0100h (т.е. CS = 1234h, а IP = 0100h) (посмотрите в отладчике на регистры CS и IP).

    Перейдем к следующей команде (в отладчике CodeView нажмите клавишу F8, в AFD - F1, в другом - посмотрите какая клавиша нужна; будет написано что-то вроде "F8-Step" или "F7-Trace"). Теперь Вы видите, что изменились следующие регистры:

    • AX = 0900h (точнее, AH = 09h, а AL = 0, т.к. мы загрузили командой mov ah,9 число 9 в регистр AH, при этом не трогая AL. Если бы AL был равен, скажем, 15h, то после выполнения данной команды AX бы равнялся 0915h)
    • IP = 102h (т.е. указывает на адрес следующей команды. Из этого можно сделать вывод, что команда mov ah,9 занимает 2 байта: 102h - 100h = 2).

    Следующая команда (нажимаем клавишу F8 / F1) изменяет регистры DX и IP. Теперь DX указывает на смещение нашей строки ("Dima$") относительно начала сегмента, т.е. 109h, а IP равняется 105h (т.е. адрес следующей команды). Нетрудно посчитать, что команда mov dx,offset My_name занимает 3 байта (105h - 102h = 3).

    Обратите внимание, что в Ассемблере мы пишем:

    mov dx,offset My_name

    а в отладчике видим следующее:

    mov dx,109 (109 - шестнадцатеричное число, но CodeView и многие другие отладчики символ 'h' не ставят. Это надо иметь в виду).

    Почему так происходит? Дело в том, что при ассемблировании программы, программа-ассемблер (MASM / TASM) подставляет вместо offset My_name реальный адрес строки с именем My_name в памяти (ее смещение). Можно, конечно, записать сразу:




    Начало  Назад  Вперед