На чем написан ассемблер
Перейти к содержимому

На чем написан ассемблер

  • автор:

Как компилятор может быть написан на том же языке который он компилирует?

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

Отслеживать
задан 18 апр 2021 в 7:57
425 3 3 серебряных знака 15 15 бронзовых знаков

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Компилятор си написан на предыдущей версии компилятора. Но когда то давно-давно существовал момент, когда компилятор си был написан на чем то другом. Я к сожалению, не знаю этого момента.

Но вот с плюсовым компилятором все проще — вначале был написан cfront — программа на си, которая переводила «плюсовый код» в сишный, а потом уже компилировала.

С другими языками также такое происходило. К примеру, go был вначале написан на си, а потом код так модифицировали, что бы он был максимально похож на go код (https://go-review.googlesource.com/c/go/+/5652).

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

Но как появился самый первый компилятор тогда? Есть хорошая статья https://jameshfisher.com/2018/01/11/bootstrapping-a-c-compiler/ которая описывает, как поэтапно можно это сделать.

То есть, вначале все пишется ручками в памяти, в ноликах и единицах, потом постепенно наращиваются инструменты и в конце концов, такими итерациями можно дойти до современного мира. Вот люди пишут простейший си компилятор https://github.com/rdtscp/c-bootstrap

И будет ли трансляция в ассемблер по сути равна компиляции

если у нас есть компилятор ассемблера, то да. Почему «компилятор»? потому что ассемблеры бывают разные. Тот же FLAT assembler обладает таким разувесистым синтаксисом, что я бы побоялся его называть его компилятор «программой для замены на двоичный код».

Да, процесс, когда компилятор компилирует сам себя называется bootstrapping. и это не имеет отношения к html.

Ассемблер

Ассемблер (англ. «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».

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

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

Компьютер на лампах, предшественник эпохи ассемблера

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

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

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

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

Код ассемблера

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

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

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

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

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

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

И вот команда вычитания чисел из регистров 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

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

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

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

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

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

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

Статьи по теме:

Как писать на ассемблере в 2021 году

Несмотря на наличие множества языков различной степени высокоуровневости, сегодня ассемблер не потерял своей актуальности и в индексе TIOBE находится на почётном 10-ом месте (на февраль 2021), обогнав такие модные языки как Go и Rust. Одна из причин его привлекательности – в простоте и максимальной близости к железу; с другой стороны, программирование на ассемблере всё ещё может рассматриваться как искусство и даёт совершенно особые эмоции.

Однако писать программы целиком и полностью на ассемблере — не просто долго, муторно и сложно — но ещё и несколько глупо — ведь высокоуровневые абстракции для того и были придуманы, чтобы сократить время разработки и упростить процесс программирования. Поэтому чаще всего на ассемблере пишут отдельно взятые хорошо оптимизированные функции, которые затем вызываются из языков более высокого уровня, таких как с++ и c#.

Исходя из этого, наиболее удобной средой для программирования будет Visual Studio, в состав которой уже входит MASM. Подключить его к проекту на с/c++ можно через контекстное меню проекта Build Dependencies – Build Customizations…, поставив галочку напротив masm, а сами программы на ассемблере будут располагаться в файлах с расширением .asm (в свойствах которого Item Type должно иметь значение Microsoft Macro Assembler). Это позволит не просто компилировать и вызывать программы на ассемблере без лишних телодвижений – но и осуществлять сквозную отладку, «проваливаясь» в ассемблерный исходник непосредственно из c++ или c# (в том числе и по точке останова внутри ассемблерного листинга), а также отслеживать состояния регистров наряду с обычными переменными в окне Watch.

Подсветка синтаксиса

B Visual Studio нет встроенной подсветки синтаксиса для ассемблера и прочих достижений современного IDE-строения; но её можно обеспечить с помощью сторонних расширений.

AsmHighlighter — исторически первый с минимальным функционалом и неполным набором команд — отсутсвуют не только AVX, но и некоторые из стандартных, в частности fsqrt. Именно этот факт побудил к написанию собственного расширения —

ASM Advanced Editor. В нём, помимо подсветки и сворачивания участков кода (с использованием комментариев «;[«, «;[+» и «;]») реализована привязка подсказок к регистрам, всплывающих по наведению курсора ниже по коду (также через комментарии). Выглядит это так:

;rdx=ссылка на текущий элемент входного массива
mov rcx, 8;=счётчик цикла

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

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

Asm Dude — обнаружился чуть позже. В нём автор пошёл другим путём и сфокусировал силы на встроенном справочнике команд и автодополнении, в том числе и с отслеживанием меток. Сворачивание кода там также присутствует (по «#region / #end region»), но привязки комментариев к регистрам вроде ещё нет.

32 vs. 64

С тех пор, как появилась 64-битная платформа, стало нормой писать по 2 варианта приложений. Пора завязывать с этим! Сколько можно тянуть легаси. Это же касается и расширений — найти процессор без SSE2 можно разве что в музее – к тому же, без SSE2 64-битные приложения и не заработают. Никакого удовольствия от программирования не будет, если писать по 4 варианта оптимизированных функций для каждой платформы. Только 64 бит/AVX, только хардкор! Хотя может быть и прямо противоположный взгляд — новые процессоры и так работают быстро, и оптимизацию стоит делать под старые. В общем, всё зависит от конкретной задачи.

Преимущество 64-битной платформе вовсе не в «широких» регистрах – а в том, что этих самых регистров стало в 2 раза больше – по 16 штук как общего назначения, так и XMM/YMM. Это не только упрощает программирование, но и позволяет значительно сократить обращения к памяти.

FPU

Если ранее без FPU было никуда, т.к. функции с вещественными числами оставляли результат на вершине стека, то на 64-битной платформе обмен проходит уже без его участия с использованием регистров xmm расширения SSE2. Intel в своих руководствах также активно рекомендует отказаться от FPU в пользу SSE2. Однако есть нюанс: FPU позволяет производить вычисления с 80-битной точностью — что в некоторых случаях может оказаться критически важным. Поэтому поддержка FPU никуда не делаcь, и рассматривать её как устаревшую технологию совершенно точно не стоит. Например, вычисление гипотенузы можно делать «в лоб» без опасения переполнения,

а именно

fld x fmul st(0), st(0) fld y fmul st(0), st(0) faddp st(1), st(0) fsqrt fstp hypot

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

Пример оптимизации: преобразование Хартли

Современные компиляторы с++ достаточно умны, чтобы автоматически векторизировать код на простых задачах типа суммирования чисел в массиве или поворота векторов, распознавая соответствующие паттерны в коде. Поэтому получить значительный прирост производительности на примитивных задачах не то что не получится — а наоборот, может оказаться, что ваша супер-оптимизированная программа работает медленнее того, что сгенерировал компилятор. Но и далеко идущие выводы из этого делать тоже не стоит — как только алгоритмы становятся чуточку сложнее и неочевиднее для оптимизации — всё волшебство оптимизирующих компиляторов пропадает. Получить десятикратный прирост производительности путём ручной оптимизации в 2021 году по-прежнему ещё возможно.

Итак, в качестве задачи возьмём алгоритм (медленного) преобразования Хартли:

static void ht_csharp(double[] data, double[] result) < int n = data.Length; double phi = 2.0 * Math.PI / n; for (int i = 0; i < n; ++i) < double sum = 0.0; for (int j = 0; j < n; ++j) < double w = phi * i * j; sum += data[j] * (Math.Cos(w) + Math.Sin(w)); >result[i] = sum / Math.Sqrt(n); > >

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

код (комментарии удалены)

ht_asm PROC local sqrtn:REAL10 local _2pin:REAL10 local k:DWORD local n:DWORD and r8, 0ffffffffh mov n, r8d mov r11, rcx xor rcx, rcx mov r9, r8 dec r9 shr r9, 1 mov r10, r8 sub r10, 2 shl r10, 3 finit fld _2pi fild n fdivp st(1), st fstp _2pin fld1 fild n fsqrt fdivp st(1), st ; mov rax, r11 mov rcx, r8 fldz @loop0: fadd QWORD PTR [rax] add rax, 8 loop @loop0 fmul st, st(1) fstp QWORD PTR [rdx] fstp sqrtn add rdx, 8 mov k, 1 @loop1: mov rax, r11 fld QWORD PTR [rax] fld st(0) add rax, 8 fld _2pin fild k fmulp st(1),st fsincos fld1;=u fldz;=v mov rcx, r8 dec rcx @loop2: fld st(1) fmul st(0),st(4) fld st(1) fmul st,st(4) faddp st(1),st fxch st(1) fmul st, st(4) fxch st(2) fmul st,st(3) fsubrp st(2),st fld st(0) fadd st, st(2) fmul QWORD PTR [rax] faddp st(5), st fld st(0) fsubr st, st(2) fmul QWORD PTR [rax] faddp st(6), st add rax, 8 loop @loop2 fcompp fcompp fld sqrtn fmul st(1), st fxch st(1) fstp QWORD PTR [rdx] fmulp st(1), st fstp QWORD PTR [rdx+r10] add rdx,8 sub r10, 16 inc k dec r9 jnz @loop1 test r10, r10 jnz @exit mov rax, r11 fldz mov rcx, r8 shr rcx, 1 @loop3:;[ fadd QWORD PTR [rax] fsub QWORD PTR [rax+8] add rax, 16 loop @loop3;] fld sqrtn fmulp st(1), st fstp QWORD PTR [rdx] @exit: ret ht_asm ENDP

Обратите внимание: тут нет ни разворачивания цикла, ни SSE/AVX, ни косинусных таблиц, ни снижения сложности за счёт «быстрого» алгоритма преобразования. Единственная явная оптимизация — это итеративное вычисление синуса/косинуса во внутреннем цикле алгоритма непосредственно в регистрах FPU.

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

Результаты авто-оптимизации программы на c++ также могут сильно зависеть от настроек параметров компилятора и выбора допустимого расширенного набора инструкций (SSE/AVX/etc). При этом есть два нюанса:

  1. Современные компиляторы склонны всё возможное вычислять на этапе компиляции – поэтому вполне возможно в откомпилированном коде вместо алгоритма увидеть заранее посчитанное значение, что при замере производительности даст преимущество компилятору в 100500 раз. Во избежание этого в моих замерах используется внешняя функция zero(), добавляющая неопределённости входным параметрам.
  2. Если компилятору указать «не использовать AVX» — это ещё не значит, что в полученном коде будет отсутствовать AVX. Внешние библиотеки сами проверяют доступный набор команд на текущей платформе и выбирают соответствующую реализацию. Поэтому единственно надёжный способ сравнения производительности в таком случае – испытывать код на платформе, где AVX отсутствует в принципе.

Итак, компилятор Visual Studio 2019, целевая платформа AVX2, Floating Point Model=Precise. Чтобы было ещё интереснее — будет измерять из проекта на c# на массиве из 10000 элементов:

C# ожидаемо оказался медленнее с++, а функция на ассемблере оказалась быстрее в 9 раз! Однако ещё рано радоваться — установим Floating Point Model=Fast:

Как видно, это помогло значительно ускорить код и отставание от ручной оптимизации составило всего лишь в 1.8 раз. Но вот что не изменилось – так это погрешность. Что тот, что другой вариант дал ошибку в 4 значащих цифры – а это немаловажно при математических вычислениях.

В данном случае наш вариант оказался и быстрее, и точнее. Но так бывает не всегда – и выбирая FPU для хранения результатов мы неизбежно будем терять в возможности оптимизации векторизацией. Также никто не запрещает комбинировать FPU и SSE2 в тех случаях, когда это имеет смысл (в частности, такой подход я использовал в реализации double-double арифметики, получив 10-кратное ускорение при умножении).

Дальнейшая оптимизация преобразования Хартли лежит уже в другой плоскости и (для произвольного размера) требует алгоритма Блюстейна, который также критичен к точности промежуточных вычислений. Ну а этот проект можно скачать на GitHub, и в качестве бонуса там также можно найти реализацию функций для суммирования/масштабирования массивов на FPU/SSE2/AVX.

Что почитать

Литературы по ассемблеру навалом. Но можно выделить несколько ключевых источников:
1. Официальная документация от Intel. Ничего лишнего, вероятность опечаток минимальна (кои в печатной литературе встречаются повсеместно).
2. Официальная документация от Microsoft.
3. Онлайн справочник, спарсенный из официальной документации.
4. Сайт Агнера Фога, признанного эксперта по оптимизации. Также содержит образцы оптимизированного кода на C++ с использованием интринсиков.
5. SIMPLY FPU.
6. 40 Basic Practices in Assembly Language Programming.
7. Все, что нужно знать, чтобы начать программировать для 64-разрядных версий Windows.

Appendix: Почему бы просто не использовать интринсики (Intrinsics)?

Скрытый текст

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

  • Не вся оптимизация делается векторизацией. Если во времена DOS оптимизация делалась за счёт экономии тактов и количества обращений к памяти, то сейчас основной инструмент оптимизации – это организация оптимальной работы с памятью во избежание промахов кеша.
  • Интринсики к новым инструкциям появляются с некоторым запаздыванием. Недостающие интринсики нельзя добавить простым включением заголовочного файла – их поддержка должна быть реализована на уровне компилятора.
  • Не на все инструкции возможно сделать интринсики. Когда оптимизация касается точности математических выражений, можно добиться значительных улучшений, программируя непосредственно на математическом сопроцессоре (FPU). Для команд сопроцессора же интринсики отсутствуют. Они также отсутствуют для команд, на результат которых влияют флаги переноса/переполнения/etc.
  • Интринсики не представляют из себя какой-либо высокоуровневый фреймворк – по факту, это не более чем лишь ещё один уровень мнемоник над ассемблерными инструкциями, мало чем отличающийся от ассемблерных вставок. Что автоматически означает, что код вовсе не становится более читаемым, а при его написании так или иначе нужно придерживаться ассемблерного стиля мышления.
  • Также, из C++ кода вовсе не очевидно, что существуют какие-то ограничения на количество одновременно используемых SIMD-регистров. В 32-х битном ассемблере вы не можете использовать XMM8 наравне с XMM0 / XMM7 – код просто не откомпилируется. А интринсиками вы можете определить хоть тысячу одновременно используемых регистров — и компилятор вынужден будет сам решать, что хранить в регистрах, что в памяти, и как между собой их оптимально комбинировать. В таком случае применение интринсиков не даёт никаких преимуществ в плане увеличения производительности – компилятор работает с ними так же, как и с обычными структурами на C++.
  • Программировать на ассемблере не так уж и сложно, особенно если не пытаться делать на нём хитрые высокоуровневые конструкции. Многое можно почерпнуть, изучая ассемблерный листинг простых алгоритмов в режиме отладки и с различными уровнями оптимизации – компилятор от Microsoft производит достаточно лёгкий для понимания и в то же время эффективный код, комментируя его исходным кодом на C++.
  • Программирование
  • Assembler

На каком языке написан Assembler? И на каком C/C++?

Вопрос, возможно, глупый, но я, как программист, дилетант. Программировал на QBasic, VB и немного Borland Delphi.

Лучший ответ

ни на каком. язык он и есть язык.

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

nameМыслитель (5654) 14 лет назад

Я тут ответы почитал и вроде, понял. Значит, язык программирования — это 2 вещи (в основном) — текстовый редактор и компиллятор. В текстовом редакторе я пишу текст программы на определённом языке, а компилятор, понимая синтаксис этого языка, переводит весь написанный мною текст в двоичную систему (типа «110001001110100011010. «). И язык программирования — это сам компилятор, я правильно понял?

Антон Катцын Гуру (4935) Да, в общем вы правильно поняли. Просто под понятием язык программирования понимается лишь набор правил языка (синтаксис, семантика и т.д.), а вот реализация языка программирования — это программа компилятор, которая преобразует текст в двоичный код. Именно поэтому вопрос «на каком языке написан тот или иной язык» некорректен.

Остальные ответы
Ассемблер и C\C++ и есть языки. Это на них пишут
Букавки аглицкие))).. . Вся суть в компиляторе — как он эти бУкавки и циферки понимает))

