10784

Основы языка ассемблер: Метод. указания к лабораторной работе

Лабораторная работа

Информатика, кибернетика и программирование

Основы языка ассемблер: Метод. указания к лаб. работе по дисциплине Вычислительные машины системы и сети/ Воронеж. гос. ун. инж технол. Сост. Е.А. Хромых И.А. Козенко. Воронеж 2011. 30 с. Указания разработаны в соответствии с требованиями ФГОС ВПО подготовки бакалавров по н...

Русский

2013-04-01

650 KB

29 чел.

Основы языка ассемблер: Метод. указания к лаб. работе по дисциплине «Вычислительные машины, системы и сети»/ Воронеж. гос. ун. инж технол.; Сост. Е.А. Хромых, И.А. Козенко,. Воронеж, 2011.  30 с.

Указания разработаны в соответствии с требованиями ФГОС ВПО подготовки бакалавров по направлению 220400 – «Управление в технических системах», профиль подготовки «Управление и информатика в технических системах» и по направлению 220700 – «Автоматизация технологических процессов и производств», профиль подготовки «Автоматизация технологических процессов и производств (в пищевой и химической промышленности)». Они предназначены для закрепления теоретических знаний дисциплины цикла Б3. Методические указания посвящены ознакомлению студентов с языком программирования низкого уровня.

Составители доцент Е.А. ХРОМЫХ,

ассистент И.А. КОЗЕНКО.

Научный редактор профессор В.Ф. ЛЕБЕДЕВ

Рецензент профессор, д.т.н. Ю.А. ЧЕВЫЧЕЛОВ

Печатается по решению

редакционно-издательского совета

Воронежского государственного университета инженерных технологий

© Хромых Е.А.,

   Козенко И.А., 2011

© Воронежский                                государственный            

   университет инженерных технологий, 2011

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

1. АРХИТЕКТУРА ПРОЦЕССОРА

Процессор — это кремниевая плата или «подложка» с логическими цепями, состоящими из транзисторов, скрытая в пластмассовом корпусе, снабженном контактными ножками (выводами,pin). Большинство ножек процессора подключено к шинам - шине адреса, шине данных и шине управления, связывающим чип процессора с остальной частью компьютера. Остальные ножки служат для подачи питания на сам чип. Каждая шина состоит из группы проводников, которые выполняют определенную функцию.

Пункт 7 концепции фон Неймана говорит: инструкции и данные (то есть операнды, результаты или адреса) представляются в виде двоичных сигналов и в двоичной системе счисления. Это означает, что один проводник шины компьютера может передавать один бит. Значение этого бита (1 или 0) определяется уровнем напряжения в проводнике. Значит, процессор с одной 16-разрядной шиной и одной 8-разрядной должен иметь 24 (16 и 8) ножки, соединенные с различными проводниками. Например, при передаче числа 27 (00011011 в двоичной системе) по 8-разрядной шине проводник, по которому передается самый правый бит (LSB - Least Significant Bit наименее значимый бит), покажет логический уровень 1, следующий провод также покажет 1, следующий - 0 и т.д.

Процессор состоит из логических контуров. Эти цепи реализуют все модули, из которых процессор должен состоять согласно концепции фон Неймана: контроллер, арифметико-логическое устройство (АЛУ) и регистры (рис. 1).

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

Рис.1. Структура микропроцессора.

Арифметико-логическое устройство (АЛУ) выполняет арифметические и логические действия над данными. Для более простых процессоров достаточно АЛУ, умеющего выполнять операции отрицания и сложения, поскольку другие арифметические действия (вычитание, умножение и целочисленное деление) могут быть сведены к этим операциям. Другая, логическая, часть АЛУ выполняет основные логические действия над данными, например, логическое сложение и умножение (OR, AND), а также исключительное ИЛИ (XOR). Еще одна функция АЛУ, которую выполняет устройство циклического сдвига (barrel-shifter), заключается в сдвигах битов влево и вправо. Для выполнения процессором инструкции необходимо намного меньше времени, чем для чтения этой инструкции из памяти. Чтобы сократить время ожидания памяти, процессор снабжен временным хранилищем инструкций и данных - регистрами. Размер регистра - несколько байтов, но зато доступ к регистрам осуществляется почти мгновенно. Среди регистров обязательно должны присутствовать следующие группы: регистры общего назначения, регистры состояния и счетчики. Регистры общего назначения содержат рабочие данные, полученные из памяти. Регистры состояния содержат текущее состояние процессора (или состояние АЛУ). Последняя группа - это счетчики. Согласно теории фон Неймана, должен быть хотя бы один регистр из этой группы - счетчик команд, содержащий адрес следующей инструкции.

1.1. Процессор 80386

Микропроцессор 80386 полностью 32-разрядный, что означает, что он может работать с 4 Гб оперативной памяти (232 байтов). Поскольку шина данных также 32-разрядная, процессор может обрабатывать и хранить в своих регистрах 32-разрядное число (аналог типа данных int в большинстве реализаций языка С\С++). Регистры процессора являются важнейшим инструментом программиста (не только на языке ассемблера, но и на языках высокого уровня), и необходимо иметь четкое представление о составе регистров процессора, их названиях и применении.

