Шаг 9 - Указатель на данные

Итак, мы знаем, что регистр DS указывает на сегмент данных, но ведь данных может быть много, например, много строк, вот для этого и используется адресация сегмент - смещение. Вообще подобная адресация была создана в связи с необходимостью адресации к большему диапазону чем позволяет число 16 бит. В нашем случае нам нужно еще и получить указатель на данные. И мы это делали.

DATASEG Hellostr DB 'Hello First Step Site ' CODESEG start: ...... mov dx,offset Hellostr

Мы использовали offset это команда умеет вычислять как смещены определенные данные относительно сегмента данных в нашем случае строка. При сборки приложения в это место будет поставлено конкретное число.


А вот комбинация DS - смещение(эти число) будут указывать нам на местоположение строки. Вот смотрите


После того как регистр DS выставлен нам больше нечего не волнует. Мы просто указываем относительно него смещение в данном случае (001С) и получаем первую букву нашей строки. Вот именно выяснением этого числа и занимается offset.

Итак, у наших данных есть понятие смещение, которое высчитывается относительно регистра DS. Для этого есть команда offset

Offset имя_переменной

Шаг 10 - Turbo Debugger для DOS

После установки TASM Вы можете его найти через ПУСК:


Запускаем. Вот он какой:

Давайте через меню File откроем нашу программу (попасть в меню F10 смотри подсказку ниже). После загрузки Вы увидите машинный код который является как раз почти точной копией нашего кода.

Нажимая на клавишу F8 Вы можете передвигаться по каждой команде наблюдая за тем как меняются регистры и но кроме этого Вы можете просматривать в окнах содержимое памяти. Давайте остановимся рядом прямо перед прерыванием на вывод строки.

Перейдем в окно ниже кода и щелкнем правой кнопкой мыши:

И вот теперь выберем пункт меню Goto, указав адрес:


Вот теперь мы и видим наше строку по смещению DS:001C (смещение можно увидеть в регистрах):

 

 

Шаг 11 - JMP или прыжок

Использование этого оператора позволяет нам перемещаться по коду. То есть фактически команда JMP меняет регистр IP. Переход производится на метку. Итак, нам нужно указать команду перехода:

JMP метка

И саму метку

метка:

Давайте изменим пример шага "Шаг 3 - Программа HelloWord". Так, чтобы обойти вывод строки:

MODEL TINYSTACK 256 DATASEG Hellostr DB 'Hello First Step Site 'CODESEG start: mov ax,@data mov ds,ax jmp w1 mov bx,1 mov cx,21 mov dx,offset Hellostr mov ah,40h int 21hw1: mov ah, 04Ch mov al, 1h int 21hend start

Мы просто переходим на метку. А теперь смотрим, как все это выглядит в отладчике:

В результате у процессора есть точно такая же команда перехода. Нажимаем на F8 еще раз:

Обратите внимание, что регистр IP стал 0015 в данном случае, то есть JMP указывает IP куда нужно переместить указатель команд. После выполнения указатель команд стоит по этому адресу, а ненужные команды мы проскочили.

Итак JMP позволяет нам произвольно перемещаться по коду.

 

 

Шаг 12 - Что такое стек

Стек - это специальная область памяти. Адресацией в этой области управляет регистр SP или указатель стека. Используется эта память в основном для временного хранения содержимого регистров. Именно временного. Самое главное понять, как стек работает. А работает он по принципу первый пришел последний ушел. Давайте представим. Я ложу книгу на стол. Потом сверху еще одну книгу. Первая книга внизу. Что бы извлечь ее мне сначала нужно снять верхнею и только после этого я получу доступ к первой. Но можно просто в жизни ее выдернуть. Можно. Представьте себе кучу книг до потолка. Попробуйте выдернуть нижнею. Есть огромный шанс что Вас этими книгами и завалит. То же будет и с Вашей программой. Для работы со стеком используются команды. Для того, чтобы положить в стек:

Push регистр

Для извлечения:

Pop регистр

Изменим пример из шага "Шаг 3 - Программа HelloWord". Вот код:

MODEL TINYSTACK 256 DATASEG Hellostr DB 'Hello First Step Site 'CODESEG start: mov ax,@data mov ds,ax mov ah,04Ch mov al,1h push ax mov bx,1 mov cx,21 mov dx,offset Hellostr mov ah,40h int 21h pop ax int 21hend start

Что вы должны были заметить? Что настройку регистра AX я сделал в самом начале программы. И сохранил в стек.

push ax

Потом этот регистр мы изменяем для вызова функции строки:

mov ah,40hint 21h

И в самом конце мы с Вами восстанавливаем содержимое регистра AX из стека:

pop ax

Так, нам пора в отладчик. В самом начале указатель стека 100:


Дойдем до выполнения push:

После его выполнения указатель стека изменится. А теперь дойдем до pop перед ее выполнением.

Указатель стека не изменился. В регистре AX находится какое-то значение. Выполним команду:

Указатель стека вернулся на исходную позицию, а в регистре появилось наше сохраненное значение.

 

 





©2015-2017 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.

Обратная связь

ТОП 5 активных страниц!