Нам часто говорят, что аппаратному обеспечению не важно, на каком языке написана программа, поскольку оно видит только скомпилированный двоичный код, однако это не вся правда. Например, рассмотрим скромный Z80; его расширения к набору команд 8080 включают в себя такие инструкции, как CPIR, которые полезны для сканирования строк в стиле C (с нулевым символом в конце), например, для выполнения strlen()
. Разработчики, должно быть, определили, что запуск программ на C (в отличие от Pascal, где длина строки находится в заголовке) - это то, для чего их дизайн, вероятно, будет использоваться. Другой классический пример - машина Лиспа .
Какие еще примеры есть? Например, инструкции, количество и тип регистров , режимы адресации, которые делают определенный процессор предпочтительным для соглашений конкретного языка? Я особенно заинтересован в пересмотрах той же семьи.
sizeof(int)
равно 1, должна требовать, чтобы этот типchar
был подписан (поскольку онint
должен содержать все значения типаchar
). Я написал код для машины, гдеchar
иint
16-разрядные целые числа со знаком; самые большие трудности заключаются в том, что нельзя использовать объединения для преобразования типов, а эффективное хранение большого количества байтов требует ручной упаковки и распаковки. Эти проблемы незначительны по сравнению с тем, что в C возможно, что sizeof (int) == sizeof (long), так как ...unsigned int
значениями. C99 улучшил эту ситуацию, но до C99 не было гарантированного безопасного одношагового способа сравнения потенциально отрицательного значения со значением типаunsigned int
(перед сравнением нужно было проверить, было ли число отрицательным).Ответы:
Существующие ответы сосредоточены на изменениях ISA . Есть и другие аппаратные изменения. Например, C ++ обычно использует виртуальные таблицы для виртуальных вызовов. Начиная с Pentium M , в Intel появился компонент «косвенный предсказатель ветвления», который ускоряет вызовы виртуальных функций.
источник
Набор команд Intel 8086 включает в себя вариант «ret», который добавляет значение к указателю стека после получения адреса возврата. Это полезно для многих реализаций Pascal, когда вызывающая функция помещает аргументы в стек перед выполнением вызова функции и выводит их позже. Если подпрограмма будет принимать, например, четыре байта параметров, она может закончиться «RET 0004» для очистки стека. В отсутствие такой инструкции такое соглашение о вызовах, вероятно, потребовало бы, чтобы код вставлял адрес возврата в регистр, обновлял указатель стека и затем переходил в этот регистр.
Интересно, что большинство кода (включая подпрограммы ОС) на исходном Macintosh использовали соглашение о вызовах Pascal, несмотря на отсутствие упрощающей инструкции в 68000. Использование этого соглашения о вызовах позволило сэкономить 2-4 байта кода на типичном сайте вызовов, но потребовало дополнительного 4-6 байт кода на сайте возврата каждой функции, которая принимала параметры.
источник
ENTER
аналог этогоRET n
...ENTER
существовал в оригинальном 8086; это пришло с более поздними процессорами. Тем не менее, это поднимает интересный момент: режимы адресации на основе BP четко разработаны с использованием стековых параметров и локальных объектов, доступ к которым осуществляется через указатель кадра. Я нахожу это соглашение интересным по ряду причин, особенно учитывая, что (1) код на чистом ассемблере более склонен использовать значения в регистрах, чем в стеке, но (2) преимущества адресации [BP + nn] перед [SP +] nn] адресация болееОдним из примеров является MIPS, который имеет как
add
иaddu
для перехвата и игнорирования переполнения соответственно. (Такжеsub
иsubu
.) Требовался первый тип инструкций для языков, таких как Ada (я думаю, я никогда не использовал Ada), которые явно имеют дело с переполнениями, и второй тип для языков, подобных C, которые игнорируют переполнения.Если я правильно помню, фактический процессор имеет некоторые дополнительные схемы в ALU для отслеживания переполнений. Если бы единственный язык, который заботился о людях, был C, это бы не нуждалось в этом.
источник
nmemb*size+offset
байты и вам нужно убедиться, что вы не получите переполнение.addu
иsubu
инструкции (те , которые не проверяют для перелива) были те , которые были добавлены , чтобы сделать C счастливым. Конечно, я действительно не знаю - мы только смутно освещали это в лекции, и я, конечно, не специалист по архитектуре: P.Серия Burroughs 5000 была разработана для эффективной поддержки ALGOL, а Intel iAPX-432 была разработана для эффективной работы Ada. У Inmos Transputer был свой собственный язык, Оккам. Я думаю, что процессор Parallax "Propeller" был разработан для программирования с использованием своего собственного варианта BASIC.
Это не язык, но набор инструкций VAX-11 содержит одну инструкцию для загрузки контекста процесса, которая была разработана по запросу команды разработчиков VMS. Я не помню деталей, но ISTR потребовалось так много инструкций, чтобы реализовать серьезный верхний предел количества процессов, которые они могли запланировать.
источник
Похоже, что до сих пор никто не упомянул о том, что успехи в оптимизации компилятора (где базовый язык в значительной степени не имеет значения) привели к переходу от наборов команд CISC (которые были в значительной степени разработаны для кодирования людьми) к наборам команд RISC (которые в основном были предназначен для кодирования компиляторами.)
источник
Семейство Motorola 68000 представило несколько режимов автоинкремента, которые сделали копирование данных через процессор очень эффективным и компактным.
[Обновленный пример]
это был некоторый код C ++, который повлиял на ассемблер 68000
реализован в обычном ассемблере (псевдокод, я забыл 68000 команд ассемблера)
с новым адресным режимом это стало чем-то похожим на
только две инструкции в цикле вместо 4.
источник
Мэйнфрейм IBM серии Z является потомком IBM 360 1960-х годов.
Там было несколько инструкций, специально предназначенных для ускорения программ на COBOL и Fortran. Классическим примером является
BXLE
«Ветвь по индексу с низким или равным», которая представляет собой большую частьfor
цикла Фортрана или COBOL,PERFORM VARYING x from 1 by 1 until x > n
инкапсулированных в одну инструкцию.Существует также целое семейство упакованных десятичных инструкций для поддержки десятичной арифметики с фиксированной запятой, распространенной в программах на языке COBOL.
источник
DO
петлю Фортрана .Ранние процессоры Intel имели следующие функции, многие из которых теперь устарели в 64-битном режиме:
Флаг знака, найденный в регистре состояния многих процессоров, существует для простой выполнения арифметики со знаком и без знака.
Набор инструкций SSE 4.1 представляет инструкции для обработки строк, как с нулевым, так и с нулевым окончанием (PCMPESTR и т. Д.)
Кроме того, я мог бы представить, что ряд функций системного уровня был разработан для обеспечения безопасности скомпилированного кода (проверка предела сегмента, шлюзы вызовов с копированием параметров и т. Д.)
источник
Некоторые процессоры ARM, в основном мобильные, включают в себя (d) расширение Jazelle, которое является аппаратным интерпретатором JVM; он интерпретирует байт-код Java напрямую. JVM, поддерживающая Jazelle, может использовать аппаратное обеспечение для ускорения выполнения и устранения большей части JIT, но резервирование виртуальной машины программного обеспечения все еще гарантируется, если байт-код не может быть интерпретирован на кристалле.
Процессоры с таким модулем включают в себя инструкцию BXJ, которая переводит процессор в специальный «режим Jazelle», или, если активация модуля не удалась, она просто интерпретируется как обычная команда перехода. Устройство повторно использует регистры ARM для хранения состояния JVM.
Преемником технологии Jazelle является ThumbEE
источник
Насколько я знаю, это было более распространенным в прошлом.
Есть сеанс вопросов, на котором Джеймс Гослинг сказал, что были люди, пытающиеся сделать аппаратное обеспечение, которое могло бы лучше справляться с байт-кодом JVM, но затем эти люди нашли бы способ сделать это с помощью обычного «универсального» intel x86 (возможно, компиляции байт-код каким-то умным способом).
Он упомянул, что есть преимущество в использовании универсального популярного чипа (такого как Intel), потому что у него есть крупная корпорация, которая тратит огромные суммы денег на продукт.
Видео стоит проверить. Он говорит об этом на 19 или 20 минуте.
источник
Я сделал быстрый поиск по страницам, и кажется, что никто не упомянул процессоры, разработанные специально для выполнения Forth . Язык программирования Forth основан на стеке, компактен и используется в системах управления.
источник
Процессор Intel iAPX был специально разработан для ОО-языков. Не совсем получилось, хотя.
источник
У 68000 был MOVEM, который больше всего подходил для помещения нескольких регистров в стек в одной инструкции, чего и ожидали многие языки.
Если вы видели MOVEM (MOVE Multiple), предшествующий JSR (Jump SubRoutine) по всему коду, то вы, как правило, знали, что имеете дело с C-совместимым кодом.
MOVEM допускает автоматическое увеличение регистра назначения, позволяя при каждом использовании продолжать наложение на место назначения или удаление из стека в случае автоматического уменьшения значения.
http://68k.hax.com/MOVEM
источник
Архитектура Atmel AVR полностью разработана с нуля для того, чтобы она подходила для программирования на C. Например, эта заметка по применению уточняется далее.
IMO, это тесно связано с отличным ответом rockets4kids: ранние PIC16 разрабатывались для прямого программирования на ассемблере (всего 40 инструкций), а более поздние семейства нацелены на C.
источник
Когда был разработан числовой сопроцессор 8087, для языков было довольно распространенным делом выполнять всю математику с плавающей запятой, используя тип с наивысшей точностью, и округлять результат только до более низкой точности при назначении его переменной с более низкой точностью. В исходном стандарте C, например, последовательность:
будет способствовать
a
иb
кdouble
, добавить их, поощрятьc
кdouble
, добавьте его, а затем сохранить результат округляется доfloat
. Хотя во многих случаях компилятору было бы быстрее генерировать код, который выполнял бы операции непосредственно над типомfloat
, было проще иметь набор подпрограмм с плавающей запятой, которые будут работать только над типомdouble
, вместе с подпрограммами для преобразования в / отfloat
, чем иметь отдельные наборы подпрограмм для обработки операцийfloat
иdouble
. 8087 был разработан вокруг этого подхода к арифметике, выполняя все арифметические операции с использованием 80-битного типа с плавающей запятой [80 битов, вероятно, было выбрано, потому что:На многих 16- и 32-разрядных процессорах быстрее работать с 64-разрядной мантиссой и отдельным показателем степени, чем со значением, которое делит байт между мантиссой и показателем степени.
Очень трудно выполнять вычисления, которые являются точными с полной точностью используемых числовых типов; например, если кто-то пытается вычислить что-то вроде log10 (x), проще и быстрее вычислить результат с точностью до 100 муль для 80-битного типа, чем для вычисления результата с точностью до 1 муль от 64-битного тип и округление первого результата до 64-битной точности даст 64-битное значение, которое является более точным, чем второе.
К сожалению, будущие версии языка изменили семантику того, как должны работать типы с плавающей точкой; в то время как семантика 8087 была бы очень полезной, если бы языки поддерживали их последовательно, если бы функции f1 (), f2 () и т. д. возвращали тип
float
, многие авторы компилятора самиlong double
взялись бы за создание псевдонима для 64-битного двойного типа а не 80-битный тип компилятора (и не предоставляют никаких других средств для создания 80-битных переменных), и произвольно оценивать что-то вроде:любым из следующих способов:
Обратите внимание, что если f3 и f4 возвращают те же значения, что и f1 и f2 соответственно, исходное выражение должно явно возвращать ноль, но многие из последних выражений могут и не быть. Это привело к тому, что люди осудили «дополнительную точность» 8087, хотя последняя формулировка обычно превосходила бы третью и - с кодом, соответствующим образом использующим расширенный тип double, - редко бы уступала.
За прошедшие годы Intel отреагировала на тенденцию языка (ИМХО) к тому, чтобы заставить промежуточные результаты округляться до точности операндов, проектируя свои более поздние процессоры, чтобы способствовать такому поведению, в ущерб коду, который выиграл бы от использования более высоких точность промежуточных расчетов.
источник
## How the stack changed the processor
и## How floating point changed the processor
), чтобы люди могли получить правильное мышление при чтении и с меньшей вероятностью считают, что вы либо не обращали внимания на ответы или репосты. такие же (похожие) ответы.