Микропроцессор 80386 в своем составе имеет следующие регистры:

  1.  общего назначения;
  2.  индексные
  3.  указатели
  4.  сегментные
  5.  флаги;
  6.  специальные.

Рис. 2. Регистры процессора 80386.

1.2. Регистры общего назначения

Рассмотрим регистры общего назначения: ЕАХ, ЕВХ, ЕСХ и EDX (Аккумулятор, База, Счетчик и Данные). Программист может использовать их по своему усмотрению для временного хранения любых объектов (данных или адресов) и выполнения над ними требуемых операций. При этом регистры допускают независимое обращение младшему 16-разрядному регистру (AX, BX, CX, DX) и к старшему (АН, BH, CH, DH) и младшему (AL, BL, CL, DL) 8-разрядным регистрам:

Рис.3. Регистр EAX.

Все регистры общего назначения кроме названия ничем другим друг от друга не отличаются.

1.3. Индексные регистры

К регистрам общего назначения иногда относят и индексные регистры процессора 80386 - ESI, EDI и ЕВР (или SI, DI и ВР для 16-разрядных). Обычно эти регистры используются для адресации памяти: обращения к массивам, индексирования и т.д. Отсюда их имена: индекс источника (Source Index), индекс приемника (Destination Index), указатель базы (Base Pointer). Но хранить в них только адреса совсем необязательно: регистры ESI, EDI и ЕВР могут содержать произвольные данные. Эти регистры программно доступны, то есть их содержание может быть изменено программистом. Описанные индексные регистры имеют только 16-разрядную и 32-разрядную версии.

1.4. Сегментные регистры

Эту группу регистров можно отнести к регистрам состояния. Регистры из этой группы используются при вычислении реального адреса (адреса, который будет передан на шину адреса). Процесс вычисления реального адреса зависит от режима процессора (реальный или защищенный). Сегментные регистры только 16-разрядные. Названия этих регистров соответствуют выполняемым функциям: CS (Code Segment, сегмент кода) вместе с EIP (IP) определяют адрес памяти, откуда нужно прочитать следующую инструкцию; аналогично регистр SS (Stack Segment, сегмент стека) в паре с ESP (SS:SP) указывают на вершину стека. Сегментные регистры DS, ES, FS, и GS (Data, Extra, F и G сегменты) используются для адресации данных в памяти. Сегментные регистры, естественно, не могут выступать в качестве регистров общего назначения.

1.5. Регистры управления

Регистр ESP (SP) - это указатель памяти, который указывает на вершину стека (х86-совместимые процессоры не имеют аппаратного стека). Также программно не может быть изменен регистр EIP (IP, Instruction Pointer) - указатель команд. Этот регистр указывает на инструкцию, которая будет выполнена следующей. Значение этого регистра изменяется непосредственно контроллером процессора согласно инструкциям, полученным из памяти.

1.6. Регистр флагов

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

  1.  Признак нуля ZF (Zero Flag) - 1, если результат предыдущей операции равен нулю.
  2.  Признак знака SF (Sign Flag) - 1, если результат предыдущей операции отрицательный.
  3.  Признак переполнения OF (Overflow Flag) - 1, если при выполнении предыдущей операции произошло переполнение (overflow), то есть результат операции больше, чем зарезервированная для него память.
  4.  Признак переноса CF (Carry Flag) - 1, если бит был перенесен и стал битом более высокого порядка.
  5.  Признак прерывания IF (Interrupt Flag) - 1, если прерывания процессора разрешены.
  6.  Признак направления DF (Direction Flag) - используется для обработки строк. При DF равным 0 строка обрабатывается в прямом направлении, от меньших адресов к большим; если DF равен 1, обработка строки идет в обратном направлении.

Другие регистры процессора относятся к работе в защищенном режиме.

1.7. Прерывания

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

Прерывания могут быть программными и аппаратными. Аппаратные прерывания происходят по запросу периферийных устройств и называются IRQ (Interrupt Requests). Архитектура шины ISA ограничивает их число до 16 (IRQ0IRQ15). К аппаратным прерываниям относятся также специальные прерывания, которые генерирует сам процессор. Такие прерывания используются для обработки исключительных ситуаций - неверный операнд, неизвестная команда, переполнение и другие непредвиденные операции, когда процессор сбит с толку и не знает, что делать. Эти прерывания имеют свои обозначения и никак не относятся к зарезервированным для периферии прерываниям

IRQ0-IRQ15.

Все аппаратные прерывания можно разделить на две группы: прерывания, которые можно игнорировать (замаскировать) и те, которые игнорировать нельзя. Первые называются маскируемыми (maskable), а вторые - немаскируемыми (non-maskable). Аппаратные прерывания могут быть отключены путем установки флага IF регистра признаков в 0. Единственное прерывание, которое отключить нельзя - это NMI, немаскируемое прерывание, генерирующееся при сбое памяти, сбое в питании процессора и подобных форс-мажорных обстоятельствах.

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

1.8. Реальный и защищенный режим

В реальном режиме процессор обращаться лишь к 1 Мбайт адресного пространства. Адрес, сброшенный на адресную шину, получался как сумма значений соответствующего 16-битного регистра и сегментного регистра, умноженного на 16.

В защищенном режиме по-прежнему используются сегменты и смещения в них, однако начальные адреса сегментов не вычисляются путем умножения на 16 содержимого сегментных регистров, а извлекаются из таблиц сегментных дескрипторов, индексируемых с помощью тех же сегментных регистров. Данный режим позволяет использовать 32-разрядный адрес, что позволяет адресовать 232байта (4 Гбайта).

2. КОМПИЛЯТОР NASM

Синтаксис компилятора подобен синтаксису коммерческих компиляторов MASM (Microsoft Assembler) и TASM (Turbo Assembler от Borland), поэтому использовать NASM вдвойне удобно - никаких проблем с лицензией и возможность переноса программ, написанных для других ассемблеров. Компилятор NASM (Netwide Assembler) свободно распространяется (вместе со своими исходными кодами) по лицензии LGPL.

2.1. Структура программы

Каждая программа, вне зависимости от языка программирования, состоит из трех основных частей: код программы, статические данные (то есть известные во время компиляции) и динамические данные (неинициализированные, то есть те, под которые во время компиляции только отводится память, а значение им не присваивается).

Эти секции могут быть определены с помощью директив SECTION. Традиционно секция кода называется .text, секция статических данных - .data, а секция динамических данных - -.bss.

Пример программы, содержащий две секции

001

SECTION .text

;Начало секции

002

mov eax,2

;Регистр EAX заполняется 2

003

mov ebx,5

;регистр EBX заполняется 5

004

add eax,ebx

;EAX = EAX + EBX = 2 + 5

005

add eax,[stat]

;EAX = EAX + stat = 7 + 1

006

SECTION .data

;Начало секции статических данных

007

stat: dd 1

;Выделение памяти под статическую переменную stat и ее инициализация

2.2. Язык NASM

Как и в большинстве ассемблеров, каждая строка NASM содержит комбинацию четырех полей:

метка: инструкция операнды ; комментарий

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

2.3. Константы

Ассемблер NASM различает четыре типа констант: числовые, символьные, строковые и с плавающей точкой.

2.4. Числовые константы

NASM позволят определять числа в различных системах счисления и различными способами. Суффиксы H, Q и B позволяют определять константы в шестнадцатеричной, восьмеричной и двоичной системах счисления.

Например:

mov ax,100 ; десятичная константа 10010

mov ax,a2h ; шестнадцатеричная константа 4210

mov ax,0xa2 ; шестнадцатеричная константа 4210

mov ax,777q ; восьмеричная константа 51110

mov ax,10010011b ; двоичная константа 14710

2.5. Символьные константы

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

Символьная константа, содержащая более одного символа, будет загружена в обратном порядке следования байт.

Например:

mov eax,'abcd' ; в регистр EAX заносится символьная константа

Сгенерированной константой будет не ‘abcd’, а ‘dcba’.

2.6. Псевдокоманды

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

Псевдокоманды DB, DW и DD определения констант

Псевдокоманда DB (define byte) позволяет определить числовые константы и строки.

Пример:

001

db 0x55                            

; один байт в шестнадцатеричном виде

002

db 0x55,0x56,0x57

; три последовательных байта: 0x55,;0х56, 0x57

003

db 'а',0x55

; можно записать символ в одинарных кавычках.

; получится последовательность 0x61, 0x55

004

db 'Hello',13,10,'$'

; можно записать целую строку.

; получится 0x48, 0x65, 0х6С, 0х6С 0x6F, 0xD, 0xA, 0x24

Для определения порции данных размера, кратного слову (16 бит), служит директива DW (define word):

001

dw 0x1234

;0х34, 0x12

002

dw ' a '

;0x61, 0x00: второй байт заполняется нулями

Директива DD (define double word) задает значение порции данных размера,

кратного двойному слову (32 бита):

001

dd 0x12345678

; 0х78 0x56 0x34 0x12

002

dd 1.234567e20

; так определяются числа с плавающей точкой

Определение переменных осуществляется следующим образом:

003

number dd 0x1

; переменная number инициализирована значением 1

Переменная number теперь представляет адрес в памяти, по которому записано значение 0x00000001 длиной в двойное слово (32 бита).

Псевдокоманды RESB, RESW и RESD объявления переменных

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

Для резервирования памяти служат три директивы: RESB (резервирует байт), RESW (резервирует слово) и RESD (резервирует двойное слово). Аргументом этих псевдокоманд является количество резервируемых позиций:

001

resb 1

; резервирует 1 байт

002

resb 2

; резервирует 2 байта

003

resw 2

; резервирует 4 байта (2 слова)

004

resd 1

; резервирует 4 байта

005

number resd

; резервирует 4 байта для переменной «number»

006

buffer resb 64

; резервирует 64 байта для переменной «buffer»

Представленные команды используются в секции .data!

2.7. Основные команды ассемблера

Команда MOV

Команда MOV позволяет копировать данные из регистра в память и обратно. Команда MOV, хоть название ее и происходит от слова «move» (перемещать), на самом деле не перемещает, а копирует значение из источника в приемник:

MOV приемник, источник

Если приемник – регистр, источник может быть регистром, значением памяти или числом. Если приемник – значение памяти, то источник может быть только регистром или числом.

Пример:

001

mov AX,[number]

; загрузить значение переменной number в регистр АХ

002

mov [number],BX

; загрузить значение регистра ВХ в переменную number

003

mov BX,СX

; загрузить в регистр ВХ значение регистра СХ

004

mov AL,1

; загрузить в регистр AL значение 1

005

mov DH,CL

; загрузить  в регистр DH значение регистра CL

Арифметические команды

Инструкции сложения ADD и вычитания SUB

Синтаксис команды ADD:

ADD назначение, источник

Данная инструкция складывает источник с назначением. Результат сохраняется в назначении. Используется для сложения двух регистров, регистра с адресом памяти (переменной), константой.

Синтаксис команды SUB:

SUB назначение, источник

Инструкция, по аналогии с ADD, вычитает источник из назначения, результат записывается в назначение. Назначение – регистр или значение памяти, источник – регистр, значение памяти или константа.

Пример:

001

mov AX, 8

; загрузить в АХ число 8

002

mov СХ, 6

; загрузить в СХ число 6

003

mov DX, СХ

; копирует СХ в DX

004

add DX, AX

; DX = DX + АХ

005

add EAX,8

; EAX = EAX + 8

006

sub ECX,EBP

; ECX = ECX - EBP

007

add byte [number], 4

; складывает 4 с переменной number (1 байт)

008

sub word [number], 4

; number = number – 4 размером в 2 байта

009

add dword [number], 4

; суммирует значение 4 и переменную number (4 байта)

010

sub byte [number], AL

; вычитает значение регистра AL из number

011

sub AH,AL

; вычитает AL из АН, результат помещается в АН

Команды инкрементирования INC и декрементирования DEC

Команда INC добавляет, a DEC вычитает единицу из единственного операнда. Допустимые типы операнда – такие же, как у команд ADD и SUB, а формат команд таков:

001

INC byte a

; a = a +1

002

DEC word b

; b = b – 1

ВНИМАНИЕ! Ни одна из этих инструкций не изменяет флаг CF.

Целочисленное умножение и деление

Умножение выполняется командой MUL, а деление – командой DIV. С целью упрощения реализации команд умножения и деления, они спроектированы так, что один из операндов и результат находятся в фиксированном регистре, а второй операнд указывается программистом. Подобно командам ADD и SUB, команды MUL, DIV изменяют регистр признаков.

Синтаксис команды MUL:

MUL источник

Первым множителем выступает содержимое регистра EAX: AL умножается на источник, если его размер байт; AX умножается на источник, если его размер слово; EAX умножается на источник, если содержимое источника двойное слово. Результат записывается в AX, DX:AX, или EDX:EAX соответственно. Источник может быть регистром или значением памяти (но не в коем случае не константа!).

Пример:

001

mov АХ,13

; помещает в AX 13

002

mov CL,2

; помещает в CL 2

003

mul CL

; умножает AX на CL 

Синтаксис команды DIV:

DIV источник

Инструкция делит АХ на источник, если источник – байт, DX:AX на источник, если источник – слово (частное в AL, остаток в АН), и EDX:EAX на источник, если источник – двойное слово (DX остаток, АХ частное). Значение хранится в AL, AX или EAХ (частное в ЕАХ, остаток в EDX). Источником может быть регистр или значение памяти (но не в коем случае не константа!).

Пример:

001

mov АХ,13

; помещает в AX 13

002

mov CL,2

; помещает в CL 2

003

div CL

; делит AX на CL 

Управляющие конструкции.

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

Конструкция «IF   THEN»

В языках программирования высокого уровня конструкция выбора известна как условный оператор «IF   THEN». Эта конструкция позволяет выбрать следующее действие из нескольких возможных вариантов в зависимости от выполнения определенного условия. В языке ассемблера механизм выбора реализован посредством команд сравнения, условного и безусловного переходов CMP и TEST.

Синтаксис команды CMP:

СМР операнд1 ,операнд2

Команда СМР – это сокращение от «compare» («сравнить»). Она работает подобно SUB: операнд1 вычитается из операнд2. Результат нигде не сохраняется, команда просто изменяет регистр признаков. Команда СМР может использоваться как для сравнения целых беззнаковых чисел, так и для сравнения чисел со знаком.

Синтаксис команды TEST:

TEST операнд1 ,операнд2

Команда TEST работает подобно СМР, но вместо вычитания она вычисляет поразрядное И операндов. Результат инструкции – измененные флаги регистра признаков. Инструкция TEST чаще всего используется для проверки значений отдельных битов в массиве битов.

Пример:

001

cmp АХ, 4

; сравнивается АХ со значением 4

002

cmp DL, AH 

; сравнивается DL с АН

003

cmp AX, [diameter]

; AX сравнивается с переменной «diameter»

Команда безусловного перехода JMP

Самый простой способ изменить последовательность выполнения команд заключается в использовании команды JMP – так называемой команды безусловного перехода. Она перезаписывает указатель команд (регистр IP или CS), что заставляет процессор «переключиться» на выполнение команды по указанному адресу. Формат команды таков:

JMP операнд

Команда JMP – аналог конструкции GOTO, которая используется в высокоуровневых языках программирования. Команде нужно передать один обязательный операнд – адрес в памяти, с которого процессор должен продолжить выполнение программы. Операнд может быть указан явно (непосредственное значение адреса) или быть регистром общего назначения, в который загружен требуемый адрес, либо меткой.

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

Объявление метки:

[идентификатор метки]:

Пример:

001

mov АХ,4

; АХ = 4

002

new_loop :

; объявление метки new_loop в тексте

003

mov BX, АХ

; копирует АХ в ВХ

Чтобы перейти к метке new_loop из другого места программы, используйте команду:

004

jmp new_loop

; переходит к new_loop

После выполнения этой команды выполнение программы продолжится с метки new_loop.

Условные переходы Jx

Другой способ изменения последовательности выполнения команд заключается в использовании команды условного перехода. В языке ассемблера имеется множество команд условного перехода. Имена этих команд различаются в зависимости от условия перехода. Условие состоит из значений одного или нескольких флагов в регистре признаков. Работают эти команды одинаково: если условие истинно, выполняется переход на указанную метку, если нет, то процессор продолжит выполнять программу со следующей команды. Общий формат команд условного перехода следующий:

Jx метка_назначения

Наиболее часто встречающиеся команды:

001

jz is_true

; переходит к is_true, если флаг ZF = 1

002

jc is_true

; переходит к is_true, если флаг CF = 1

003

js is_true

; переходит к is_true, если флаг SF = 1

004

jo is_true

; переходит к is_true, если флаг переполнения OF = 1

Любое условие может быть инвертировано, например:

005

jnz is_true

;переходит к is_true, если флаг ZF = О

Так же образованы имена команд JNC, JNS и JNO.

Сводная таблица команд условного перехода в зависимости от условия, которое проверяет процессор:

Пример:

001

cmp AL, AL 

; сравнивает AL и CL

002

Jz  write_1

; переходит к write_1 , если AL = CL

003

cmp ALl, CL

; сравнивает AL и CL

004

Ja write_2

; переходит к write_2, если AL > CL

005

mov BL , 3

; последний случай – сразу загружает 3 в BL

006

end_if:

; метка, символизирующая конец IF

Команды PUSH и POP: втолкнуть и вытолкнуть

Команда PUSH позволяет поместить в стек содержимое любого 16- или 32-битного регистра или ячейки памяти. Формат команды следующий:

PUSH источник

Пример:

001

push EAX

; поместить ЕАХ в стек

Другая команда, POP, записывает в свой операнд значение вершины стека (последнее сохраненное в стеке значение). Тип операнда должен быть таким же, как у инструкции PUSH (другими словами, если вы поместили в стек 32-разрядный регистр, извлечение из стека должно происходить тоже в 32-разрядный регистр).

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

POP приемник

Пример:

001

push EAX

; сохранить значение регистра ЕАХ в стеке

002

push ESI

; сохранить значение регистра ESI в стеке

003

pop EAX

; извлечь данные из стека в ЕАХ

004

pop ESI

; извлечь данные из стека в ESI

В результате выполнения этих команд поменялись местами значение регистров ЕАХ и ESI: сначала поместили в стек значение ЕАХ, затем – ESI, после этого извлекается из стека последнее сохраненное значение (бывшее значение регистра ESI) в регистр ЕАХ, после этого в стеке остается бывшее значение ЕАХ, которое записывается в ESI.

Команды CALL и RET. Организация подпрограмм

Ни одна серьезная программа не обходится без подпрограмм. Основное назначение

подпрограмм — сокращение кода основной программы: одни и те же инструкции не нужно писать несколько раз — их можно объединить в подпрограммы и вызывать по мере необходимости.

Для вызова подпрограммы используется команда CALL, а для возврата из подпрограммы в основную программу – RET. Формат обеих команд таков:

CALL тип_вызова операнды

RET

Команде CALL нужно передать всего один операнд – адрес начала подпрограммы. Это может быть непосредственное значение, содержимое регистра, памяти или метка. В отличие от JMP, при выполнении команды CALL первым делом сохраняется в стеке значение регистра IP (EIP). Передача управления на указанный адрес называется вызовом подпрограммы.

Пример подпрограммы суммирования двух целых чисел. Входные параметры в подпрограмму передаются через регистры:

001

add_it:

; начало подпрограммы

002

push EAX

; сохраняет значение ЕАХ в стек

003

add EAX,EBX

; EAX = ЕАХ + ЕВХ

004

mov ECX,EAX

; копирует значение из ЕАХ в ЕСХ

005

pop EAX

; восстанавливает оригинальное значение ЕАХ

006

ret

; завершает подпрограмму (возврат)

Вызов подпрограммы в программе:

001

mov EAX,4

; ЕАХ = 4

002

mov EBX,8

; ЕВХ = 8

003

call add it

; вызывает add_it

; результат будет в регистре ЕСХ

Рассмотрим процедуру суммирования двух целых чисел, но входные параметры передадим через глобальные переменные:

001

SECTION .text

; начало секции кода

002

mov AH, 4

; в регистр AH поместили 4

003

mov BH, 3

; в регистр BH поместили 3

004

mov [summand1],AH

; в однобайтную переменную  summand1  поместили AH

005

mov [summand2],BH

; в однобайтную переменную  summand2 поместили BH

006

call addproc

; вызывается процедура addproc

007

008

mov DL, [amount]

; заносим в регистр DL результат сложения – переменную amount

009

add DL,'0'

; определяем код символа

010

mov AH,0x02

; функция DOS вывода символа

011

int 0x21

; DOS прерывание

012

013

mov AH,0x4c

; функция DOS завершения программы

014

int 0x21

; DOS прерывание

015

016

addproc:

; заголовок процедуры суммирования

017

mov AH,[summand1]

; заносим в регистр AH значение переменной summand1

018

add AH,[summand2]

; суммируем регистр AH с переменной summand2

019

mov [amount],AH

; сохраняем результат в переменную amount

020

ret

; выходим из процедуры

021

SECTION .data

; секция объявления статических данных

022

summand1 db 1

; создаем однобайтную переменную summand1 

023

summand2 db 1

; создаем однобайтную переменную summand2

024

amount   db 1

; создаем однобайтную переменную amount

3. УСТАНОВКА КОМПИЛЯТОРА NASM

Дистрибутив, а также исходные коды компилятора можно бесплатно скачать на сайте http://nasm.sourceforge.net.Для установки необходимо обладать правами администратора. Для справок обратитесь к администратору сети. Запустив установщик появится окно следующего вида:

Рис. 4. Окно установщика компилятора NASM

В данном окне можно уточнить список устанавливаемых компонентов: непосредственно сам компилятор, утилита для работы с объектными файлами rdf (RDOFF), руководство пользователя и интеграция компилятора в среду Visual Studio 2008 от Microsoft.

Рис. 5. Окно выбора директории установки

В окне (рис. 5) указывается папка назначения установки. Кнопка далее («Next>») инициирует процесс распаковки, по завершении которой в меню Пуск появится новый пункт «Netwide Assembler 2.09rc7».

3.1. Запуск компилятора.

Для запуска компилятора необходимо выбрать «Пуск» - «Netwide Assembler 2.09rc7» - «nasm-shell»:

Рис. 6. Запуск компилятора NASM.

3.2. Создание файла *.asm.

Ввод  кода программы осуществляется в текстовом редакторе «Блокнот» или любом другом, но при сохранении необходимо указать расширение asm. После модификации кода в исходном файле перед компиляцией и линковкой необходимо сохранять все изменения. Файл можно сохранять в любую директорию, но для упрощения работы в командной строке рекомендуется сохранять в папку установки NASM (если разрешено политикой безопасности).

Формат выходного файла.

Netwide Assembler (NASM) легко портируется на различные операционные системы в пределах х86-совместимых процессоров. Поэтому для NASM не составит труда откомпилировать программу для указанной операционной системы, даже если вы сейчас работаете под управлением другой ОС.

Создание выходного файла: компиляция и компоновка.

Создание исполняемого файла состоит из двух этапов. Первый – это компиляция (трансляция) исходного кода программы в некоторый объектный формат. Объектный формат содержит машинный код программы, но символы (переменные и другие идентификаторы) в объектном файле пока не привязаны к адресам памяти.

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

Для компиляции и линковки необходимо выполнить в командной строке:

nasm -f bin -о имя_исполняемого_файла.exe имя_файла_кодов.asm

Ключ f указывает тип выходного формата. В данном примере двоичный.

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

В файле имя_файла_кодов.asm содержится исходный код программы на языке ассемблер.

После выполнения команды в директории с файлом имя_файла_кодов.asm появится файл имя_исполняемого_файла.exe, который можно запустить двойным щелчком мыши.

3.3. Основные системные вызовы (DOS)

Операционная система предлагает запущенной программе множество сервисов. Используя операционную систему, программа может выводить сообщения на экран, считывать ввод с клавиатуры, работать с файлами или требовать выделения  дополнительной памяти. Сервисы операционной системы доступны через прерывание 0x21. Параметры системных вызовов указываются в определенных регистрах. Под DOS номер необходимой функции указывается в регистре АН. Если системный вызов завершился ошибочно, то устанавливается флаг переноса, а в регистр АХ помещается код ошибки.

Запуск DOS-приложений под Windows

Для запуска DOS-приложения в среде Windows используется так называемый «Сеанс MS DOS». Для запуска DOS-режима выполните команду cmd (Пуск -> Выполнить - cmd). Открывшееся окно полностью эмулирует функции DOS. Если файлы компилятора NASM находятся в каталоге C:\NASM, можно использовать команду DOS, чтобы перейти в этот каталог:

cd С:\NASM

Помните, что в DOS существует ограничение на длину файлов – все имена файлов  должны быть в формате 8+3 (8 символов – имя, 3 – расширение). Для редактирования исходных файлов используйте редактор, который показывает номера строк – так будет проще найти ошибку.

Немедленное завершение программы

Простейшая программа – это та, которая завершается немедленно после запуска. Запрос на завершение программы обеспечивается системным вызовом DOS с номером 0х4С, прерывающим программу и передающим управление родительской программе.

Пример:

Ввод:

Завершение программы:

АН 0x4С

AL = код возврата

Вывод:

Ничего

Номер вызываемой функции передается через регистр АН, а в AL указывается так называемый код возврата, то есть значение, которое должна анализировать родительская программа. Дочерняя программа может либо сообщить родительской, что завершилась нормально, либо вернуть код ошибки. Эта функция такого же назначения, как exit в языке С.

Пример программы под DOS, которая завершается сразу после запуска.

001

SECTION .text

; начало секции кода

002

mov AH,0x4C

; эта функция завершает программу

003

mov AL,0

; код возврата 0

004

int 0x21

; вызывает ядро операционной системы

; конец программы

