Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
flor_apparato-orientirovnnoe_prog.doc
Скачиваний:
89
Добавлен:
15.06.2014
Размер:
926.72 Кб
Скачать

2.3. Средства преобразования в исполняемый файл

Текст программы (листинг 2.2.1) и подобные ему сами по себе не способны управлять компьютером, для такого выполнения их необходимо преобразовать в исполняемый файл. Преобразование осуществляется транслятором с языка ассемблера. Этот транслятор является исполняемым файлом соответствующей операционной системы и имеет в Linux имя nasm. В ОС Windows именем транслятора ассемблера NASM является nasmw.exe. Эти трансляторы предназначены для использования в режиме командной строки (не интегрированной системы разработки) и управляются, в свою очередь, опциями командной строки.

Наиболее важной из этих опция является опция формата для файла результата. Задается эта опция в командной строке в виде

-f формат

где параметр формат может принимать ряд символических значений, из которых в данном курсе представляют интерес значения bin, obj, elf и win32. Формат bin указывает порождение простейшего варианта двоичного кода машинных команд и данные без какой-либо служебной или настроечной информации. Этот вариант используется для построения простейших программ для MS-DOS (так называемых com-файлов, представляющих собой исполняемые файлы односегментных программ) и, кроме того, для построения драйверов этой же ОС (файлов со стандартными расширениями sys).

Формат obj отвечает варианту построения объектных файлов, которые были приняты для старых систем фирмы Microsoft и совместимых с ними. Это объектные файлы, которые могут быть собраны в исполняемые файлы компоновщиками link.exe, tlink.exe и tlink32.exe, соответственно фирм Microsoft и Borland, а также ряд компоновщиков от других разработчиков (в частности компоновщик alink.exe, входящий в комплект системы программирования NASMW). Формат win32, называемый более точно OMF (Object Microsoft Format), генерируется современными компиляторами фирмы Microsoft (masm.exe, cl.exe средой MS Visual C++).

Наконец, формат elf - это стандартная форма объектных файлов, производимых компиляторами в Linux, именно он и потребуется нам в первую очередь.

Вызов транслятора nasm для Linux в простеющем случае имеет вид

nasm -f elf имя_ассемберного_файла

Имя файла результата, формируемое транслятором из файла исходного текста, зависит от используемого формата, если только это результирующее имя не указывается явно. Так объектные файлы для операционных систем Windows получают расширение OBJ - при той же основной части имени, что и у исходного файла. Объектные файлы для Unix получают автоматически расширение .o (используемое для объектных файлов в этих системах). Явное указание оказывается нужным при использовании формата bin, поскольку автоматически создается файл с той же основной частью имени, но без расширения. Для получения исполняемых файлов ОС MS DOS, являющихся наиболее простыми для этой системы - так называемых односегментных, требуется расширение COM в имени этих файлов. Для достижения этой цели помогает вспомогательная опция явного указания имени результирующего файла. Она записывается в виде

-o имя_результирующего_файла

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

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

-l имя_файла_листинга

При использовании операционной системы Linux исполняемый файл из объектных файлов создается с помощью компоновщика, который имеет наименование ld. Обычная форма его использования при построении исполняемого файла только из одного исходного есть

ld имя_объектного_файла

но такой вариант создает исполняемый файл с обычным стандартным именем a.out, поэтому практичней использовать более сложную форму

ld -o имя_исполныемого_файла имя_объектного_файла

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

nasm -f elf $1.asm -l $1.lst

ld -o $1.exe $1.o

и назвав его, например, nasml. Тогда построение исполняемого файла из исходного файла с именем prog1.asm может быть получено вызовом в командной строке

./nasml prog1

(Естественно, предполагается, что командный файл nasml находится в текущем каталоге; если же он находится в каталоге, по которому ведется автоматический поиск согласно переменной окружения PATH, то достаточно вызвать его в виде nasml prog1.) В ходе выполнения командного файла будет построен промежуточный файл с именем prog1.o - как результирующий при работе программы nasm - и файл листинга с именем prog1.lst, из которых программ компоновщика должна построить исполняемый файл с именем prog1.exe. (В действительности какой-то или какие-то файлы из перечисленных могут не быть созданы, если в ходе выполнения программ, вызываемых в командном файле, будут обнаружены ошибки, мешающие такому созданию.)

Разработка простейших программ, предназначенных выполняться в операционной системе MS-DOS, может быть выполнена под любой из ОС типа MS Windows.

Вызов транслятора NASMW.EXE, выполняемого в любой ОС типа Windows, для простейщих ассемблерных программ целесообразно выполнять в виде

nasmw -f bin -o имя_файла.com имя_файла.asm -l имя_файла_листинга

или же путем использования командного файла, например с именем stnasm.bat (при использовании ОС Windows NT файла с именем stnasm.cmd), который содержит единственную строку

nasmw -f bin -o %1.com -l %1.lst %1.asm

путем вызова в виде

stnasm имя_без_расширения_файла_программы

