Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лр2 ПО ИП Новиков А.С..doc
Скачиваний:
0
Добавлен:
20.11.2019
Размер:
171.52 Кб
Скачать

Министерство образования и науки российской федерации федеральное государственное автономное образовательное учреждение высшего профессионального образования

«Национальный исследовательский ядерный университет «мифи»

Озерский технологический институт-филиал нияу мифи

Кафедра: Электроники и автоматики

Лабораторная работа №2

по дисциплине «ПО ИП»

Преподаватель

Изарова Е.Г.

Выполнил

студент группы

1ИТ-30

Новиков А.С.

(индекс группы)

(дата, подпись)

(Ф.И.О.)

2012

Структура программы на ассемблере. Представление простых типов данных.

Цель работы:

Изучить директивы описания данных простых типов; с помощью окна Dump отладчика tdebug.exe просмотреть область памяти, содержащую сегмент данных программы.

Теоретические сведения

Для описания простых типов данных в программе используются специальные директивы резервирования и инициализации данных, которые по сути являются указаниями транслятору на выделение определенного объема памяти. Если проводить аналогию с языками высокого уровня, то директивы резервирования и инициализации данных являются определениями переменных. Машинного эквивалента этим директивам нет; просто транслятор, обрабатывая каждую такую директиву, выделяет необходимое количество байт памяти и при необходимости инициализирует эту область некоторым значением. Директивы резервирования и инициализации данных простых типов имеют формат, показанный на рисунке.

Рисунок 1. Директивы описания данных простых типов.

? – показывает, что содержимое поля не определено, т.е. при задании директивы с таким значением выражения содержимое выделенного участка физической памяти изменяться не будет. Фактически создается неинициализированная переменная;

значение инициализации – значение элемента данных, которое будет занесено в память после загрузки программы. Фактически создается инициализированная переменная, в качестве которой могут выступать константы, строки символов, константные и адресные выражения в зависимости от типа данных;

выражение – итеративная конструкция с синтаксисом, описанным на рис.1 эта конструкция позволяет повторить последовательное занесение в физическую память выражения в скобках n раз;

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

На рис.1. представлены следующие поддерживаемые TASM директивы резервирования и инициализации данных:

db – резервирование памяти для данных размером 1 байт;

dw – резервирование памяти для данных размером 2 байт;

dd – резервирование памяти для данных размером 4 байт;

df – резервирование памяти для данных размером 6 байт;

dp – резервирование памяти для данных размером 6 байт;

dq – резервирование памяти для данных размером 8 байт;

dt – резервирование памяти для данных размером 10 байт для ДКД-чисел (BCD).

Очень важно запомнить порядок размещения данных в памяти. Он напрямую связан с логикой работы микропроцессора с данными. Микропроцессоры Intel требуют следования данных в памяти по принципу: младший байт по младшему адресу.

Листинг 1. Пример текста программы Prg_5_2.asm на языке ассемблера, с использованием директив резервирования и инициализации данных.

;---------Prg_5_2.asm---------------------------------------

; Пример использования директив резервирования и инициализации данных.

;-----------------------------------------------------------

masm

model small

.stack 100h

.data

message db 'Запустите эту программу в отладчике','$'

perem_1 db 0ffh

perem_2 dw 3a7fh

perem_3 dd 0f54d567ah

mas db 10 dup (' ')

pole_1 db 5 dup (?)

adr dw perem_3

adr_full dd perem_3

fin db 'Конец сегмента данных программы $'

.code

start:

mov ax,@data

mov ds,ax

mov ah,09h

mov dx,offset message

int 21h

mov ax,4c00h

int 21h

end start

Для того, чтобы посмотреть содержимое сегмента данных программы Prg_5_2.asm нужно создать исполняемый модуль prg_5_2.ехе с помощью командных строк:

tasm.exe /zi prg_5_2,,,

tlink.exe /v prg_5_2.obj.

Теперь можно производить отладку: td prg_5_2.exe.

Если все было сделано правильно, то в отладчике откроется окно Module с исходным текстом программы. Для того чтобы с помощью отладчика просмотреть область памяти, содержащую наш сегмент данных, необходимо открыть окно Dump. Это делается с помощью команды главного меню ViewDump.

Но одного открытия окна недостаточно: нужно еще настроить его на адрес начала сегмента данных. Этот адрес должен содержаться в сегментном регистре ds, но, как сказано выше, перед началом выполнения программы адрес в ds не соответствует началу сегмента данных. Нужно перед первым обращением к любому символическому имени произвести загрузку действительного физического адреса сегмента данных. Это действие производят двумя командами в сегменте кода. Действительный физический адрес сегмента данных извлекают как значение предопределенной переменной @data. В нашей программе эти действия выполняют команды:

mov ax, @data

mov ds, ax

Для того чтобы посмотреть содержимое нашего сегмента данных, нужно остановить выполнение программы после этих двух команд. Это можно сделать, если перевести отладчик в пошаговый режим с помощью клавиш F7 или F8. Нажмите два раза F8. Теперь можно открыть окно Dump.

В окне Dump вызовите контекстное меню, щелкнув правой кнопкой мыши. В появившемся контекстном меню выберите команду Goto. Появится диалоговое окно, в котором нужно ввести начальный адрес памяти ds:0000, начиная с которого будет выводиться информация в окне Dump.

Рассмотрим рисунок 2. На нем вы видите данные Вашего сегмента в двух представлениях: шестнадцатеричном и символьном. Видно, что со смещением 0000 расположены символы, входящие в строку message. Она занимает 34 байта. После нее следует байт, имеющий в сегменте данных символическое имя perem_1, содержимое этого байта 0ffh. (Если шестнадцатеричное число начинается с латинской буквы, то перед ней ставится нуль. Это необходимо транслятору для того, чтобы можно было отличить текст от чисел.) Теперь обратите внимание на то, как размещены в памяти байты, входящие в слово, обозначенное символическим именем perem_2. Сначала следует байт со значением 7fh, а затем со значением 3ah. Как видите, в памяти действительно сначала расположен младший байт значения, а затем старший.

Теперь посмотрите и самостоятельно проанализируйте размещение байтов для поля, обозначенного символическим именем perem_3. Оставшуюся часть сегмента данных вы можете теперь проанализировать самостоятельно.

Остановимся лишь на двух специфических особенностях использования директив резервирования и инициализации памяти. Речь идет о случае использования в поле операндов директив dw и dd символического имени из поля имя этой или другой директивы резервирования и инициализации памяти. В нашем примере сегмента данных это директивы с именами adr и adr_full. Когда транслятор встречает директивы описания памяти с подобными операндами, то он формирует в памяти значения адресов тех переменных, чьи имена были указаны в качестве операндов. В зависимости от директивы, применяемой для получения такого адреса, формируется либо полный адрес (директива dd) в виде двух байтов сегментного адреса и двух байтов смещения, либо только смещение (директива dw).

Найдите в дампе на рисунке 2 поля, соответствующие именам adr и adr_full и проанализируйте их содержимое.

Dump

ds: 0000 87 A0 AF E3 E1 E2 A8 E2 Запустит

ds: 0008 A5 20 ED E2 E3 20 AF E0 е эту пр

ds: 0010 AE A3 E0 A0 AC AC E3 20 ограмму

ds: 0018 A2 20 AE E2 AB AO A4 E7 в отладч

ds: 0020 A8 AA A5 24 FF 7F 3A 7A ике$ :z

ds: 0028 56 4D F5 20 20 20 20 20 VMI

ds: 0030 20 20 20 20 20 00 00 00

ds: 0038 00 00 27 00 27 00 42 1B ‘ ‘ B

ds: 0040 8A AE AD A5 E6 20 E1 A5 Конец се

ds: 0048 A3 AC A5 AD E2 A0 20 A4 гмента д

ds: 0050 A0 AD AD EB E5 20 AF E0 анных пр

Рисунок 2. Окно дампа памяти.

Любой переменной, объявленной с помощью директив описания простых типов данных, ассемблер присваивает три атрибута:

  1. Сегмент (seg) – адрес начала сегмента, содержащего переменную.

  2. Смещение (offset) в байтах от начала сегмента с переменной.

  3. Тип (type) – определяет количество памяти, выделяемой переменной в соответствии с директивой объявления переменной.

Получить и использовать значение этих атрибутов в программе можно с помощью рассмотренных операторов ассемблера seg, offset, и type.