Теперь сохраните программу в файл example.asm. Далее откомпилируйте ее:

nasm -f bin -о example.exe example.asm

Рис. 7. Компиляция и линковка программы example.asm

После компиляции можно запустить программу example.exe, написав «example.exe» в командной строке и нажав «Enter». Программа сразу же вернет управление командному интерпретатору.

Вывод символа в DOS.

Для вывода символа в режиме DOS используется следующая команда, код которой равен 0x02.

При вызове:

AH=0x02

DL=КОД выводимого символа

Код символа определяется путем сложения значения с символом ‘0’. Например:

001

MOV DL, 3

; помещает в регистр DL число 3

002

ADD DL,’0’

; определяет код символа 3 путем прибавления кода 0

003

MOV AH, 0x02

; вызывает функцию DOS вывода символа на экран

004

Int 0x21

; вызывает ядро операционной системы


4. ПЕРЕЧЕНЬ ЗаданиЙ:

  1.  Поместить в регистр общего назначения AH число 3, в СH – число 6 и сложить полученные числа, результат сохранить в регистр DL
  2.  Поместить в регистр общего назначения CX число 10, в BX – число 17. Вычесть из регистра BX содержимое регистра СХ. Результат сохранить в переменную res.
  3.  Поместить в переменную num значение 10, в переменную denum значение 5. Сохранить результат выражения num/denum в регистр общего BX.
  4.  Поместить в переменную a1 значение 3, в переменную a2 значение 5. Сохранить результат выражения a1*a2 в регистр общего AX.
  5.  Поместить в регистр общего назначения AH число 3, в СH – число 4. Сохранить в регистр DX результат выражения (AHCH )*5.
  6.  Написать подпрограмму сложения двух чисел 5 и 2. Вывести результат на экран
  7.  Написать подпрограмму инкрементирования числа меньшего 7. Вывести результат на экран. Входное значение в подпрограмму передавать через регистры.
  8.  Написать подпрограмму декремента числа меньшего 10. Вывести результат на экран. Входное значение передавать через глобальные переменные.
  9.  Написать программу расчета выражения C=A+B/2. Все значения однобайтные целые. Результат вывести на экран.
  10.  Написать программу расчета выражения D=A+B+С*A. Все значения однобайтные целые. Результат вывести на экран.
  11.  Написать подпрограмму деления целых однобайтных чисел. Параметры передавать через регистры. Результат вывести на экран.
  12.  Написать подпрограмму деления целых однобайтных чисел. Параметры передавать через регистры. Результат вывести на экран.
  13.  Написать подпрограмму возведения в квадрат однобайтного числа 3. Результат вывести на экран и сохранить в переменную Q.
  14.  Написать программу расчета выражения A*B*C=V, где A, B, C – двухбайтные положительные числа.
  15.  Написать программу вывода числа A, если A = 3, в противном случае вывести число 2 (числа A и B выбираются из диапазона 0-9).
  16.  Написать программу инкремента числа X, если Y = X, в противном случае выполнить декремент числа Y (числа X и Y выбираются из диапазона 0-9).
  17.   Написать подпрограмму сравнения двух чисел. Если числа равны, то в регистр AX поместить 1, если числа неравны – в регистр AX поместить 0.

5. Состав отчета

  1.  Задание.
  2.  Текст программы с подробными комментариями.
  3.  Описание использованных команд.
  4.  Выводы.

6. Библиографический список

  1.  Архитектура ЭВМ и систем [Текст]: учебное пособие / Геннадий Владимирович Абрамов [и др.] ; Воронеж. гос. технол. акад. - Воронеж, 2006. - 155с.
  2.  Бройдо, В.Л. Архитектура ЭВМ и систем [Текст]: учебник для студ.вузов (гриф МО) / В. Л. Бройдо, О. П. Ильина. - 2-е изд. - СПб. : Питер, 2009. - 720с.
  3.  Бройдо, В.Л. Вычислительные системы, сети и телекоммуникации [Текст]: учебник для студ.вузов (гриф МО) / В. Л. Бройдо, О. П. Ильина. - 4-е изд. – СПб. : Питер, 2011. – 560 с.
  4.  Мелехин, В. Ф. Вычислительные машины, системы и сети [Текст]: учебник для студ. вузов обуч. по спец. "Автоматизация и управление" (гриф УМО) / В. Ф. Мелехин, Е. Г. Павловский. - 2-е изд., стер. - М.: Академия, 2007. – 560 с.
  5.  Олифер, В.Г. Сетевые операционные системы [Текст]: учебное пособие для студ. вузов (гриф МО) / В. Г. Олифер, Н. А. Олифер. - СПб. : Питер, 2006. - 539с.
  6.  Яремчук, С. Защита вашего компьютера [Текст] / С. Яремчук. - СПб. : Питер, 2008. - 288 с.

Учебное издание 

ОСНОВЫ ЯЗЫКА АССЕМБЛЕР

Методические указания для выполнения лабораторной работы 

по дисциплине «Вычислительные машины, системы и сети»

Для бакалавров направления 220400, 220700

Составители ХРОМЫХ Елена Алексеевна

                          КОЗЕНКО Иван Александрович

Редактор Н.А. Сотникова

Корректор Н.В. Бургонова

Компьютерный набор и вёрстка А.А. Хвостов, М.Н. Тарасов

Подписано в печать

Формат 60х84 1/16. Бумага офсетная. Гарнитура Таймс. Ризография.

             Усл. печ. л. 2,2. Уч.-изд. л. 2,0. Тираж 200 экз. Заказ         . C-

Воронежский государственный университет инженерных технологий (ВГУИТ)

Участок оперативной полиграфии ВГУИТ

Адрес академии и участка оперативной полиграфии:

394000 Воронеж, пр. Революции, 19


 

А также другие работы, которые могут Вас заинтересовать

16925. ФИЗИОЛОГИЯ СЕРДЦА И СОСУДОВ 797.5 KB
  Работа сердца как насоса, его гемодинам ическая производительность, является одним из решающих факторов, определяющих интенсивность кровотока и, соответственно, уровень снабжения органов и тканей кислородом и питательными веществами. При повышении активности организма, например, при совершении им определенной физической работы
16926. БИОЭЛЕКТРИЧЕСКИЕ ПОТЕНЦИАЛЫ. ПОТЕНЦИАЛ ДЕЙСТВИЯ НЕРВА 64.5 KB
  Тема. БИОЭЛЕКТРИЧЕСКИЕ ПОТЕНЦИАЛЫ. ПОТЕНЦИАЛ ДЕЙСТВИЯ НЕРВА. Вопросы теоретической подготовки: Строение нерва и нервных волокон. Потенциал действия. Динамика изменения ионной проницаемости. Критический уровень деполяризации. Причины абсолютной и относи...
16927. Гуморальная регуляция сердечной деятельности 57.5 KB
  Тема: ГУМОРАЛЬНАЯ РЕГУЛЯЦИЯ СЕРДЕЧНОЙ ДЕЯТЕЛЬНОСТИ. Под гуморальной регуляцией сердца понимают изменение его работы под влиянием кардиоактивных гормонов вырабатываемых железами внутренней секреции и поступающих в сердце с током крови гормональная регуляция или ...
16928. ДЕЙСТВИЕ ПОСТОЯННОГО ТОКА НА НЕРВ 134.5 KB
  ТЕМА ДЕЙСТВИЕ ПОСТОЯННОГО ТОКА НА НЕРВ Вопросы теоретической подготовки: Физический электротон и кабельные свойства нервных волокон. Критический уровень деполяризации и его изменения. Изменение физиологических параметров мембраны при деполяризации
16929. ИНТЕГРАТИВНЫЕ СВОЙСТВА ЦНС (НА ПРИМЕРЕ РЕФЛЕКСОВ СПИННОГО МОЗГА). СУММАЦИЯ В НЕРВНЫХ ЦЕНТРАХ 594 KB
  Раздел ФИЗИОЛОГИЯ ЦЕНТРАЛЬНОЙ НЕРВНОЙ СИСТЕМЫ. Тема. ИНТЕГРАТИВНЫЕ СВОЙСТВА ЦНС НА ПРИМЕРЕ РЕФЛЕКСОВ СПИННОГО МОЗГА. СУММАЦИЯ В НЕРВНЫХ ЦЕНТРАХ Вопросы теоретической подготовки: Клеточное строение рефлекторных дуг спинного мозга. Свойства нервных цент
16930. НЕРВНАЯ РЕГУЛЯЦИЯ РАБОТЫ СЕРДЦА 147 KB
  РАЗДЕЛ. ФИЗИОЛОГИЯ СЕРДЦА И СОСУДОВ. ТЕМА: НЕРВНАЯ РЕГУЛЯЦИЯ РАБОТЫ СЕРДЦА. Работа сердца как насоса его гемодинам ическая производительность является одним из решающих факторов определяющих интенсивность кровотока и соответственно уровень снабжения органов и тк...
16931. ФИЗИОЛОГИЯ СКЕЛЕТНЫХ МЫШЦ. НЕРВНО-МЫШЕЧНАЯ ПЕРЕДАЧА 128.5 KB
  Тема. ФИЗИОЛОГИЯ СКЕЛЕТНЫХ МЫШЦ. НЕРВНОМЫШЕЧНАЯ ПЕРЕДАЧА. Вопросы теоретической подготовки: Физиологические свойства мышечных волокон. Механизм возникновения возбуждения и его проведение в волокнах скелетной мышцы. Типы сокращений мышцы. Двигатель...
16932. ЭЛЕКТРОКАРДИОГРАММА: МЕТОДЫ РЕГИСТРАЦИИ, АНАЛИЗ, ФОРМИРОВАНИЕ 162.5 KB
  Тема. ЭЛЕКТРОКАРДИОГРАММА: МЕТОДЫ РЕГИСТРАЦИИ АНАЛИЗ ФОРМИРОВАНИЕ. При возбуждении сердца на его поверхности и в его тканях возникает разность потенциалов закономерно меняющаяся по величине и направлению. Биоэлектрическая активность разных отделов сердца возника...
16933. Синаптическая передача в ЦНС. Понятие о синапсе. Строение электрического и химического синаптических контактов 75.5 KB
  Физиология лекция №5 Синаптическая передача в ЦНС. Понятие о синапсе. Строение электрического и химического синаптических контактов. События происходящие в химическом синапсе. Медиаторы и принцип Дэйла. Ионотропные и метаботропные эффекты медиаторов. Модуляторы