Реклама:

Начнем с примера программы HlloWrld.s. В листинге В.1 представлен исходный код программы, а на рис. В.5 показано содержимое окна трассера. В листинге символ комментария ( ! ) отделяет команды от номеров строк. В первых трех строках содержатся определения констант, привязывающие условные имена двух системных вызовов и файл вывода к соответствующим внутренним представлениям.

Псевдокоманда . SECT в строке 4 указывает на то, что нижеследующие строки входят в секцию текста, иначе говоря, являются командами процессора. Аналогичным образом, все, что следует за строкой 17, считается данными. В строке 19 инициализируется строка данных, состоящая из 12 байт, в том числе одного пробела и символа перевода строки (\п) в конце.

Hello World

Рис. В.5. Содержимое окна трассера при выполнении программы из листинга В.1

Листинг В.1. Ассемблерный код программы HlloWrld.s

Hello World

В строках 5, 18 и 20 содержатся метки, обозначенные двоеточием (:). Они представляют численные значения, схожие с константами. В данном случае ассемблеру приходится определять эти численные значения. Поскольку метка start находится в начале секции текста, соответствующее значение принимается за 0, но значения в последующих метках секции текста (в этом примере они не показаны) обуславливаются количеством предшествующих байтов кода. Теперь рассмотрим строку 6. Она заканчивается разностью двух меток - численной константой. Таким образом, строку 6 можно приравнять к следующему выражению:

MOV СХД2

Разница между ними заключается лишь в том, что в одном случае длину строки определяет ассемблер, а в другом - программист. Указанное здесь значение выражает объем пространства в секции данных, зарезервированное для размещения строки, расположенной в строке 19. Команда M0V в строке 6 представляет собой команду копирования de -hw в регистр СХ.

Содержание строк 7-11 демонстрирует механизм формирования системных вызовов в применяемом наборе инструментов. Фактически, эти строки представляют собой переведенный на языке ассемблера вызов функции из языка С:

writeü. hw, 12);

Здесь первый параметр представляет собой дескриптор файла стандартного вывода (1), второй выражает адрес отображаемой строки (hw), а третий - длину строки (12). В строках 7-9 эти параметры помещаются в стек в обратном порядке, что соответствует последовательности вызова, принятой в С и применяемой данной программой трассировки. В строке 10 в стек вводится номер системного вызова для функции write (4), а в строке 11 выполняется сам вызов. Такой порядок по большей части соответствует механизму выполнения программы на языке ассемблера в клонах UNIX (или Linux), однако при работе в другой операционной системе его необходимо скорректировать в расчете на конкретные правила выполнения системных вызовов. Впрочем, даже при работе в среде Windows ассемблер as88 и трассер t88 реализуют правила вызовов, принятые в UNIX.

Системный вызов в строке 11 ответственен за вывод данных. Код в строке 12 выполняет очистку стека, возвращая указатель стека к значению, которое у него было до размещения в стеке четырех 2-байтных слов. Если вызов write проводится успешно, число записанных байтов возвращается в регистре АХ. В строке 13 результат системного вызова после строки 11 вычитается из исходной длины строки, записанной в СХ; тем самым производится проверка успешности вызова, то есть фактической записи всех байтов. Таким образом, код завершения должен быть равен нулю при успешном вызове и, соответственно, не равен нулю в противном случае. В строках 14 и 15 подготавливается системный вызов exit, осуществляемый в строке 16; для этого коды завершения и функции, относящиеся к вызову EXIT, отправляются в стек.

Имейте в виду, что в командах M0V и SUB первый аргумент указывает на приемник, а второй - на источник. Такова особенность нашего ассемблера; в других ассемблерах порядок может быть иным. Выбор разработчиками того или иного варианта, по большому счету, произволен.

Теперь попробуем ассемблировать и запустить программу HlloWrld.s. Представляемые команды подходят как для UNIX, так и для Windows. В средах Linux, Solaris, MacOS X и других клонах UNIX процедура аналогична той, что используется для базовой версии UNIX. Во-первых, откройте окно командной строки (командную оболочку). В Windows в большинстве случаев для этого следует выбрать команду Пуск ► Все программы ► Стандартные ► Командная строка (Start ► Programs ► Accessories ► Command Prompt). Далее, перейдите к каталогу examples с помощью команды cd. Аргумент этой команды выбирается в зависимости от местоположения набора инструментов в файловой системе. Затем проверьте, имеются ли в этом каталоге двоичные файлы ассемблера и трассера; для этого воспользуйтесь командой Is (UNIX) или dir (Windows). Эти файлы называются

as88 и t88, соответственно. В среде Windows они имеют расширение .ехе, но в командах его указывать не нужно. Если файлы ассемблера и трассера в названном каталоге отсутствуют, найдите их и скопируйте в него.

После этого выполните ассемблирование тестовой программы с помощью команды

as88 HlloWrld.s

Если двоичный файл ассемблера действительно находится в каталоге examples, но, тем не менее, после запуска этой команды выводится сообщение об ошибке, в UNIX попробуйте ввести строку:

./as88 HlloWrld.s

В Windows для той же цели используйте строку:

.\as88 HlloWrld.s

В случае успешного завершения ассемблирования должны быть выведены следующие сообщения:

Project HlloWrld listfile HlloWrld.s Project HlloWrld num file HlloWrldJ Project HlloWrld loadfile HlloWrld.88

Естественно, должны быть также созданы соответствующие файлы. Если никаких сообщений об ошибках не было, введите команду

t88 HlloWrld

В результате в верхней правой секции окна трассера появится стрелка, указывающая на команду

MOV CX,de-hw

Это команда из строки 6 листинга В.1. После этого нажмите клавишу возврата каретки (на клавиатурах ПК она называется Enter). Как видите, теперь стрелка указывает на команду

PUSH сх

В регистре СХ, согласно содержанию левой секции окна, теперь находится значение 12. Еще раз нажмите клавишу возврата каретки и обратите внимание, что в средней верхней секции появилось значение 000с - шестнадцатеричный аналог десятичного числа 12. В этой секции демонстрируется содержимое стека, где в данный момент находится одно слово - 12. Нажмите клавишу возврата каретки еще три раза и ознакомьтесь с тем, как будут обрабатываться команды из строк 8, 9 и 10. После этого в стеке должно быть четыре элемента, а в левой секции в качестве значения счетчика команд указано шестнадцатеричное число 000b.

При следующем нажатии клавиши возврата каретки будет выполнен системный вызов, а в правой нижней секции окна появится строка:

"Hello World\n"

Как видите, теперь значением регистра SP является 0x7ff0. Еще одно нажатие клавиши приведет к увеличению SP на 8 - до 0x7ff8. Через четыре нажатия клавиши возврата каретки системный вызов exit завершится, как и сама трассировка.

Чтобы понять, как это все работает, полезно открыть файл hlloWrld.s в любом текстовом редакторе (от применения текстовых процессоров в данном случае лучше отказаться). В UNIX это можно сделать в ex, vi или emacs; в Windows выбор естественным образом падает на Блокнот (Notepad), для вызова которого обычно следует выбрать команду Пуск ► Все программы ► Стандартные ► Блокнот (Start ► Programs ► Accessories ► Notepad).

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

Измените сообщение в строке 19, сохраните файл, ассемблируйте его и запустите в трассере. Так вы сделаете первый шаг в области программирования на языке ассемблера.

Примеры-l || Оглавление || Регистры общего назначения-b