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


Еще немного о сегментации памяти.


Давайте возьмем часть примера, который мы уже рассматривали, но кое-что в нем упустили.

(1) ... (2) mov ah,9 (3) mov dx,offset My_string (4) int 21h (5) .... (6) My_string db 'Ура!$' (7) ...

Опустим некоторые операторы: строки (1), (5) и (7). Их вы уже знаете.

В строке (3) загружаем в регистр DX АДРЕС строки в памяти. Обратите внимание на запись: mov dx,offset My_string. Вы уже знаете, что оператор mov загружает в регистр число. Например:

mov cx,125

В строке (3) мы видим пока еще неизвестный нам оператор offset. Что же он делает? И почему нельзя записать вот так:

mov dx,My_string?

Offset по-английски - это смещение. Когда, при ассемблирвании, Ассемблер дойдет до этой строки, он заменит

offset My_string на АДРЕС (смещение) этой строки в памяти. Если мы запишем

mov dx,My_string (хотя, правильнее будет

mov dx,word ptr My_string,

но об этом позже), то в DX загрузится не адрес (смещение), а первые два символа нашей строки (в данном случае "Ур"). Почему два? Вы не знаете? Потому, что DX - шестнадцатиразрядный регистр, в который можно загрузить два байта. А один символ, как вы уже знаете, всегда один байт.

Можно записать и так:

mov dl,My_string

(здесь правильнее будет

mov dl,byte ptr My_string). В этом случае что будет находится в DL? Символ "У"! Потому, что DL восьмиразрядный регистр и может хранить только один байт.

Несколько слов про записи вида

mov dl,byte ptr My_string и

mov dx,word ptr My_string.

Byte (думаю, все знают) - это байт. Word - слово (два байта). Посмотрите внимательно на приведенные выше строки. Вы заметите, что когда используется восьмиразрядный регистр (DL), мы пишем

byte. А когда шестнадцатиразрядный (DX) - word. Это указывает Ассемблеру, что мы хотим загрузить именно байт либо слово.

Вспомним, что в DOS для формирования адреса используется сегмент и смещение. Данный пример - не исключение. Для формирования адреса строки "Ура!$" используется пара регистров DS (сегмент) и DX (смещение). Почему же мы ничего не загружаем в DS? Дело в том, что при загрузке *.com-программы в память (а мы пока создаем только такие), все сегментные регистры принимают значение равное тому сегменту, в который загрузилась наша программа (в т.ч. и DS). Поэтому нет необходимости загружать в DS сегмент строки (он уже загружен). Программа типа *.com всегда занимает один сегмент, поэтому размер программ такого типа ограничен 64 килобайтами. Помните, почему?




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



Книжный магазин