Эти варианты порождают непосредственно исполняемый файл с расширением com, без построения промежуточных объектных файлов (но только в случает отсутствия ошибок).

Сам текст программ, предназначенный для MS-DOS, в этом случае должен использовать соглашения по доступу к системным функциям, принятые именно в этой ОС. Эти соглашения гораздо менее систематичные, чем в других ОС.

Основная особенность для вызова системных функций в MS-DOS заключается в использовании только 16-битных и 8-битных регистров. (Когда создавалась эта ОС, процессоры компьютеров IBM PC еще не имели 32-битной архитектуры!) Большинство системных функций MS-DOS используют для доступа к ядру OC номер прерывания 21h, так что само такое обращение записывается командой INT 21h. Номер функции при этом задается в регистре AH, остальные регистры хотя и служат для передачи аргументов, но не используют при этом общего правила.

Вызов системной функции write требует номера функции 40h (напомним он в регистре AH), при этом хэндл, в частности хэндл стандартного вывода, должен быть помещен в регистр BX, адрес (который, на самом деле является относительным) - в регистр DX, а число выводимых байтов - в регистр CX. Поэтому фрагмент программы, выводящий текст из именованной области txt и имеющий 7 символов, запишется в виде

;--- write(1, txt, 7) == <40h>(bx, dx, cx)

mov ah,40h ; N function=write

mov bx,1 ; N handle=1 (hstdout)

mov cx,7 ; number of byte

mov dx, txt ; address of text

int 21h

Здесь также, как и выше для Linux, использованы содержательные комментарии, поясняющие особенности вызова системной функции с прототипом на Си, в данной ОС. (С формальной стороны видно, что последовательность аргументов в прототипе Си и лексикографические упорядоченные обозначения регистров для данной ОС не совпадают - в отличие от Linux.)

Сама программа для односегментных программ MS-DOS имеет следующие характерные особенности. Во-первых, для нее допускается описание только одного сегмента (это уникальная ситуация, присущая только этому виду исполняемых программ и только в указанной ОС), причем этот сегмент при использовании формата bin результирующего файла в вызове транслятора NASM должен иметь стандартное имя .text (и никакое другое, иначе диагностируется ошибка). Во-вторых, в самом начале сегмента следует разместить служебную директиву org 100h (или org 256, что то же самое). Тем самым резервируется служебная область для системной таблицы в начале исполняемых файлов типа COM и унаследованная от непосредственного предшественника ОС MS-DOS. Сразу после директивы org должны следовать команды, а область данных целесообразно размещать в конце единственного сегмента. Разместить данные можно и внутри области команд, в частности, после первой команды программы, но при этом перед началом данных необходимо использовать команду JMP метка, действия которой будут рассматриваться позже и которая предназначена для "обхода" области данных при выполнении программы.

Еще одной особенностью является возможность в качестве приказа завершения, аналогичного вызову exit(0) из языка СИ, использовать единственную команду

NT 20H

Текст односегментной программы для выполнения в MS-DOS приведен в листинге 2.3.1.

SEGMENT .text

org 100h

start:

;--- write(1, txt, 7) == <40h>(bx, dx, cx)

mov ah,40h ; N function=write

mov bx,1 ; N handle=1 (stdout)

mov cx,7 ; number of byte

mov dx, txt ; address of text

int 21h

;--- write(1, symbl, 1) == <40h>(bx, dx, cx)

mov ah,40h ; N function=write

mov bx,1 ; N handle=1 (stdout)

mov cx,1 ; number of byte

mov dx, symbl ; address of symb

int 21h

int 20h ; function=exit for COM-file

;;--- SEGMENT .data

txt db 'Privet!'

symbl db '$'

Листинг 2.3.1. Простейшая односегментная программа для MS-DOS

Для удобства программиста в трансляторе NASM имеются дополнительные неявные средства. При формате результата bin они предоставляют возможность помещения данных в отдельный сегмент данных, который транслятор при построении результирующего файла помещает в конец кодов исполняемой программы. Не следует увлекаться этой возможностью, так как другой путь построения односегментной программы через объектные файлы с форматом obj не приемлют такой вариант. Тем ни менее для демонстрации возможностей он приведен в листинге 2.3.2.

; Область данных автоматически помещается в конце кодов программы при формате bin

org 100h

SEGMENT .data ;; must to be !

txt db 'Privet!'

symbl db '$'

SEGMENT .text

start:

mov ah,40h ; N function=write

mov bx,1 ; N handle=1 (stdout)

mov cx,7 ; number of byte

mov dx, txt ; address of text

int 21h

mov ah,40h ; N function=write

mov bx,1 ; N handle=1 (stdout)

mov cx,1 ; number of byte

mov dx, symbl ; address of symb

int 21h

int 20h ; function=exit for COM-file

Листинг 2.3.2. Программа для MS-DOS с неявно включаемым сегментом данных

Соседние файлы в предмете Системное программное обеспечение