Вот как это запишется на
Давайте попробуем загрузить в пару регистров ES:DI сегмент и смещение буквы "м" в слове "памяти" из Примера № 1 (см. выше). Вот как это запишется на Ассемблере:
(1) mov ax,0020 (2) mov es,ax (3) mov di,2
Теперь в регистре ES находится сегмент с номером 20, а в регистре DI - смещение к букве (символу) "м" в слове "памяти". Проверьте, пожалуйста...
Здесь стоит отметить, что загрузка числа (т.е. какого-нибудь сегмента) напрямую в сегментный регистр запрещена. Поэтому мы в строке (1) загрузили сегмент в AX, а в строке (2) загрузили в регистр ES число 20, которое находилось в AX:
mov ds,15 // ошибка!
mov ss,34h // ошибка!
Когда мы загружаем программу в память, она автоматически располагается в первом свободном сегменте. В файлах типа *.com все сегментные регистры автоматически инициализируются для этого сегмента (устанавливаются значения равные тому сегменту, в который загружена программа). Это можно проверить при помощи отладчика. Если, например, мы загружаем программу типа *.com в память, и компьютер находит первый свободный сегмент с номером 5674h, то сегментные регистры будут иметь следующие значения:
CS = 5674h
DS = 5674h
SS = 5674h
ES = 5674h
Иначе говоря: CS=DS=SS=ES=5674h
Код программы типа *.com должен начинаться со смещения 100h. Для этого мы, собственно, и ставили в наших прошлых примерах программ оператор ORG 100h, указывая Ассемблеру при ассемблировании использовать смещение 100h от начала сегмента, в который загружена наша программа (позже мы рассмотрим почему так). Сегментные же регистры, как я уже говорил, автоматически принимают значение того сегмента, в который загрузилась наша программа.
Пара регистров CS:IP задает текущий адрес кода. Теперь рассмотрим, как все это происходит на конкретном примере:
Пример № 3.
(01) CSEG segment (02) org 100h (03) _start: (04) mov ah,9 (05) mov dx,offset My_name (06) int 21h (07) int 20h (08) My_name db 'Dima$' (09) CSEG ends (10) end _start
Итак, строки (01) и (09) описывают сегмент: