мета-данные страницы
  •  
Загрузка не удалась. Возможно, проблемы с правами доступа?

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
asm:lesson3 [30/09/2010 19:40] arabusovasm:lesson3 [07/02/2012 18:38] (текущий) arabusov
Строка 1: Строка 1:
-======Урок 3 ====== +======Начало работы с ассемблером ====== 
-Первым делом проверим конфигурацию dosbox. Зайдём в домашний каталог, затем в папку asm. Проверим наличие в ней файлов debug.exe, папок tasm и tc, в которых содержится turbo assembler и turbo c. Если чего-то нет, то переходите к началу [[http://wiki.nsunc.com/asm]], скачивайте необходимые файлы и распаковывайте их в нужные каталоги. Затем запустим и выключим dosbox, затем в терминале введём команду gedit ~/.dosbox/dosbox-0.73.conf В конце файла должны быть следующие строки:+Первым делом проверим конфигурацию dosbox. Зайдём в домашний каталог, затем в папку asm. Проверим наличие в ней файлов debug.exe, папок tasm и tc, в которых содержится turbo assembler и turbo c. Если чего-то нет, то переходите к началу [[http://wiki.nsunc.com/asm]], скачивайте необходимые файлы и распаковывайте их в нужные каталоги. Затем запустим и выключим dosbox (Приложения -> Игры -> Эмулятор DosBox), затем в терминале (Приложения -> Стандартные -> Терминал) введём команду gedit ~/.dosbox/dosbox-0.74.conf В конце файла должны быть следующие строки:
   * mount c ~/asm   * mount c ~/asm
   * path=z:\;c:\;c:\tasm;c:\tc   * path=z:\;c:\;c:\tasm;c:\tc
Строка 6: Строка 6:
   * keyb ru   * keyb ru
 Если что-то не так, то доредактируем файл. После этого dosbox будет сконфигурирован. Если что-то не так, то доредактируем файл. После этого dosbox будет сконфигурирован.
 +
 ===== Сегментация программы ===== ===== Сегментация программы =====
 По знаменитой формуле Никлауса Вирта (создателя языка Pascal, [[http://ru.wikipedia.org/wiki/%D0%92%D0%B8%D1%80%D1%82,_%D0%9D%D0%B8%D0%BA%D0%BB%D0%B0%D1%83%D1%81]]) программа = алгоритм + данные. Этот принцип в программировании реализуется повсеместно. Процессор 8086 на аппаратном уровне производит разделение программы на код и данные. Для этого вводится понятие сегмента: это участок памяти объёмом в 64 KB, в котором процессор подразумевает нахождение либо данных, либо кода. Адрес начала сегмента хранят сегментные (системные) регистры: cs, ds, ss, es. При выполнении программы процессор обращается по адресу cs:ip и выполняет команду, которая содержится в этой ячейке памяти. Регистр ds указывает на начало сегмента данных, многие команды процессора, которые связаны с работой с памятью, вычисляют физический адрес данных, начиная от ds. Однако мы рассмотрели не все системные регистры: осталось ещё два. es - это дополнительный сегмент данных, он функционирует практически так же, как и ds. А вот ss - сегмнт стека (stack segment), он по-сложнее... По знаменитой формуле Никлауса Вирта (создателя языка Pascal, [[http://ru.wikipedia.org/wiki/%D0%92%D0%B8%D1%80%D1%82,_%D0%9D%D0%B8%D0%BA%D0%BB%D0%B0%D1%83%D1%81]]) программа = алгоритм + данные. Этот принцип в программировании реализуется повсеместно. Процессор 8086 на аппаратном уровне производит разделение программы на код и данные. Для этого вводится понятие сегмента: это участок памяти объёмом в 64 KB, в котором процессор подразумевает нахождение либо данных, либо кода. Адрес начала сегмента хранят сегментные (системные) регистры: cs, ds, ss, es. При выполнении программы процессор обращается по адресу cs:ip и выполняет команду, которая содержится в этой ячейке памяти. Регистр ds указывает на начало сегмента данных, многие команды процессора, которые связаны с работой с памятью, вычисляют физический адрес данных, начиная от ds. Однако мы рассмотрели не все системные регистры: осталось ещё два. es - это дополнительный сегмент данных, он функционирует практически так же, как и ds. А вот ss - сегмнт стека (stack segment), он по-сложнее...
Строка 20: Строка 21:
 ===== Написание программ на ассемблере ===== ===== Написание программ на ассемблере =====
 Первое, с чем мы столкнёмся: для ассемблера нет оболочки. Исторически сложилось, что программу вводят в текстовом редакторе, а затем запускают сам ассемблер и получают исполняемый файл - файл, который можно (а может и нельзя) запустить на компьютере. Итак, чтобы написать программу мы должны создать файл в папке asm, отредактировать его с помощью gedit (особо одарённые могут использовать vi или emacs) и скомпилировать его в dosbox. Компиляция проходит в два этапа. Первый: собственно ассемблирование (команда tasm имя_файла). В результате получится файл имя_файла.obj. Этот файл запустить в dosbox просто так не удастся. Вы можете подключить к этому файлу другие с аналогичным расширением. Это действие называется линковкой. В нашем случае почти всегда мы будем линковать только один файл командой tlink имя_файла.obj. Если программа была написана без ошибок, то на выходе мы получим имя_файла.exe или имя_файла.com. Первое, с чем мы столкнёмся: для ассемблера нет оболочки. Исторически сложилось, что программу вводят в текстовом редакторе, а затем запускают сам ассемблер и получают исполняемый файл - файл, который можно (а может и нельзя) запустить на компьютере. Итак, чтобы написать программу мы должны создать файл в папке asm, отредактировать его с помощью gedit (особо одарённые могут использовать vi или emacs) и скомпилировать его в dosbox. Компиляция проходит в два этапа. Первый: собственно ассемблирование (команда tasm имя_файла). В результате получится файл имя_файла.obj. Этот файл запустить в dosbox просто так не удастся. Вы можете подключить к этому файлу другие с аналогичным расширением. Это действие называется линковкой. В нашем случае почти всегда мы будем линковать только один файл командой tlink имя_файла.obj. Если программа была написана без ошибок, то на выходе мы получим имя_файла.exe или имя_файла.com.
 +== ВНИМАНИЕ!!! ==
 +Имя файла в MS-DOS и в DOSBox не может превышать восьми символов!!!
 +
 ===== Программы типа *.com ===== ===== Программы типа *.com =====
 Главная особенность com-программ: cs, ds, es и ss указывают на один и тот же сегмент, тем самым смешивая всё в одну кучу! При компиляции tasm тщательно следит за тем, чтобы вы не меняли содержимого системных регистров. Так как на всю программу выделен всего один сегмент, то максимальный размер программы: 64 КБайт. Обычно этот тип файлов используется в качестве драйверов для MS-DOS. Главная особенность com-программ: cs, ds, es и ss указывают на один и тот же сегмент, тем самым смешивая всё в одну кучу! При компиляции tasm тщательно следит за тем, чтобы вы не меняли содержимого системных регистров. Так как на всю программу выделен всего один сегмент, то максимальный размер программы: 64 КБайт. Обычно этот тип файлов используется в качестве драйверов для MS-DOS.
Строка 29: Строка 33:
       [метка:] опкод [операнды] [;комментарий]       [метка:] опкод [операнды] [;комментарий]
 где опкод (код операции) — непосредственно мнемоника инструкции процессору. К ней могут быть добавлены префиксы (повторения, изменения типа адресации и пр.). где опкод (код операции) — непосредственно мнемоника инструкции процессору. К ней могут быть добавлены префиксы (повторения, изменения типа адресации и пр.).
 +Метка (если имеется),  команда  и операнд  (если имеется)
 +pазделяются по  крайней  мере  одним  пробелом  или символом
 +табуляции.  Максимальная длина строки - 132 символа, однако,
 +большинство предпочитают работать со строками в  80 символов
 +(соответственно ширине экрана). Примеры кодирования:
 +
 +     Метка     Команда   Операнд
 +     COUNT     DB        1    ;Имя, команда, один операнд
 +               MOV       AX,0 ;Команда, два операнда
 +
 +=== Метки ===
 +
 +Метка в языке ассемблера может содержать  следующие симво
 +лы:
 +          Буквы:         от A до Z и от a до z
 +          Цифры:         от 0 до 9
 +          Спецсимволы:   знак вопроса (?)
 +                         точка (.) (только первый символ)
 +                         знак "коммерческое эт" (@)
 +                         подчеркивание (-)
 +                         доллар ($)
 +
 +Первым символом  в метке должна  быть  буква или спецсимвол.
 +Ассемблер  не  делает различия между заглавными  и строчными
 +буквами.  Максимальная  длина  метки  -  31  символ. Примеры
 +меток:   COUNT,  PAGE25,  $E10.  Рекомендуется  использовать
 +описательные  и смысловые метки.  Имена регистров, например,
 +AX,  DI  или AL  являются  зарезервированными и используются
 +только для указания  соответствующих регистров.  Например, в
 +команде
 +                    ADD  AX,BX
 +
 +ассемблер "знает",  что  AX  и  BX  относится  к  регистрам.
 +Однако, в команде
 +
 +                    MOV  REGSAVE,AX
 +
 +ассемблер воспримет имя REGSAVE только  в  том  случае, если
 +оно  будет определено  в сегменте  данных.   В  приложении 3
 +приведен cписок всех зарезервированных слов ассемблера.
 +
 +=== Команда ===
 +
 +Мнемоническая команда указывает ассемблеру какое действие
 +должен выполнить данный оператор.  В сегменте данных команда
 +(или   директива)   определяет  поле,  рабочую  oбласть  или
 +константу.  В  сегменте  кода  команда  определяет действие,
 +например, пересылка (MOV) или сложение (ADD).
 +
 +=== Операнд ===
 +
 +Если команда специфирует выполняемое действие, то операнд
 +определяет  а)  начальное значение  данных  или б) элементы,
 +над которыми  выполняется действие  по  команде. В следующем
 +примере  байт COUNTER  определен в сегменте  данных и  имеет
 +нулевое значение:
 +
 +          Метка     Команда   Операнд
 +          COUNTER   DB      ;Определить байт (DB)
 +                              ;  с нулевым значением
 +
 +Команда может иметь  один  или  два операнда,  или вообще
 +быть без операндов. Рассмотрим следующие три примера:
 +
 +                    Команда Операнд     Комментарий
 +     Нет операндов    RET               ;Вернуться
 +     Один операнд     INC     CX        ;Увеличить CX
 +     Два операнда     ADD     AX,12     ;Прибавить 12 к AX
 +
 +Метка, команда и операнд не обязательно должны начинаться
 +с какой-либо определенной позиции в  строке. Однако, рекомен
 +дуется записывать  их в колонку  для большей yдобочитаемости
 +программы.  Для этого, например, редактор DOS EDLIN обеспечи
 +вает табуляцию чепез каждые восемь позиций.
 ==== Комментарии ==== ==== Комментарии ====
 Использование  комментариев  в   программе   улучшает  ее Использование  комментариев  в   программе   улучшает  ее
Строка 53: Строка 131:
     * всевозможные абстракции (то есть элементы языков высокого уровня) — от оформления процедур и функций (для упрощения реализации парадигмы процедурного программирования) до условных конструкций и циклов (для парадигмы структурного программирования),     * всевозможные абстракции (то есть элементы языков высокого уровня) — от оформления процедур и функций (для упрощения реализации парадигмы процедурного программирования) до условных конструкций и циклов (для парадигмы структурного программирования),
     * макросы.     * макросы.
 +Директивы управления листингом: PAGE и TITLE
 +
 +
 +Ассемблер  содержит  ряд  директив,  управляющих форматом
 +печати (или  листинга).  Обе директивы  PAGE  и  TITLE можно
 +использовать в любой программе.
 +
 +=== Директива PAGE ===
 +В начале программы можно указать количест
 +во строк,  распечатываемых на одной странице, и максимальное
 +количество  символов на одной строке.  Для  этой цели cлужит
 +директива  PAGE.  Следующей  директивой  устанавливается  60
 +строк на страницу и 132 символа в строке:
 +
 +                         PAGE 60,132
 +
 +Количество строк на странице межет быть в пределах  от 10 до
 +255,  а  символов в  строке -  от 60  до 132. По умолчанию в
 +ассемблере установлено PAGE 66,80.
 +Предположим,  что счетчик строк установлен на 60.  В этом
 +случае  ассемблер,  распечатав  60  строк,  выполняет прогон
 +листа  на  начало  следующей  страницы  и  увеличивает номер
 +страницы  на  eдиницу.  Кроме того можно заставить ассемблер
 +сделать прогон листа на конкретной строке, например, в конце
 +сегмента.  Для этого необходимо записать  директиву PAGE без
 +операндов.  Ассемблер автоматически делает  прогон листа при
 +обработке диpективы PAGE.
 +
 +=== Директива TITLE ===
 +Для того,  чтобы вверху каждой страницы
 +листинга печатался заголовок (титул) программы, используется
 +диpектива TITLE в следующем формате:
 +
 +                         TITLE   текст
 +
 +Рекомендуется в качестве текста использовать  имя програм
 +мы, под которым она находится в каталоге на диске. Например,
 +если программа называется ASMSORT, то можно использовать это
 +имя и описательный комментарий общей длиной до 60 символов:
 +
 +     TITLE ASMSORT - Ассемблерная программа сортировки имен
 +
 +В ассемблере также имеется директива подзаголовка SUBTTL,
 +которая может оказаться полезной для очень больших программ,
 +содержащих много подпрограмм.
 +
 +=== Директива SEGMENT ===
 +
 +Любые ассемблерные  программы  содержат  по  крайней мере
 +один  сегмент  -   сегмент  кода.   В  некоторых  программах
 +используется  сегмент для стековой  памяти  и сегмент данных
 +для определения данных.  Асcемблерная директива для описания
 +сегмента SEGMENT имеет следующий формат:
 +
 +               Имя       Директива      Операнд
 +               имя       SEGMENT        [параметры]
 +                         .
 +                         .
 +                         .
 +               имя       ENDS
 +
 +Имя  сегмента  должно  обязательно  присутствовать,  быть
 +уникальным  и   соответствовать   соглашениям   для  имен  в
 +ассемблере.  Директива  ENDS обозначает конец  сегмента. Обе
 +директивы  SEGMENT и  ENDS  должны  иметь  одинаковые имена.
 +Директива  SEGMENT  может  содержать  три  типа  параметров,
 +определяющих выравнивание, объединение и класс.
 +== Выравнивание ==
 +Данный параметр определяет границу начала
 +сегмента.  Обычным значением является PARA,  по которму
 +сегмент устанавливается на  границу  параграфа.  В этом
 +случае начальный адрес делится на 16  без остатка, т.е.
 +имеет  шест.  адрес  nnn0.  В  случае  отсутствия этого
 +операнда ассемблер принимает по умолчанию PARA.
 +== Объединение ==
 +Этот элемент  определяет объединяется  ли
 +данный   сегмент   с  другими  сегментами   в  процессе
 +компановки  после  ассемблирования   (пояснения  см.  в
 +следующем  разделе  "Компановка  программы").  Возможны
 +следующие типы  объединений:  STACK, COMMON, PUBLIC, AT
 +выражение   и   MEMORY.   Сегмент   стека  определяется
 +следующим образом:
 +
 +               имя  SEGMENT   PARA STACK
 +
 +Когда отдельно ассемблированные программы должны объединяться  компановщиком,   то  можно  использовать  типы:
 +PUBLIC,  COMMON и  MEMORY.  В случае, если программа не
 +должна объединяться  с другими  программами,  то данная опция может быть опущена.
 +== Класс ==
 +Данный элемент, заключенный в апострофы,  используется  для группирования  относительных  сегментов при
 +компановке:
 +
 +               имя  SEGMENT   PARA   STACK   'Stack'
 +
 +Фрагмент  программы  на  рис.  3.1.  в  следующем разделе
 +иллюстрирует директиву SEGMENT и ее различные опции.
 +
 +=== Директива PROC ===
 +
 +Сегмент  кода  содержит  выполняемые  команды  программы.
 +Кроме  того  этот  сегмент также включает  в  себя  одну или
 +несколько процедур,  определенных директивой  PROC. Сегмент,
 +содержащий только одну процедуру имеет следующий вид:
 +
 +     имя-сегмента   SEGMENT   PARA
 +     имя-процедуры  PROC      FAR       Сегмент
 +                    .                   кода
 +                    .                   с
 +                    .                   одной
 +                    RET                 процедурой
 +     имя-процедуры  ENDP
 +     имя-сегмента   ENDS
 +Имя  процедуры  должно  обязательно  присутствовать, быть
 +уникальным и удовлетворять соглашениям по именам  в ассембле
 +ре.  Операнд FAR указывает загрузчику DOS, что начало данной
 +процедуры является точкой входа для выполнения программы.
 +Директива  ENDP  определяет конец процедуры  и имеет имя,
 +аналогичное  имени в директиве PROC.  Команда  RET завершает
 +выполнение программы и в данном случае возвращает управление
 +в DOS.
 +Сегмент может содержать несколько процедур.
 +
 +=== Директива  ASSUME ===
 +
 +Процессор  использует  регистр  SS  для  адресации стека,
 +ркгистр  DS для адресации  сегмента данных и регистр  CS для
 +адресации  cегмента  кода.  Ассемблеру  необходимо  сообщить
 +назначение каждого сегмента.  Для этой цели служит директива
 +ASSUME, кодируемая в сегменте кода следующим образом:
 +
 +     Директива Операнд
 +     ASSUME     SS:имя_стека,DS:имя_с_данных,CS:имя_с_кода
 +
 +Например,  SS:имя_стека  указывает,  что ассемблер должен
 +ассоциировать  имя сегмента  стека с регистром  SS. Операнды
 +могут  записываться  в любой последовательности.  Регистр ES
 +также может присутствовать в числе операндов. Если программа
 +не использует регистр ES,  то его можно опустить или указать
 +ES:NOTHING.
 +
 +=== Директива END ===
 +
 +Как уже показано,  директива  ENDS  завершает  сегмент, а
 +директива  ENDP  завершает процедуру.  Директива END  в свою
 +очередь полностью завершает всю программу:
 +
 +          Директива      Операнд
 +          END            [имя_процедуры]
 +
 +Операнд может быть опущен,  если программа не предназначе
 +на для выполнения, например, если ассемблируются только определения данных, или эта программа должна быть скомпанована с
 +другим  (главным)  модулем.  Для  обычной программы  с одним
 +модулем oперанд содержит  имя,  указанное в  директиве PROC,
 +которое было oбозначено как FAR.
  
 ===== Hello, world! ===== ===== Hello, world! =====
 [[http://www.roesler-ac.de/wolfram/hello.htm]] [[http://www.roesler-ac.de/wolfram/hello.htm]]