Язык ассемблера | |
---|---|
Класс языка | язык программирования |
Появился в | 1949 |
Расширение файлов |
.asm |
Язы́к ассе́мблера (англ. assembly language) — машинно-ориентированный язык программирования низкого уровня. Его команды прямо соответствуют отдельным командам машины или их последовательностям, также он может предоставлять дополнительные возможности облегчения программирования, такие как макрокоманды, выражения, средства обеспечения модульности программ. Может рассматриваться как автокод (см. ниже), расширенный конструкциями языков программирования высокого уровня[1][2]. Является существенно платформо-зависимым. Языки ассемблера для различных аппаратных платформ несовместимы, хотя могут быть в целом подобны.
В русском языке может именоваться просто «ассемблером» (типичны выражения типа «писать программу на ассемблере»), что, строго говоря, неверно, так как ассемблером именуется утилита трансляции программы с языка ассемблера в объектный код компьютера.
Автокод — язык программирования, предложения которого по своей структуре в основном подобны командам и обрабатываемым данным конкретного машинного языка[2].
Язык ассемблера — система обозначений, используемая для представления в удобно читаемой форме программ, записанных в машинном коде. Язык ассемблера позволяет программисту пользоваться алфавитными мнемоническими кодами операций, по своему усмотрению присваивать символические имена регистрам ЭВМ и памяти, а также задавать удобные для себя схемы адресации (например, индексную или косвенную). Кроме того, он позволяет использовать различные системы счисления (например, десятичную или шестнадцатеричную) для представления числовых констант и даёт возможность помечать строки программы метками с символическими именами с тем, чтобы к ним можно было обращаться (по именам, а не по адресам) из других частей программы (например, для передачи управления)[3].
Перевод программы на языке ассемблера в исполнимый машинный код (вычисление выражений, раскрытие макрокоманд, замена мнемоник собственно машинными кодами и символьных адресов на абсолютные или относительные адреса) производится ассемблером — программой-транслятором, которая и дала языку ассемблера его название.
Команды языка ассемблера один к одному соответствуют командам процессора. Фактически, они и представляют собой более удобную для человека символьную форму записи — мнемокоды — команд и их аргументов. При этом одной команде языка ассемблера может соответствовать несколько вариантов команд процессора[4].
Кроме того, язык ассемблера позволяет использовать символические метки вместо адресов ячеек памяти, которые при ассемблировании заменяются на вычисляемые ассемблером или компоновщиком абсолютные или относительные адреса, а также так называемые директивы (команды ассемблера, не переводимые в машинные команды процессора, а выполняемые самим ассемблером).
Директивы ассемблера позволяют, в частности, включать блоки данных, задать ассемблирование фрагмента программы по условию, задать значения меток, использовать макрокоманды с параметрами.
Каждая модель (или семейство) процессоров имеет свой набор — систему — команд и соответствующий ему язык ассемблера. Наиболее популярные синтаксисы языков ассемблера — Intel-синтаксис и AT&T-синтаксис.
Существуют компьютеры, реализующие в качестве машинного язык программирования высокого уровня (Форт, Лисп, Эль-76). Фактически, в таких компьютерах они выполняют роль языков ассемблера.
Использование языка ассемблера предоставляет программисту ряд возможностей, как правило, недоступных при программировании на языках высокого уровня. Большинство из них связано с близостью языка к аппаратной платформе.
Использование ассемблера практически не имеет альтернативы при создании:
Отдельно можно отметить, что с помощью программы-дизассемблера возможно преобразование откомпилированной программы в программу на языке ассемблера. В большинстве случаев это единственный (хотя и крайне трудоёмкий) способ обратного реконструирования алгоритмов программы, если не доступен её исходных код на языке высокого уровня.
Исторически, если первым поколением языков программирования считать машинные коды, то язык ассемблера можно рассматривать как второе поколение языков программирования. Недостатки языка ассемблера, сложность разработки на нём больших программных комплексов привели к появлению языков третьего поколения — языков программирования высокого уровня (таких как Фортран, Лисп, Кобол, Паскаль, Си и др.). Именно языки программирования высокого уровня и их наследники в основном используются в настоящее время в индустрии информационных технологий. Однако языки ассемблера сохраняют свою нишу, обусловленную их уникальными преимуществами в части эффективности и возможности полного использования специфических средств конкретной платформы.
На языке ассемблера пишут программы или их фрагменты в тех случаях, когда критически важны:
С использованием программирования на языке ассемблера производятся:
Поскольку уже давно на языке ассемблера часто кодируют только фрагменты программ, их необходимо связывать с остальными частями программной системы, написанными на других языках программирования. Это достигается двумя основными способами:
Синтаксис языка ассемблера определяется системой команд конкретного процессора.
Типичными командами языка ассемблера являются (большинство примеров даны для Intel-синтаксиса архитектуры x86):
mov
и др.)add
, sub
, imul
и др.)or
, and
, xor
, shr
и др.)jmp
, loop
, ret
и др.)int
in
, out
)cjne
— перейти, если не равноdjnz
— декрементировать, и если результат ненулевой, то перейтиcfsneq
— сравнить, и если не равно, пропустить следующую команду[метка:] [ [префикс] мнемокод [операнд {, операнд}] ] [;комментарий]
где мнемокод — непосредственно мнемоника инструкции процессору. К ней могут быть добавлены префиксы (повторения, изменения типа адресации и пр.).
В качестве операндов могут выступать константы, адреса регистров, адреса в оперативной памяти и пр. Различия между синтаксисом Intel и AT&T касаются в основном порядка перечисления операндов и указания различных методов адресации.
Используемые мнемоники обычно одинаковы для всех процессоров одной архитектуры или семейства архитектур (среди широко известных — мнемоники процессоров и контроллеров x86, ARM, SPARC, PowerPC, M68k). Они описываются в спецификации процессоров. Возможные исключения:
Например, процессор Zilog Z80 наследовал систему команд Intel 8080, расширил её и поменял мнемоники (и обозначения регистров) на свой лад. Процессоры Motorola Fireball наследовали систему команд Z80, несколько её урезав. Вместе с тем, Motorola официально вернулась к мнемоникам Intel и в данный момент половина ассемблеров для Fireball работает с мнемониками Intel, а половина — с мнемониками 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
.MODEL SMALL
.DATA
msg DB 'Hello World',13,10,'$'
.CODE
START:
mov ax, @DATA
mov ds, ax
mov ax, 0900h
lea dx, msg
int 21h
mov ax, 4C00h
int 21h
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'
;yasm-1.0.0-win32.exe -f win64 HelloWorld_Yasm.asm
;setenv /Release /x64 /xp
;link HelloWorld_Yasm.obj Kernel32.lib User32.lib /entry:main /subsystem:windows /LARGEADDRESSAWARE:NO
bits 64
global main
extern MessageBoxA
extern ExitProcess
section .data
mytit db 'The 64-bit world of Windows & assembler...', 0
mymsg db 'Hello World!', 0
section .text
main:
mov r9d, 0 ; uType = MB_OK
mov r8, mytit ; LPCSTR lpCaption
mov rdx, mymsg ; LPCSTR lpText
mov rcx, 0 ; hWnd = HWND_DESKTOP
call MessageBoxA
mov ecx, eax ; uExitCode = MessageBox(...)
call ExitProcess
ret
.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 — сборщик). Название обусловлено тем, что программа «автоматически собиралась», а не вводилась вручную покомандно непосредственно в кодах. При этом наблюдается путаница терминов: ассемблером нередко называют не только транслятор, но и соответствующий язык программирования («программа на ассемблере»).
Использование термина «язык ассемблера» также может вызвать ошибочное мнение о существовании некоего единого языка низкого уровня или хотя бы стандартов на такие языки. При именовании языка ассемблера желательно уточнять, ассемблер для какой архитектуры имеется в виду.
![]() |
Язык ассемблера в Викиучебнике |
---|---|
![]() |
Язык ассемблера на Викискладе |
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .