Это перевод одной из статей Lin Clark. Если вы не читали остальные, мы рекомендуем начать с начала.
Чтобы понять, как работает WebAssembly, неплохо понимать, что такое код на ассемблере и как компиляторы его генерируют. В статье о JIT я сравнивала взаимодействие с компьютером со взаимодействием с инопланетянином.
![](https://habrastorage.org/r/w1560/webt/tl/ya/kj/tlyakj2ri2tvkudltu7gyk8cqva.png)
Я хочу рассмотреть работу инопланетного мозга — как мозг компьютера анализирует и понимает сообщения, которые ему поступают. Часть мозга предназначена для мышления, например, сложения, вычитания или логических операций. Есть область, отвечающая за кратковременную память и другая — отвечающая за долговременную.
Все они имеют названия.
![](https://habrastorage.org/r/w1560/webt/y6/rm/ea/y6rmeamnfn8qcpi-0-qriokvubw.png)
Предложения на машинном коде называются инструкциями.
Что происходит, когда такая инструкция попадает в мозг? Она разделяется на несколько частей с различным значением. Разделение инструкций зависит от устройства мозга. К примеру, мозг на картинке может принять первые 6 и провести их в арифметико-логический блок (ALU). На основе нулей и единиц ALU определяет, что ему нужно соединить эти части.
Этот чанк называется «опкод» (opcode, operation code), потому что он сообщает ALU, какую операцию произвести.
![](https://habrastorage.org/r/w1560/webt/ay/b3/ea/ayb3eais4x66agvp6vmrtqzij40.png)
После этого мозг возьмет следующие 2 чанка по 3 бита каждый, чтобы определить, какие 2 числа нужно добавить. Это будут адреса регистров.
![](https://habrastorage.org/r/w1560/webt/8b/ri/mg/8brimgxfp4ajuhg0qi7suiyweuy.png)
Обратите внимание на пояснения над кодом, которые помогут нам, людям, понять, что здесь происходит. Вот что такое ассемблер. Его называют символьным машинным кодом. Это способ для людей понять машинный код.
Между ассемблером и машинным кодом существует прямая связь. Из-за этого для разных типов машинных архитектур существуют разные типы ассемблеров. При столкновении с новой архитектурой, вам, скорее всего, потребуется новый диалект ассемблера.
Получается, что у нас не один объект для перевода. Существует не один язык, называемый машинным кодом, а множество разных типов машинного кода. Также как и люди, машины говорят на разных языках.
Переводя с человеческого на инопланетный, вы переходите с английского, русского или китайского на инопланетный язык А или инопланетный язык Б. В терминологии программирования — это как переходить с C, или C++, или Rust на x86 или ARM.
Допустим, вы хотите иметь возможность переводить любой из этих высокоуровневых языков программирования на любой из видов ассемблера (который подходит разным архитектурам). Один из способов это сделать — создать множество переводчиков, которые смогут переводить с любого языка на любой ассемблер.
![](https://habrastorage.org/r/w1560/webt/qz/uj/i8/qzuji8fln5n4zecw_e7m5q7sdgw.png)
Это будет довольно неэффективно. Для решения этой проблемы большинство компиляторов добавляют к процессу еще один этап. Высокоуровневый язык программирования преобразуется в более простой, но всё еще не работающий на уровне машинного кода. Это называется промежуточным представлением ( intermediate representation IR).
![](https://habrastorage.org/r/w1560/webt/la/du/uf/laduufh__3w40f7ge2dg7vfn7jm.png)
Это означает, что компилятор может взять любой из языков программирования высокого уровня и перевести его на IR-язык. После этого другая часть компилятора может взять IR-язык и скомпилировать из него что-то подходящее для целевой архитектуры.
Фронтенд компилятора переводит высокоуровневый язык программирования в промежуточное представление. А бэкенд — промежуточное представление в ассемблер для целевой архитектуры.
![](https://habrastorage.org/r/w1560/webt/ij/sm/bb/ijsmbb8rlhqphxzpd6giexe9-p8.png)
Вот что такое ассемблер, и вот как компиляторы переводят высокоуровневые языки программирования в ассемблеры. В следующей статье мы увидим, как это связано с WebAssembly.
Чтобы понять, как работает WebAssembly, неплохо понимать, что такое код на ассемблере и как компиляторы его генерируют. В статье о JIT я сравнивала взаимодействие с компьютером со взаимодействием с инопланетянином.
![](https://habrastorage.org/webt/tl/ya/kj/tlyakj2ri2tvkudltu7gyk8cqva.png)
Я хочу рассмотреть работу инопланетного мозга — как мозг компьютера анализирует и понимает сообщения, которые ему поступают. Часть мозга предназначена для мышления, например, сложения, вычитания или логических операций. Есть область, отвечающая за кратковременную память и другая — отвечающая за долговременную.
Все они имеют названия.
- Область мышления — это арифметико-логический блок (ALU).
- Кратковременная память обеспечивается регистрами.
- Долговременная память — это оперативная память (RAM).
![](https://habrastorage.org/webt/y6/rm/ea/y6rmeamnfn8qcpi-0-qriokvubw.png)
Предложения на машинном коде называются инструкциями.
Что происходит, когда такая инструкция попадает в мозг? Она разделяется на несколько частей с различным значением. Разделение инструкций зависит от устройства мозга. К примеру, мозг на картинке может принять первые 6 и провести их в арифметико-логический блок (ALU). На основе нулей и единиц ALU определяет, что ему нужно соединить эти части.
Этот чанк называется «опкод» (opcode, operation code), потому что он сообщает ALU, какую операцию произвести.
![](https://habrastorage.org/webt/ay/b3/ea/ayb3eais4x66agvp6vmrtqzij40.png)
После этого мозг возьмет следующие 2 чанка по 3 бита каждый, чтобы определить, какие 2 числа нужно добавить. Это будут адреса регистров.
![](https://habrastorage.org/webt/8b/ri/mg/8brimgxfp4ajuhg0qi7suiyweuy.png)
Обратите внимание на пояснения над кодом, которые помогут нам, людям, понять, что здесь происходит. Вот что такое ассемблер. Его называют символьным машинным кодом. Это способ для людей понять машинный код.
Между ассемблером и машинным кодом существует прямая связь. Из-за этого для разных типов машинных архитектур существуют разные типы ассемблеров. При столкновении с новой архитектурой, вам, скорее всего, потребуется новый диалект ассемблера.
Получается, что у нас не один объект для перевода. Существует не один язык, называемый машинным кодом, а множество разных типов машинного кода. Также как и люди, машины говорят на разных языках.
Переводя с человеческого на инопланетный, вы переходите с английского, русского или китайского на инопланетный язык А или инопланетный язык Б. В терминологии программирования — это как переходить с C, или C++, или Rust на x86 или ARM.
Допустим, вы хотите иметь возможность переводить любой из этих высокоуровневых языков программирования на любой из видов ассемблера (который подходит разным архитектурам). Один из способов это сделать — создать множество переводчиков, которые смогут переводить с любого языка на любой ассемблер.
![](https://habrastorage.org/webt/qz/uj/i8/qzuji8fln5n4zecw_e7m5q7sdgw.png)
Это будет довольно неэффективно. Для решения этой проблемы большинство компиляторов добавляют к процессу еще один этап. Высокоуровневый язык программирования преобразуется в более простой, но всё еще не работающий на уровне машинного кода. Это называется промежуточным представлением ( intermediate representation IR).
![](https://habrastorage.org/webt/la/du/uf/laduufh__3w40f7ge2dg7vfn7jm.png)
Это означает, что компилятор может взять любой из языков программирования высокого уровня и перевести его на IR-язык. После этого другая часть компилятора может взять IR-язык и скомпилировать из него что-то подходящее для целевой архитектуры.
Фронтенд компилятора переводит высокоуровневый язык программирования в промежуточное представление. А бэкенд — промежуточное представление в ассемблер для целевой архитектуры.
![](https://habrastorage.org/webt/ij/sm/bb/ijsmbb8rlhqphxzpd6giexe9-p8.png)
Вывод
Вот что такое ассемблер, и вот как компиляторы переводят высокоуровневые языки программирования в ассемблеры. В следующей статье мы увидим, как это связано с WebAssembly.