Язык ассемблера: различия между версиями
[отпатрулированная версия] | [непроверенная версия] |
AVB (обсуждение | вклад) м ← Откат правок 89.239.173.36 (обс) к версии EleferenBot |
|||
Строка 26: | Строка 26: | ||
=== Недостатки === |
=== Недостатки === |
||
* [[Файл:symbol oppose vote.svg|15px]] Главное преимущество ассемблера |
* [[Файл:symbol oppose vote.svg|15px]] Главное преимущество ассемблера почти незаметно благодаря хорошей [[Оптимизация компилятора|оптимизацией]] в современных [[компилятор]]ах [[Высокоуровневый язык программирования|языков высокого уровня]] и окончательно полностью нивелируется хорошей оптимизацией современных аппаратных платформ с кэшированием шины процессора.{{нет АИ|23|07|2009}} |
||
* [[Файл:symbol oppose vote.svg|15px]] В силу своей машинной ориентации («низкого» уровня) человеку по сравнению с языками программирования высокого уровня иногда сложнее читать и понимать программу, она состоит из слишком «мелких» элементов — машинных команд, соответственно усложняются программирование и отладка, растет трудоемкость, велика вероятность внесения ошибок. В значительной степени возрастает сложность совместной разработки. |
* [[Файл:symbol oppose vote.svg|15px]] В силу своей машинной ориентации («низкого» уровня) человеку по сравнению с языками программирования высокого уровня иногда сложнее читать и понимать программу, она состоит из слишком «мелких» элементов — машинных команд, соответственно усложняются программирование и отладка, растет трудоемкость, велика вероятность внесения ошибок. В значительной степени возрастает сложность совместной разработки. |
||
* [[Файл:symbol oppose vote.svg|15px]] Как правило, меньшее количество доступных [[библиотека (программирование)|библиотек]] по сравнению с современными индустриальными языками программирования. |
* [[Файл:symbol oppose vote.svg|15px]] Как правило, меньшее количество доступных [[библиотека (программирование)|библиотек]] по сравнению с современными индустриальными языками программирования. |
Версия от 12:19, 2 марта 2010
В статье не хватает ссылок на источники (см. рекомендации по поиску). |
Язык ассемблера (автокод) — язык программирования низкого уровня. В отличие от языка машинных кодов, позволяет использовать более удобные для человека мнемонические (символьные) обозначения команд. При этом для перевода с языка ассемблера в понимаемый процессором машинный код требуется специальная программа, называемая ассемблером.
Содержание языка
Команды языка ассемблера один к одному соответствуют командам процессора, фактически, они представляют собой более удобную для человека символьную форму записи (мнемокод) команд и их аргументов.
Кроме того, язык ассемблера обеспечивает использование символических меток вместо адресов ячеек памяти, которые при ассемблировании заменяются на автоматически рассчитываемые абсолютные или относительные адреса, а также так называемых директив (команд, не переводящихся в процессорные инструкции, а выполняемых самим ассемблером).
Директивы ассемблера позволяют, в частности, включать блоки данных, задать ассемблирование фрагмента программы по условию, задать значения меток, использовать макроопределения с параметрами.
Каждая модель (или семейство) процессоров имеет свой набор команд и соответствующий ему язык ассемблера. Наиболее популярные синтаксисы: Intel-синтаксис и AT&T-синтаксис.
Существуют компьютеры, реализующие в качестве машинного язык программирования высокого уровня (Forth, Lisp, Эль-76), фактически в них он является «ассемблером».
Достоинства и недостатки
Достоинства
- Язык ассемблера позволяет писать самый быстрый и компактный код, как минимум не хуже, чем генерируемый трансляторами языков более высокого уровня, всё зависит от способностей программиста.
- Если код программы достаточно большой, данные, которыми он оперирует, не помещаются целиком в регистрах процессора, т.е. частично или полностью находятся в оперативной памяти, то искусный программист, как правило, способен значительно оптимизировать программу по сравнению с высокоуровневыми трансляторами по одному или нескольким параметрам: скорость работы (за счёт оптимизации вычислений и/или более рационального обращения к ОП, перераспределения данных), объём кода (в том числе за счёт эффективного использования промежуточных результатов).
- Обеспечение максимального использования специфических возможностей конкретной платформы, что также позволяет создавать более эффективные программы с меньшими затратами ресурсов.
- При программировании на ассемблере возможен непосредственный доступ к аппаратуре, в том числе портам ввода-вывода, регистрам процессора, и др.
- Язык ассемблера применяется для создания драйверов оборудования и ядра операционной системы
- Язык ассемблера используется для создания «прошивок» BIOS.
- С помощью языка ассемблера создаются компиляторы и интерпретаторы языков высокого уровня, а также реализуется совместимость платформ.
- Существует возможность исследования других программ с отсутствующим исходным кодом с помощью дизассемблера.
Недостатки
- Главное преимущество ассемблера почти незаметно благодаря хорошей оптимизацией в современных компиляторах языков высокого уровня и окончательно полностью нивелируется хорошей оптимизацией современных аппаратных платформ с кэшированием шины процессора.[источник не указан 5630 дней]
- В силу своей машинной ориентации («низкого» уровня) человеку по сравнению с языками программирования высокого уровня иногда сложнее читать и понимать программу, она состоит из слишком «мелких» элементов — машинных команд, соответственно усложняются программирование и отладка, растет трудоемкость, велика вероятность внесения ошибок. В значительной степени возрастает сложность совместной разработки.
- Как правило, меньшее количество доступных библиотек по сравнению с современными индустриальными языками программирования.
- Отсутствует переносимость программ на компьютеры с другой архитектурой и системой команд (кроме двоично-совместимых).
Применение
Исторически можно рассматривать ассемблер как второе поколение языков программирования ЭВМ (если первым считать машинный код). Недостатки ассемблера, сложность разработки на нем больших программных комплексов привели к появлению языков третьего поколения — языков программирования высокого уровня (Фортран, Лисп, Кобол, Паскаль, Си и др.). Именно языки программирования высокого уровня и их наследники в основном используются в настоящее время в индустрии информационных технологий. Однако, языки ассемблера сохраняют свою нишу, обуславливаемую их уникальными преимуществами в части эффективности и возможности полного использования специфических средств конкретной платформы.
На ассемблере пишутся программы или фрагменты программ, для которых критически важны:
- быстродействие (драйверы, игры);
- объем используемой памяти (загрузочные сектора, встраиваемое (англ. embedded) программное обеспечение, программы для микроконтроллеров и процессоров с ограниченными ресурсами, вирусы, программные защиты).
С использованием программирования на ассемблере производятся:
- Оптимизация критичных к скорости участков программ написанных на языке высокого уровня, таком как C++. Это особенно актуально для игровых приставок, у которых фиксированная производительность, и для мультимедийных кодеков, которые стремятся делать менее ресурсоемкими и более популярными.
- Создание операционных систем (ОС). ОС часто пишут на Си, языке, который специально был создан для написания одной из первых версий Unix. Аппаратно зависимые участки кода, такие, как загрузчик ОС, уровень абстрагирования от аппаратного обеспечения — HAL и ядро, часто пишутся на ассемблере. Ассемблерного кода в ядрах Windows или Linux совсем немного, поскольку авторы стремятся к переносимости и надёжности, но тем не менее он присутствует. Некоторые любительские ОС, такие, как MenuetOS, целиком написаны на ассемблере. При этом MenuetOS помещается на дискету и содержит графический многооконный интерфейс.
- Программирование микроконтроллеров (МК) и других встраиваемых процессоров. По мнению профессора Танненбаума, развитие МК повторяет историческое развитие компьютеров новейшего времени.[1] На сегодняшний день для программирования МК весьма часто применяют ассемблер. В МК приходится перемещать отдельные байты и биты между различными ячейками памяти. Программирование МК весьма важно, так как, по мнению Танненбаума, в автомобиле и квартире современного цивилизованного человека в среднем содержится 50 микроконтроллеров.[2]
- Создание драйверов. Некоторые участки драйверов, взаимодействующие с аппаратным обеспечением, программируют на ассемблере. Хотя в целом в настоящее время драйверы стараются писать на языках высокого уровня в связи с повышенными требованиями к надёжности. Надёжность для драйверов играет особую роль, поскольку в Windows NT и Linux драйверы работают в режиме ядра. Одна ошибка может привести к краху системы.
- Создание антивирусов и других защитных программ.
- Написание трансляторов языков программирования.
Связывание программ на разных языках
Поскольку на ассемблере часто разрабатываются только фрагменты программ, их необходимо связывать с остальными частями программной системы, написанными на других языках программирования.
Это достигается 2 основными способами:
- На этапе компиляции — вставка в программу ассемблерных фрагментов (англ. inline assembler) с помощью специальных директив языка (в частности, данный способ поддерживается языком программирования Си), в том числе написание функций на языке ассемблера. Способ удобен для несложных преобразований данных, но полноценного ассемблерного кода, с данными и подпрограммами, включая подпрограммы с множеством входов и выходов, не поддерживаемых высокоуровневыми языками, с помощью него сделать нельзя.
- На этапе компоновки, или раздельной компиляции. Для взаимодействия скомпонованных модулей достаточно, чтобы связующие функции (определённые в одних модулях и использующиеся в других) поддерживали нужные соглашения вызова (англ. calling conventions) и типы данных. Написаны же отдельные модули могут быть на любых языках, в том числе и на ассемблере.
Синтаксис
Синтаксис языка ассемблера определяется системой команд конкретного процессора.
Набор команд
Типичными командами языка ассемблера являются (большинство примеров даны для Intel-синтаксиса архитектуры x86):
- Команды пересылки данных (mov, lea и т. д.)
- Арифметичекие команды (add, sub, imul и т. д.)
- Логические и побитовые операции (or, and, xor, shr и т. д.)
- Команды управления ходом выполнения программы (jmp, loop, ret и т. д.)
- Команды вызова прерываний (иногда относят к командам управления): int, into
- Команды ввода/вывода в порты (in, out)
- Для микроконтроллеров и микрокомпьютеров характерны также команды, выполняющие проверку и переход по условию, например:
- cbne — перейти, если не равно
- dbnz — декрементировать, и если результат ненулевой, то перейти
- cfsneq — сравнить, и если не равно, пропустить следующую команду
Инструкции
Типичный формат записи команд:
[метка:] опкод [операнды] [;комментарий]
где опкод (код операции) — непосредственно мнемоника инструкции процессору. К ней могут быть добавлены префиксы (повторения, изменения типа адресации и пр.).
В качестве операндов могут выступать константы, адреса регистров, адреса в оперативной памяти и пр.. Различия между стандартами Intel и AT&T касаются, в основном, порядка перечисления операндов и их синтаксиса при различных методах адресации.
Используемые мнемоники обычно одинаковы для всех процессоров одной архитектуры или семейства архитектур (среди широко известных — мнемоники процессоров и контроллеров x86, ARM, SPARC, PowerPC, M68k). Они описываются в спецификации процессоров. Возможные исключения:
- Если ассемблер использует кроссплатформенный AT&T-синтаксис (оригинальные мнемоники приводятся к синтаксису AT&T)
- Если изначально существовало два стандарта записи мнемоник (система команд была наследована от процессора другого производителя).
Например, процессор Zilog Z80 наследовал систему команд Intel i8080, расширил ее и поменял мнемоники (и обозначения регистров) на свой лад. Процессоры Motorola Fireball наследовали систему команд Z80, несколько её урезав. Вместе с тем, Motorola официально вернулась к мнемоникам Intel. И в данный момент половина ассемблеров для Fireball работает с интеловскими мнемониками, а половина с мнемониками Zilog.
Директивы
Программа на ассемблере может содержать директивы: инструкции, не переводящиеся непосредственно в машинные команды, а управляющие работой компилятора. Набор и синтаксис их значительно разнятся и зависят не от аппаратной платформы, а от используемого транслятора (порождая диалекты языков в пределах одного семейства архитектур). В качестве «джентельменского набора» директив можно выделить следующие:
- определение данных (констант и переменных)
- управление организацией программы в памяти и параметрами выходного файла
- задание режима работы компилятора
- всевозможные абстракции (то есть элементы языков высокого уровня) — от оформления процедур и функций (для упрощения реализации парадигмы процедурного программирования) до условных конструкций и циклов (для парадигмы структурного программирования)
- макросы
Пример программы
Примеры программы Hello, world! для разных платформ и разных диалектов:
.MODEL TINY
CODE SEGMENT
ASSUME CS:CODE, DS:CODE
ORG 100h
START:
mov ah,9
mov dx,OFFSET Msg
int 21h
int 20h
Msg DB 'Hello World',13,10,'$'
CODE ENDS
END START
SECTION .data
msg: db "Hello, world",10
len: equ $-msg
SECTION .text
global _start
_start: mov edx, len
mov ecx, msg
mov ebx, 1 ; stdout
mov eax, 4 ; write(2)
int 0x80
mov ebx, 0
mov eax, 1 ; exit(2)
int 0x80
SECTION .data
msg: db "Hello, world",10
len: equ $-msg
SECTION .text
global _start
syscall: int 0x80
ret
_start: push len
push msg
push 1 ; stdout
mov eax, 4 ; write(2)
call syscall
add esp, 3*4
push 0
mov eax, 1 ; exit(2)
call syscall
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
.data
msg db "Hello, world", 13, 10
len equ $-msg
.data?
written dd ?
.code
start:
push -11
call GetStdHandle
push 0
push offset written
push len
push offset msg
push eax
call WriteFile
push 0
call ExitProcess
end start
format PE console
entry start
include 'include\win32a.inc'
section '.data' data readable writeable
message db 'Hello, world!',0
section '.code' code readable executable
start:
; CINVOKE макрос в составе FASM.
; Позволяет вызывать CDECL-функции.
cinvoke printf,message
cinvoke getch
; INVOKE аналогичный макрос для STDCALL-функций.
invoke ExitProcess,0
section '.idata' import data readable
library kernel,'kernel32.dll',\
msvcrt,'msvcrt.dll'
import kernel,\
ExitProcess,'ExitProcess'
import msvcrt,\
printf,'printf',\
getch,'_getch'
.section ".data"
hello: .asciz "Hello World!\n"
.section ".text"
.align 4
.global main
main:
save %sp, -96, %sp ! выделяем память
mov 4, %g1 ! 4 = WRITE (системный вызов)
mov 1, %o0 ! 1 = STDOUT
set hello, %o1
mov 14, %o2 ! количество символов
ta 8 ! вызов системы
! выход из программы
mov 1, %g1 ! move 1(exit() syscall) into %g1
mov 0, %o0 ! move 0(return address) into %o0
ta 8 ! вызов системы
org 7C00h
use16
jmp code
nop
db 'hellowrd'
SectSize dw 00200h
ClustSize db 001h
ResSecs dw 00001h
FatCnt db 002h
RootSiz dw 000E0h
TotSecs dw 00B40h
Media db 0F0h
FatSize dw 00009h
TrkSecs dw 00012h
HeadCnt dw 00002h
HidnSec dw 00000h
code:
cli
mov ax, cs
mov ds, ax
mov ss, ax
mov sp, 7c00h
sti
mov ax,0b800h
mov es,ax
mov di,200
mov ah,2
mov bx,MessStr
msg_print:
mov al,[cs:bx]
mov [es:di],ax
inc bx
add di,2
cmp bx,MessEnd
jnz msg_print
loo:
jmp loo
MessStr equ $
Message db 'Hello, World!'
MessEnd equ $
Происхождение и критика термина «язык ассемблера»
Данный тип языков получил свое название от названия транслятора (компилятора) с этих языков — ассемблера (англ. assembler — сборщик). Название обусловлено тем, что программа «автоматически собиралась», а не вводилась вручную покомандно непосредственно в кодах. При этом наблюдается путаница терминов: ассемблером нередко называют не только транслятор, но и соответствующий язык программирования («программа на ассемблере»).
Использование термина «язык ассемблера» также может вызвать ошибочное мнение о существовании некоего единого языка низкого уровня, или хотя бы стандартов на такие языки. При именовании языка ассемблера желательно уточнять, ассемблер для какой архитектуры имеется в виду.
В СССР язык ассемблера ранее называли «автокод».
См. также
Примечания
Литература
- Галисеев Г. В. Ассемблер для Win 32. Самоучитель. — М.: Диалектика, 2007. — 368 с. — ISBN 978-5-8459-1197-1.
- Зубков С. В. Ассемблер для DOS, Windows и UNIX. — М. ДМК Пресс; СПб. Питер, 2006. — 608 с. — ISBN 5-94074-259-9.
- Кип Ирвин. Язык ассемблера для процессоров Intel = Assembly Language for Intel-Based Computers. — М.: Вильямс, 2005. — 912 с. — ISBN 0-13-091013-9.
- Калашников О. А. Ассемблер? Это просто! Учимся программировать. — СПб.: БХВ-Петербург, 2007. — 384 с. — ISBN 978-5-94157-709-5.
- Крис Касперски. Искусство дизассемблирования. — СПб.: БХВ-Петербург, 2008. — 896 с. — ISBN 978-5-9775-0082-1.
- Владислав Пирогов. Ассемблер для Windows. — СПб.: БХВ-Петербург, 2007. — 896 с. — ISBN 978-5-9775-0084-5.
- Владислав Пирогов. Ассемблер и дизассемблирование.. — СПб.: БХВ-Петербург, 2006. — 464 с. — ISBN 5-94157-677-3.
- Ричард Саймон. Microsoft Windows API Справочник системного программиста.
- Фрунзе А. В. Микроконтроллеры? Это же просто!. — Т. 1.
Ссылки
- WASM.ru — портал, посвящённый информационной безопасности и программированию на языках ассемблера.