Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Тема 2.1 Синтаксис языка ассемблер




Язык ассемблера — это низкоуровневый язык программирования, который транслируется непосредственно в инструкции машинного языка. Трансляцию выполняет специальная программа — ассемблер (от англ. assembler — сборщик).

У каждого семейства процессоров есть собственный набор инструкций для выполнения различных операций, например для получения ввода с клавиатуры, вывода информации на экран и выполнения других действий. Эти наборы инструкций называются «инструкциями машинного языка».

Инструкции машинного языка представлены в виде последовательностей из нулей и единиц. Создавать программное обеспечение в виде таких последовательностей очень сложно для человека. Поэтому был разработан низкоуровневый язык сборки, в котором инструкции представлены в более понятной для человека форме.

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

Для Intel, например, самые популярные ассемблеры это MASM (входит в состав Visual Studio), FASM и TASM, которые достаточно современны и поддерживают Win32 API (хотя их развитие, нужно признать, уже пару лет как остановлено).

2. Пример кода на языке ассемблера

Для DOS

Для примера используем FASM (Flat Assembler). Редактор кода FEditor 2. 0 предлагает следующий шаблон кода приложения типа «Hello World! » для DOS.

use16

org 100h

mov ah, 9

mov dx, mes

int 21h

mov ah, 0Ah

mov dx, key

int 21h

mov ax, 4C00h

int 21h

mes db 'Hello World! $'

key db 2, 0, 0, 0

Это инструкции языка ассемблера как таковые. В этом приложении не используются макросы, которые широко применяются в современных приложениях на языке ассемблера. Рассмотрим вкратце, что делает эта программа.

Используется 16-разрядная система, создается приложение. com.

В таких приложениях исполняемый код должен начинаться со смещения 100H. Первые адреса (до 0FFH) используются для префикса сегмента программы (Program Segment Prefix, PSP), в котором хранятся разные важные данные, которые крайне нежелательно перезаписывать.

В регистр AH помещается код команды вывода строки, а в dx — адрес этой строки, затем вызывается прерывание 21H, которое выполняет эту команду (это зарезервированный сервис со стороны DOS, что-то типа современного Win32 API).

Таким же образом готовится ожидание нажатия клавиши после вывода строки. Код команды — в ah, адрес буфера для строки — в dx.

После нажатия клавиши готовится команда завершения работа приложения. Ее код передается в регистр ax и снова вызывается прерывание.

Далее расположены определения данных: буфер для строки, которая выводится на экран, и для строки, которую представляет нажатая клавиша.

Вывод в DOSBox:

Windows — консольное

Пример 64-разрядного консольного приложения типа «Hello World! » на FASM, опять же из примеров FEditor.

format PE64 Console 5. 0

entry Start

include 'win64a. inc'

section '. text' code readable executable

Start:

invoke GetStdHandle, [STD_OUTP_HNDL]

mov [hStdOut], eax

invoke WriteConsoleA, [hStdOut], mes, mesLen, chrsWritten, 0

invoke ExitProcess, 0

section '. data' data readable writeable

mes db 'Hello World! ', 0dh, 0ah, 0

mesLen = $-mes

hStdOut dd 0

chrsWritten dd 0

STD_OUTP_HNDL dd -11

section '. idata' import data readable

library kernel, 'KERNEL32. DLL'

import kernel, \

GetStdHandle, 'GetStdHandle', \

WriteConsoleA, 'WriteConsoleA', \

ExitProcess, 'ExitProcess'

Объявляется формат выходного файла.

Объявляется точка входа в программу.

В программу включается файл заголовков для 64-разрядных систем Windows и кодировки ANSI для текущей кодовой страницы.

Объявляется секция кода.

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

Вызывается функция Windows для получения описателя стандартного потока вывода (для вывода в консоль). В результате ее выполнения этот описатель будет помещен в регистр EAX.

Этот описатель передается из регистра EAX по адресу, закрепленному за идентификатором hStdOut.

Вызывается API-функция Windows WriteConsole для вывода в консоль (по адресу, находящемуся в hStdOut), сообщения, расположенного в буфере, на который указывает указатель mes. Сообщение имеет длину mesLen символов. Фактическая длина выведенного сообщения отправляется по адресу, закрепленному за идентификатором chrsWritten. Последний параметр зарезервирован, и в него передается значение 0.

Вызывается функция Windows ExitProcess для выхода из приложения с нулевым кодом (успешное завершение).

Объявляется секция данных с доступом для чтения и записи. В нашем приложении она будет разбита на участки из байтов и двойных слов.

Объявляется буфер из байтов (db = define byte) для строки, которая будет выведена. Ее завершает нулевой байт.

По адресу с идентификатором mesLen размещается длина сообщения. Она получена путем вычитания адреса первого байта строки из текущего адреса ($).

По следующим двум адресам будут записаны указатель на поток стандартного вывода и количество выведенных символов (в виде двойных слов).

Указатель на константу для получения описателя потока стандартного вывода.

Объявляется секция импорта данных.

Объявляется псевдоним для библиотеки KERNEL32. DLL, из которой затем импортируются функции GetStdHandle, WriteConsoleA и ExitProcess.

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

Windows— GUI

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

; example of simplified Windows programming using complex macro features

include 'win32ax. inc'; you can simply switch between win32ax, win32wx, win64ax and win64wx here

. code

start:

invoke MessageBox, HWND_DESKTOP, " May I introduce myself? ", invoke GetCommandLine, MB_YESNO

. if eax = IDYES

invoke MessageBox, HWND_DESKTOP, " Hi! I'm the example program! ", " Hello! ", MB_OK

. endif

invoke ExitProcess, 0

. end start

Он выводит диалоговое окно с сообщением, а затем, если будет нажата кнопка «Да», выводит еще одно диалоговое окно.

3. Синтаксис языка ассемблера

Синтаксис языка ассемблера зависит, в основном, от набора команд процессора. С другой стороны его определяют директивы определенного транслятора. Поэтому, например, для процессоров, совместимых с Intel, есть синтаксис Intel и синтаксис AT& T.

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...