Баннер мобильный (1) Пройти тест

Ассемблер

Глоссарий

28 февраля 2024

Поделиться

Скопировано

Содержание

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

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

    Как выглядит язык ассемблер
    Пример кода на ассемблере. Источник

    Начинают изучение программирования обычно с вывода на экран строки «Hello, world!». В языке программирования Python для этого достаточно одной команды:

    print("Hello, World!")

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

    .MODEL SMALL
    .STACK 100h
    .DATA
        HelloMessage DB 'Hello, World!',13,10,'$'
    .CODE
    START:
        mov ax,@data
        mov ds,ax
        mov ah,9
        mov dx,OFFSET HelloMessage
        int 21h
        mov ah,4ch
        int 21h
    END START

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

    Кратко про процессоры и машинный язык

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

    язык ассемблер низкоуровневый язык программирования
    Схематическое изображение уровня языков программирования. Источник

    Процессор представляет собой электронное устройство, которое, несмотря на свою маленькую размерность сегодня (раньше процессоры занимали целые залы), не обладает способностью понимать слова или цифры. Его реакция основана исключительно на двух уровнях напряжения: высокий уровень соответствует «1», а низкий уровень — «0». Таким образом, каждая команда процессора представляет собой последовательность нулей и единиц: «1» — это импульс, а «0» — его отсутствие.

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

    Например, в архитектуре Intel 8088 инструкция 0000001111000011B представляет операцию сложения двух чисел, в то время как 0010101111000011B выполняет вычитание.

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

    Поэтому был разработан язык ассемблера, в котором операции обозначаются буквами и сокращениями английских слов, отражающих суть команды. Например, команда mov ax, 6 означает: «переместить число 6 в регистр AX».

    Основы ассемблера

    Ниже приведена таблица с примерами машинного кода, соответствующими инструкциями на ассемблере и их описаниями:

    Машинный кодИнструкции на ассемблереОписание
    10110000MOV AL, 0Загрузить значение 0 в регистр AL
    10110001MOV BL, 1Загрузить значение 1 в регистр BL
    10001011ADD AL, BLСложить значения в регистрах AL и BL
    00100000JMP labelБезусловный переход к метке (адресу) label
    11001001CMP AX, BXСравнить значения в регистрах AX и BX
    01100010JZ labelПереход к метке label, если флаг ZF=1
    10010110SUB AL, 6Вычесть 6 из значения в регистре AL
    11001000AND AX, BXПобитовое И между значениями AX и BX
    11101010OR AL, 10Побитовое ИЛИ значения в регистре AL и 10
    10111000XOR AL, 8Побитовое исключающее ИЛИ с 8 в регистре AL
    00000000NOPПустая операция (ничего не делать)
    01100110PUSH AXПоложить значение из регистра AX в стек
    10010111POP CXИзвлечь значение из стека в регистр CX
    11011000CALL subroutineВызвать подпрограмму (переход с сохранением адреса возврата)
    00010001RETВернуться из подпрограммы (извлечь адрес возврата и перейти туда)
    10001000INC ALУвеличить значение в регистре AL на 1
    10011000DEC ALУменьшить значение в регистре AL на 1
    10001111NOT ALПобитовое отрицание значения в регистре AL
    10001110NEG ALЗнаковое отрицание значения в регистре AL
    Таблица с примерами машинного кода и ассемблера

    История создания ассемблера

    Это произошло в период сороковых годов прошлого века. Ассемблер возник для обеспечения работы первых электронно-ламповых ЭВМ, программы для которых писались на машинном языке. В то время, так как объем памяти у компьютеров был ограничен, команды вводились путем переключения тумблеров и нажатия кнопок. Простейшие вычисления занимали значительное количество времени.

    Компьютер на лампах, предшественник эпохи ассемблера
    ЭВМ ENIAC на электронных лампах. Источник

    Проблема была решена, когда ЭВМ научились хранить программы в памяти. В 1950 году была разработана первая программа-транслятор, которая переводила программы, написанные на понятном человеку языке, в машинный код. Эта программа была названа программой-сборщиком, а язык программирования получил название «ассемблера» (от английского слова «assembler» — сборщик). Впервые этот термин стал использовать английский учёный Морис Уилкс (Maurice Wilkes).

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

    Как устроен язык ассемблер

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

    Код ассемблера
    Код ассемблера из кодов операций и операндов. Источник

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

    Операции в языке ассемблера имеют мнемоническую форму, что делает их удобными для запоминания:

    • ADD — сложение (от англ. addition);
    • SUB — вычитание (от англ. subtraction);
    • MUL — умножение (от англ. multiplication) и так далее.

    Регистры и ячейки памяти получают символические имена, например:

    • EAX, EBX, AX, AH — имена для регистров;
    • mem1 — имя для ячейки памяти.

    Пример команды сложения чисел из регистров AX и BX:

    add ax, bx

    И вот команда вычитания чисел из регистров AX и BX:

    sub ax, bx

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

    Некоторые из них:

    • INCLUDE — открыть файл и начать его компиляцию;
    • EXIT — прекратить компиляцию файла;
    • DEF — назначить регистру символическое имя и так далее.

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

    Вот пример ассемблерного кода, который выводит на экран цифры от 1 до 10:

    section .text global _start _start: mov ecx,10 mov eax, '1'
    
    label1: mov [num], eax mov eax, 4 mov ebx, 1 push ecx
    
    mov ecx, num
    mov edx, 1
    int 0x80
    
    mov eax, [num] sub eax, '0' inc eax add eax, '0' pop ecx loop label1
    
    mov eax,1
    int 0x80
    section .bss num resb 1
    Видео про язык ассемлера. Источник

    Почему для разных семейств процессоров нужен свой ассемблер

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

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

    Кому и зачем нужен язык ассемблера?

    Ассемблер, даже по нашему примеру «Hello, World!», показывает, что он не так удобен для разработки, как языки высокого уровня. Большие программы на этом языке уже никто не пишет, но есть области, где он становится незаменимым: 

    1. Разработка встроенных программ для микроконтроллеров. Микроконтроллеры устанавливаются в системах сигнализации, пультах управления, датчиках, бытовой технике, модемах и других устройствах. Микроконтроллеры даже используются в робототехнике и спутниковых навигационных системах. Память у них ограничена, поэтому ассемблер идеально подходит для их программирования, так как каждая его команда транслируется в одну команду в двоичном коде. Это позволяет определить время выполнения программы и объем памяти, необходимый для ее хранения, исходя из исходного текста программы.
    2. Написание драйверов устройств и некоторых компонентов операционных систем, например, ядра или загрузчика. Некоторые любительские операционные системы, такие как MenuetOS и KolibriOS, полностью написаны на ассемблерном коде. Его также можно найти и в программах для игровых приставок и мультимедийных кодеков.
    3. Реверс-инжиниринг — обратная разработка программ. Область используется для понимания работы программ и их алгоритмов в случаях, когда исходный код не доступен по каким-либо причинам. Этим занимаются антивирусные компании, исследующие вирусы и трояны, создатели драйверов и операционных систем, а также просто любопытные люди. Кроме того, компьютерные злоумышленники также активно используют реверс-инжиниринг для взлома программ, поиска уязвимостей, написания вирусов, генерации ключей и прочих противоправных действий.

    Таким образом, если вам интересно разрабатывать новые микропроцессоры или заниматься реверс-инжинирингом, то стоит серьезно изучить язык ассемблера.

    Востребованность программистов на ассемблере в 2023

    Программисты на ассемблере востребованы, хотя на веб-сайтах по поиску работы, вероятнее всего, вы не найдете вакансий с заголовками «Требуется программист на ассемблере». Зато там много объявлений, которые требуют знание языка в дополнение к языкам высокого уровня, таким как C, C++ или Python. Вакансии могут быть связаны с реверс-инженерингом, компьютерной безопасностью, разработкой драйверов и программ для микроконтроллеров/микропроцессоров, а также системным программированием и другими областями.

    Вакансия программист на ассемблере с зарплатой и требованиями
    Вакансия hh на программиста Ассемблера

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

    Стоит ли начинать изучение программирования с языка ассемблера

    Нет, такой подход не рекомендуется. На это есть несколько причин:

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

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

    Поделиться

    Скопировано

    0 комментариев

    Комментарии