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

Различия

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

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

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
asm:lesson3 [30/09/2010 19:31] 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.
Строка 26: Строка 30:
 ===== Программа на ассемблере ===== ===== Программа на ассемблере =====
 Для того, чтобы приступить к работе, мы должны познакомится с синтаксисом языка ассемблер. Для того, чтобы приступить к работе, мы должны познакомится с синтаксисом языка ассемблер.
-Типичный формат записи команд:+==== Команды ====
       [метка:] опкод [операнды] [;комментарий]       [метка:] опкод [операнды] [;комментарий]
-      где опкод (код операции) — непосредственно мнемоника инструкции процессору. К ней могут быть добавлены префиксы (повторения, изменения типа адресации и пр.). +где опкод (код операции) — непосредственно мнемоника инструкции процессору. К ней могут быть добавлены префиксы (повторения, изменения типа адресации и пр.). 
-Директивы+Метка (если имеется),  команда  и операнд  (если имеется) 
 +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 обеспечи 
 +вает табуляцию чепез каждые восемь позиций. 
 +==== Комментарии ==== 
 +Использование  комментариев  в   программе   улучшает  ее 
 +ясность,   oсобенно  там,   где  назначение   набора  команд 
 +непонятно.  Комментаpий  всегда  начинаются  на любой строке 
 +исходного модуля с символа  точка с запятой (;)  и ассемблер 
 +полагает в этом случае,  что все символы, находящиеся справа 
 +от  ;  являются  комментарием.  Комментарий  может содержать 
 +любые печатные символы, включая пробел. 
 +Комментарий может занимать  всю строку  или  следовать за 
 +командой на той же строке, как это показано в двух следующих 
 +примерах: 
 + 
 +   1.     ;Эта строка полностью является комментарием 
 +   2.     ADD AX,BX  ;Комментарий на одной строке с командой 
 + 
 +==== Директивы ====
  
 Программа на языке ассемблера может содержать директивы: инструкции, не переводящиеся непосредственно в машинные команды, а управляющие работой компилятора. Набор и синтаксис их значительно разнятся и зависят не от аппаратной платформы, а от используемого транслятора (порождая диалекты языков в пределах одного семейства архитектур). В качестве «джентельменского набора» директив можно выделить следующие: Программа на языке ассемблера может содержать директивы: инструкции, не переводящиеся непосредственно в машинные команды, а управляющие работой компилятора. Набор и синтаксис их значительно разнятся и зависят не от аппаратной платформы, а от используемого транслятора (порождая диалекты языков в пределах одного семейства архитектур). В качестве «джентельменского набора» директив можно выделить следующие:
Строка 38: Строка 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]]