ассемблер — машинные коды, они написаны на Булейных кодах, двоичной алгебре и шестиричной системе исчесления

Виталий ОлеговичМастер (2170) 14 лет назад
Тру ответ, ты ему теперь обьясни чё такое Булейные коды!))))
nameМыслитель (5654) 14 лет назад

Или это компилятор создают, чтобы создать язык программирования?
Я тут ответы почитал и вроде, понял. Значит, язык программирования — это 2 вещи (в основном) — текстовый редактор и компиллетор. В текстовом редакторе я пишу текст программы на определённом языке, а компилятор, понимая синтаксис этого языка, переводит весь написанный мною текст в двоичную систему (типа «110001001110100011010. «). И язык программирования — это сам компилятор, я правильно понял?

Голый Мужик Мыслитель (9628) Как правило, компьютерный язык — упрощённый аналог языка естественного. Компиляторы хоть и играют роль, но не столь существенную. Русский язык существует вне зависимости от того, есть ли рядом с вами кто-нибудь, кто может ему внемлить. Вы можете передавать информацию на нём как вам угодно: текст, речь, азбука Морзе, жесты глухонемых — всё это реализация выражения мысли на русском языке, но не сам язык и не сама мысль. Аналогично, язык программирования — способ выражения мысли в формальных терминах для машины, реализация в этом контексте вообще не рассматривается. Некоторые языки высокого уровня, например, реализуются аппаратно, для них не нужен компилятор (точнее, нужен только парсер). Существуют и нетекстовые компьютерные языки (скажем, язык проектирования UML, описывающий архитектуру и поведение системы в виде набора диаграмм), реализацией для которых может служить клочок туалетной бумаги, изначально взятый из макдональдса как средство для протирки ботинка от собачьей какашки.

assembler написан машинными командами, бе зо всяких языков. а с++ можно и на assembler-е написать

Компиляторы могут быть написаны абсолютно на любых языках. Тот же ассемблер может быть написан на С++ (MASM, например, именно на плюсах и писан) . Однако компиляторы языков высокого уровня, как правило, бутстрапятся, то есть пишутся на том же самом языке. Intel C++ написан на Intel C++, Java написана на Java, C# написан на C# и так далее. Это, как бы, признак состоятельности компилятора как инструмента для описания сложных систем.

На машинных кодах, наверное самые первые версии компилятора ассемблер кода были вручную выбиты на перфокартах

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *