Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Met_Lab2_121113

.pdf
Скачиваний:
16
Добавлен:
11.05.2015
Размер:
1.72 Mб
Скачать

%1

:exit

Здесь ключ компилятора zi служит для включения в obj-файл информации для работы отладчика ключ I разрешает генерацию файла листинга. Ключ компоновщика v служит для включении в ехе-файл информации для работы отладчика, ключ х подавляет генерацию map файла.

Данный текст необходимо ввести в файл пакетной обработки BAT. Данный набор команд производит автоматически 2й и 3й шаги, описанные выше, сначала запускается транслятор tasm.exe, если написанная программа прошла трансляцию без ошибок, то запускается компоновщик tlink.exe, если и компоновка прошла успешно, то происходит запуск созданного после компоновки исполняемого модуля.

Здесь запись %1 заменяется параметром, поданым на вход при запуске этого BAT файла. Например, имеется созданый BAT файл с именем Compile.bat, и если при его запуске указать параметр, например, prog, то реально выполнится следующий набор команд:

echo off

tasm -zi -l prog

if errorlevel 1 goto exit tlink -v -x prog

if errortevel t goto exit prog

:exit

Замечание. Желательно в качестве параметра использовать только имя файла программы, не указывая его расширение, поскольку на трансляцию подается файл с раширением ASM, на компоновку с расширением OBJ, а на запуск EXE или COM. Транслятору и компоновщику из пакета TASM не обязательно указывать расширение.

Все команды DOS, вводимые в командную строку, а так же запускаемые из пакетных файлов, в том числе и запуск исполняемых модулей работает в следующей последовательности:

Проверяется, не ввёл ли пользователь имя внутренней команды DOS (в том числе и имя внутренней утилиты, например ATTRIB). Если введена внутренняя команда, она будет выполнена.

Проверяется текущая директория на предмет выявления программного файла с именем и расширением .com или .exe. и только затем ищется командный файл с расширением .bat. Найденный файл исполняется.

Если ничего из перечисленного в пп. 1 и 2 не найдено, то система начнёт поиск по путям, записанным в файле Autoexec.bat (Windows 9x) или в Autoexec.nt (Windows 2000).

Если система не находит ни команду, ни имя исполняемого файла, то выводится соответствующее сообщение.

Для того чтобы постоянно не скидывать в одну папку с написанной программой

компилятор, компоновщик и их вспомогательные модули, а так же и сам BAT файл, можно записать в файл Autoexec.bat путь к папке, в которой располагаются эти файлы. Производится это с помощью команды PATH.

Добавляем следующую строку в файл Autoexec.bat: PATH=Путь к папке с компилятором и транслятором

41

К примеру, если пакет TASM установлен в папку C:/Tasm, то нужно будет записать

строку

PATH C:/Tasm/Bin

После сохранение необходимо будет перезапустить операционную систему. После этого, при попытке запуска каких либо исполняемых файлов из строки DOS (из любой папки), будет происходить просмотр указаной папки на предмет наличия в нем запускаемого файла.

Для дальнейшей работы запишите в файл Autoexec.bat команду PATH с указанием пути до папки Bin пакета Tasm.

2.1.2. Компиляция программы. Опции командной строки

Рассмотрим процесс трансляции программы на примере простой интерактивной программы Hello.asm (см. лаб. Работу № 1). Для ассемблирования файла Hello.asm в командной строке наберите:

tasm hello.asm

и нажмите клавишу Enter. Поскольку Вы не задали другое имя для объектного файла, то будет создан объектный файл с этим же именем hello.obj. Заметим, что расширение имени файла .asm вводить не требуется, т.к. tasm принимает это по умолчанию. На экране вы увидите следующее:

Turbo Assembler Version 4.1 Copyright (C) 1988,1996 Borland International

Assembling file: Hello.asm

Error messages: None

Warning messages: None

Passes 1

Remaining memory: ***K

Из сообщения следует, что ассемблирование завершено без ошибок (Error messages: None) и отсутствия предупреждений (Warning messages: None). Предупреждение не является ошибкой, однако его игнорирование может привести к неприятностям в дальнейших этапах работы с программой, поэтому лучше своевременно реагировать на данный тип замечаний. Если в программе имеются ошибки, транслятор в сообщении в строке Error messages: укажет количество ошибок и в

последующих строках опишет каждую ошибку, в т.ч. номер строки в

которой находится ошибка.

Для компоновки программы введите в командную строку: tlink hello.obj.

Здесь, также как и при ассемблировании, расширение имени obj не является обязательным. По завершению компоновки будет сформирован файл hello.exe с выводом на экран сообщения.

Turbo Linker Version 7.1. 30.1 Copyright (C) 1987,1996 Borland International

Теперь программу hello.exe можно запустить на исполнение, результатом которого будет вывод на экран сообщения:

Это время после полудня? (Да/Нет-Y/N)

42

Курсор будет мерцать после последнего символа в ожидании ввода ответа. Введите букву y. Программа ответит:

Здравствуйте!

Если будет введена строчная буква n, то программа ответит: Доброе утро!

В процессе ассемблирования или компоновки вы можете выбирать различные исполнения процесса, которые задаются опциями в командной строке Tasm или Tlink. Для вывода списка опций командной строки Turbo Assembler наберите tasm и нажмите <Enter>; то же самое проделайте с командой tlink.

Опции описываются одной или несколькими буквами. Для задания опции наберите косую черту (или дефис) и соответствующую букву между командой tasm или tlink и именем программы, которую вы ассемблируете либо компонуете. Например, для ассемблирования программы Hello.asm и получения файла с листингом (файл, в котором содержится описание процесса ассемблирования), используйте команду: tasm/l hello. Опции разрешается набирать как прописными, так и строчными буквами. Исполните эту команду и затем рассмотрите файл с листингом Hello.lst, используя текстовый редактор. В листинге каждая строка начинается с номера, затем следуют байты объектного кода и, наконец, собственно текст программы. Кроме того, TASM выводит в файле листинга таблицу идентификаторов, где содержится информация о метках и сегментах, включая значение и тип каждой метки и атрибуты каждого сегмента. При ассемблировании программы вы можете использовать в одной командной строке несколько опций, разделяя их косыми чертами. Рассмотрим некоторые примеры для команды tasm:

tasm/l/c hello – команда дополняет файл листинга таблицей перекрёстных ссылок, в которой указывается, где была определена каждая метка и где на неё есть ссылка;

tasm/l/n hello – исключает таблицу идентификаторов из листинга;

tasm/ml – включает различие прописных и строчных символов в пользовательских идентификаторах;

tasm/zi hello – команда добавляет в Hello.obj информацию, необходимую для использования отладчика Turbo Debugger.

Для команды tlink:

tlink/v hello – опция /v включает в Hello.exe информацию, необходимую для последующего открытия этого файла в отладчике Turbo Debugger;

tlink/m hello – опция /m приводит к созданию файла отображения или файла загрузки Hello.map. В нём перечисляются имена, адреса загрузки и размеры всех сегментов, входящих в программу;

tlink/x/v hello – команда даёт возможность загрузить Hello.exe в отладчик Turbo Debugger, запрещает создание (опция /x) файла отображения.

Tlink/3 <file_name.obj> – компоновщик создаёт файл типа .exe с поддержкой 32-битного кода.

Tlink/t <file_name.obj> – опция /t создаёт файл типа .com.

43

2.2. Cинтаксис ассемблерной программы

Алфавит Ассемблера включает большие и малые буквы ленинского алфавита, символ подчеркивания (который также считается буквой), цифры и спецсимволы. По умолчанию, различий между большими и малыми буквами не далается, однакоможно задать опцию компилятора, при которой большие и малые буквы будут различаться. Буквы кириллицы допустимы только в комментариях и в значениях символьных переменных и констант.

Лексемами Ассемблера могут быть ключевые слова, именавводимые пользователем и числа. Имя должно состоять из латинских буквицифр причем первым символом имени должна быть буква. Внутри имени не должно быть пробелов.

Программа на Ассемблере состоит из и команд и директив. Различие между директивами и командами следующее: при компиляции команда непосредственно порождает команду процессора, директива не порождает команд процессора, а служит для описания переменных, задания режимов работы компилятора и проч.

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

Формат команды:

Метка: Мнемокод Операнды ;Комментарий

Формат директивы:

Имя Мнемокод Операнды ;Комментарий

При набивке программы удобно отделять одно поле от другого знаком табуляции, тогда программа будет располагаться в удобночитаемом виде в четыре колонки (хотя это и не обязательно).

2.3. Простейшая программа

Напишем простейшую программу, выводящую на экран сообщение и неформально объясним, как она работает.

1IDEAL

2MODEL small

3

STACK

256

 

4

DATASEG

 

5

Message

DB

'Hello, World $'

6

CODESEG

 

7

Start:

mov

ax,@data

8

 

mov

ds,ax

9

 

mov

ah,09h

10

 

mov

dx,offset Message

11

 

int

21h

12

Exit:

mov

ax,4C00h

13

 

int

21h

14

END

Start

Стоящие в левой колонке номера строк частью программы не являются и введены только для облегчения дальнейшего объяснения программы.

Для понимания этой программы необходимо отметить, что в любой программе на Ассемблере необходимо выполнить некоторые действия, не связанные непосредственно с задачей, которую выполняет данная программа, своего рода "накладные расходы". Эти действия связаны, в основном, с организацией сегментной адресации.

44

Приступим к построчному анализу программы: Строка 1: Переводит Turbo Assembler в режим Ideal.

Строка 2: Директива описания модели памяти. Вводит упрощенные директивы управления сегментами.

Строка 3: Резервирует пространство для стека программы (значение в байтах, следующее за директивой).

Строка 4: Начало сегмента инициализированных данных. Допускается также расположение здесь и неинициализированных данных, начальные значения которых неизвестны на момент запуска программы.

Строка 5: Директива db определяет переменную Msg как строку байт и инициализирует ее. Символ $ означает конец строки.

Строка 6: Начало сегмента кода, т.е. части программы, содержащей команды процессора.

Строка 7: Точка начала исполнения программы. Загрузка в AX адреса начального параграфа сегмента данных.

Строка 8: Загрузка в DS адреса начального параграфа сегмента данных из AX. Сразу возникают два вопроса. Почему это (строки 7 и 8) нельзя сделать одной командой? Потому что сегментные регистры можно загрузить только из регистров общего назначения и никаким другим образом. Почему мы таким же образом не загружаем регистры CS и SS? Потому что регистр команд загружается автоматически при запуске программы из DOS, то же самое происходит с регистром стека.

Строки 9-10: Подготовка к вызову 21-го прерывания для вывода сообщения на экран. Для взаимодействия с внешними устройствами (и с видеокартой в том числе), имеются процедуры DOS, оформленные в виде прерываний. Мы будем пользоваться, в основном, прерываниями 10h и 21h. Каждое из этих прорываний представляет собой целое собрание различных процедур, снабженных номерами. При возникновении необходимости взаимодействия с внешним устройствам нужно загрузить в регистр АН номер требуемой процедуры, в другие регистры загрузить данные, необходимые для работы требуемой процедуры и, наконец, вызвать необходимое прерывание, В данном случае мы загружаем в регистр АН номер 09h процедуры вывода строки на экран, а а регистр DX - cмещение начала строки сообщения (значение сегмента будет взято из сегментного регистра DS). Ключевое слово offset является оператором преобразующим операнд Message в ого смещение внутри сегмента данных.

Строка 11: Команда int вызывает прерывание с указанным номером. В Данном случае происходит вывод строки на экран.

Строка 12: Подготовка к вызову 21-го прерывания для завершения программы. Завершение любой программы есть по существу передача управления в другую программу (например в DOS). Такая передача управления также выполняется при помощи 21-го прорыанния процедурой номер 4Ch. Строка 12 может выглядеть и как Exit: mov ah,4Ch. Разницы нет никакой.

Строка 13: Вызов 21-го прерывания для завершения программы. Строка 14: Директива конца программы/точки входа.

45

2.4. Скелет (каркас) программы

Программы, выполненные под управлением DOS (сеанс MS-DOS для Windows), могут принадлежать к одному из двух типов, которым соответствуют расширения имён программных файлов .com и .exe. Основное различие этих программ заключается в том, что программы типа .com состоят из единственного сегмента объёмом в 64 Кбайт, в котором размещаются программный код, данные и стек, а в программах типа .exe для каждого из них выделяются отдельные сегменты. Управление сегментами – один из наиболее сложных аспектов программирования на языке ассемблера. При этом ассемблер имеет не один, а целых два набора директив управления сегментами. Первый набор, включающий упрощенные директивы определения сегментов, позволяет достаточно просто ими управлять и идеально подходит для компоновки ассемблерных модулей с языками высокого уровня (Pascal и С). Второй набор, включающий стандартные директивы определения сегментов, предназначен для построения сложных ассемблерных программ. В данном лабораторном практикуме, как правило, применяются упрощенные директивы, введение которых возможно лишь с одновременным указанием используемой модели памяти. В свою очередь, модель памяти неявно задаёт атрибуты упрощенных директив, определяющих действия компоновщика Turbo Linker при формировании исполнительного файла программы.

2.4.1. Модуль EXE

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

1

 

IDEAL

2

MODEL

small

3

STACK

256

4DATASEG

5CODESEG

6

Start:

mov

ax,@data

7

 

mov

ds,ax

8

Exit:

mov

ax,4C00h

9

 

int

21h

10

END

Start

 

Таким образом, используя данный скелет, можно съэкономить время при подготовке новых программ.

2.4.2. Модуль COM

Для программ типа COM:

1

 

IDEAL

2

MODEL

Tiny

3DATASEG

4CODESEG

5

Org

100h

 

6

Proc

main

 

7

Exit:

mov

ax,4C00h

8

 

int

21h

9

Endp

main

 

10

End

main

 

Из отличий от программы EXE можно выделить следующие:

46

Модель памяти описывается как Tiny;

Установка адреса начала программы (5я строка);

Организация командной части выполнена в виде процедуры main.

2.5.Образ программы в памяти

Образ программы в памяти, представленный на рис. 1.1., начинается с префикса программного сегмента PSP (Program Segment Prefix). PSP всегда имеет размер 256 байтов и содержит данные, используемые операционной системой в процессе исполнения программы. Вслед за PSP располагаются сегменты программы. Сегментные регистры ES и DS автоматически инициализируются на начало PSP. Это даёт возможность, при сохранении значения одного из регистров, обращаться к PSP в случае необходимости. В указатель команд IP загружается относительный адрес точки входа в программу (операнд директивы E0D), а в указатель стека SP – смещение конца сегмента стека. Таким образом, после загрузки программы в память, адресуемыми являются все сегменты, кроме сегмента данных. Использование директивы MODEL, делает доступным ассемблеру несколько служебных идентификаторов, к которым можно обращаться во время работы программы, чтобы получить информацию об адресах используемых сегментов. Например:

@code – 16-разрядный адрес сегмента кода;

@data – 16-разрядный адрес сегмента данных типа near;

@stack – 16-разрядный адрес сегмента стека.

2.5.1. Модуль EXE

Рис. 1.1. Образ программы EXE в памяти

Объём памяти, занимаемый программой: (138B-1373)*10h+100h=280h=640 байт. Завершение программы означает передачу управления командному процессору DOS –

Command.com, который выводит на экран системный запрос в ожидании следующей команды от оператора. Делается это с помощью функции DOS (AH = 4Ch). Эта функция требует единственного параметра – кода возврата, который и помещается программой в регистр al. Если этот код равен нулю, то исполнение программы прошло корректно, в противном случае была допущена ошибка в предшествующих обращениях программы к другим системным функциям DOS.

2.5.2. Модуль COM

Образ памяти программы типа .com показан на рис. 1.2. После загрузки программы в память все 4 сегментных регистра указывают на начало единственного сегмента – PSP.

47

Указатель стека автоматически инициализируется числом 0FFFEh. Таким образом, независимо от фактического размера программы, ей выделяется 64 Кбайт адресного пространства, нижнюю часть которого занимает стек.

Рис. 1.2. Образ программы COM в памяти

2.6. Работа с отладчиком Turbo Debugger (TD)

Tasm умеет ассемблировать синтаксически правильные программы, но не понимает, что, собственно, эта программа делает. Часто программа работает не так, как, по вашему мнению, должна была бы работать. В такой ситуации может помочь TD-программа, разработанная для поиска и исправления логических ошибок. Подобно всем отладчикам TD может работать в режиме супервизора, беря на себя управление программой в режиме пошагового исполнения, кода программы. Можно при этом изменять значения операндов в памяти, а также значения регистров и флагов. TD используется и в качестве учителя при изучении форматов машинных команд процессора в различных режимах адресации операндов.

Чтобы показать, как использовать TD при изучении языка ассемблера, исследуем программу Hello под управлением отладчика. Произведём заново ассемблирование и компоновку программы с опциями, которые добавляют отладочную информацию в obj- и exe-файлы:

tasm/zi hello.asm tlink/v hello.obj td hello.exe

После выполнения последней команды на экране увидите окно Module с исходным текстом программы Hello.asm. Это окно номер 1. Просмотреть программу можно, используя клавиши управления курсором, передвигая его вверх и вниз по тексту.

Для получения другого представления программы войдите в меню Viev [вид], выберите команду Cpu и нажмите <F5> для распахивания окна на весь экран. В Cpu-окне, состоящем из пяти областей, содержится в сокращённом виде исходный текст вашей программы, действительные машинные коды, находящиеся в памяти, значения регистров и флагов, стек и дамп байтов памяти. Для передвижения курсора из одной области в другую нажимайте клавишу <Tab>.

Область окна Cpu, в которой находится курсор, считается активной. Нажатие клавиши <Alt+F10> вызывает появление локального меню для активной секции окна Cpu. Перейдите в главную область окна Cpu и нажмите <Alt+F10>. Выберите команду Mixed (смесь), которая имеет три установки: 0o, Yes и Both. Режим Both (оба) устанавливается по умолчанию и является наилучшим способом просмотра, показывая в левой колонке байты машинного кода, а в правой – строки исходного текста программы.

48

Окно Cpu используется для наблюдения за текущим состоянием процессора при пошаговом выполнении инструкций программы. Маленькая стрелка-треугольник слева от первой команды mov ax,@data показывает, что она является следующей исполняемой командой (Рис. 1.3). Для выполнения этой команды нажмите <F8>, стрелка перейдёт на следующую команду с изменённым значением регистра ax в окне регистров. Снова нажмите <F8>, для выполнения инструкции mov ds,ax. Обратите внимание, что значение в регистре ds стало таким же, как и в регистре ax, но произошло изменение сегментации дампа памяти (левая нижняя область) с регистра ds на регистр es.

Рис. 1.3. Метка в TD в начале программы

Сделайте активной область с дампом памяти, нажмите <Alt+F10> и в появившемся локальном меню выберите команду Goto (переход). Появится заставка, в которой наберите ds:0000 и нажмите <Enter>. Теперь дамп памяти будет соответствовать массиву инициализированных данных вашей программы при их побайтовом представлении (ASCII- код символов переменной Promt, Good Morning и Good Afternoon). Для просмотра всего дампа используйте передвижение курсора с помощью стандартных клавиш. Объяснение этому факту следует из особенностей загрузки операционной системой MS-DOS в память программ с расширением exe.

Чтобы лучше разобраться с представлением переменной Promt в дампе памяти, войдите в меню Data (данные), выберите команду Inspect (проверка). В появившейся заставке наберите Promt и нажмите <Enter>. Раздвиньте с помощью мыши появившееся окно Inspecting Promt по вертикали на всю высоту экрана в правой его части. В левой колонке данного окна указывается номер элемента переменной массива Promt[i], а в правой – значение ASCII-кода этого элемента. Найдите эти коды в дампе памяти, а именно:

ds:0000 exCode=00h ds:0001 Promt[0]='Э'=9Dh ds:0002 Promt[1]='т'=E2h ds:0003 Promt[2]='о'=AEh и т. д.

Продолжим покомандное исполнение программы с помощью клавиши <F8>, предварительно закрыв окно Inspecting Promt, щёлкнув мышью по кнопке закрытия. После выполнения каждой команды наблюдаем за изменением значений регистров.

Описанный выше процесс выполнения программы прерывается после исполнения команды прерывания DOS (Int 21,функция ah = 1) по вводу символа с клавиатуры на экран. TD переводит вас с окна Cpu в окно пользователя User Screen, в котором появляется сообщение-запрос переменной Promt. Ответив на этот запрос (прописной или строчной буквой: Y или y), вы автоматически снова перейдёте в окно Cpu, для дальнейшего покомандного выполнения программы. Переход, при необходимости, к окну пользователя от TD и обратно можно осуществить нажатием клавиш <Alt+F5>. Если вы забыли это сочетание клавиш, то обратитесь к меню управления окнами Window, найдите строку User Screen с уже упомянутыми клавишами. Кстати, ниже этой строки будет приведён список всех открытых вами окон TD, а именно:

49

Module Hello (1);

CPU (2);

Inspector (3).

Вы можете вызвать любое открытое вами окно с помощью нажатия клавиш <Alt+

номер окна> или путём их последовательного перебора с помощью клавиши <F6-0ext>. Если вы хотите закрепить данное расположение окон при следующей работе с TD, то войдите в меню Options (параметры), выберите кнопку с командой Layot (схема окон). Данная схема будет зафиксирована утилитой Tdconfig.dt. Раз уж мы находимся в меню Options, укажем здесь ещё на одну полезную команду Display options (вывести параметры). Всплывающая заставка Display swapping (переключение экрана) позволяет выбрать один из трёх способов управления переключением между экраном TD и экраном пользователя. По умолчанию устанавливается параметр Smart (эффективный), который позволяет переключиться на экран пользователя User Screen автоматически по требованию программы (это мы наблюдали только что при выполнении требования программы Hello операции ввода одиночного символа).

Вернёмся снова в окно Cpu для завершения работы с программой Hello. Используя клавишу <F8>, доводим маркер исполнения текущей команды до команды с меткой Exit (вызов функции DOS с номером 4Сh для выхода из программы) и, нажав <Alt+F5>, увидим на экране пользователя ответ программы на наш диалог с ней. Если вы хотите повторить выполнение программы, то она может быть перезагружена с произвольной команды с помощью нажатия клавиш <Ctrl+F2> или командой меню Run = Program Reset (сброс программы). При этом программа снова загружается с диска и TD восстанавливает свои исходные опции. Если вы находитесь в окне Cpu или Module, то на дисплее не будет показан возврат к началу вашей программы – для этого надо нажать <F8>.

Завершая краткое описание работы с отладчиком TD, перечислим здесь возможные режимы исполнения программы в TD.

Режим автоматического исполнения, клавиша F9 (Run).

Выполнение по шагам (клавиши F8 или F7-Trace into). Отличие в назначении этих клавиш проявляется в том, что клавиша F7 используется для пошагового исполнения тела цикла, процедуры или подпрограммы обработки прерывания. Клавиша же F8 исполняет эти процедуры как одну обычную команду и передаёт управление следующей команде программы.

Выполнение до текущего положения курсора. Для активизации этого режима необходимо установить курсор на нужную строку программы (строка будет подсвечиваться другим цветом) и нажать клавишу F4.

Выполнение с установленными точками прерывания (Breakpoints). Перед исполнением программы необходимо установить эти точки, для чего следует перейти в нужную строку программы и нажать клавишу F2 (toggle). Выбранная строка с контрольной точкой подсвечивается красным цветом. Чтобы убрать контрольную точку, надо повторить эту операцию снова. После установки точек прерывания программа запускается на исполнение клавишей F9. После первого нажатия клавиши F9 программа остановится на первой точке прерывания, после второго – на второй точке и.т.д. Это очень удобный режим отладки программы, когда необходимо контролировать правильность её исполнения в некоторых характерных точках.

50

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]