Что значит для процессора поддерживать стек?


11

Как процессор может не поддерживать стек? Разве любая архитектура, использующая подпрограммы (я уверен, что это все архитектуры), не должна помещать адрес возврата в стек, чтобы он мог вернуться туда, откуда он вызвал подпрограмму? Стек означает только часть памяти с указателем, которая растет в определенном направлении и действует как структура данных стека. Нет? Я просто не понимаю, как архитектура не может поддерживать стек.

В какой степени автоматическое хранение в памяти (автоматические переменные и статические переменные) определяется компилятором в сравнении с аппаратной архитектурой?

Ответы:


8

Есть много низкоуровневых микроконтроллеров, которые имеют аппаратные стеки для подпрограммного вызова / возврата и обработки прерываний, но затрудняют, если не делают невозможным хранение данных (переменных) там, и реализация чисто программного стека данных будет ужасно неэффективной. 8051 является одним классическим примером, а PIC низкого уровня (PIC12 / PIC16) - другим. На этих машинах стек данных эмулируется путем назначения статических мест хранения для автоматических переменных, причем количество повторного использования этих мест зависит от сложности компилятора.

Обратите внимание, что если эмуляция стека выполняется таким образом, это означает, что рекурсия - функция, которая вызывает себя, прямо или косвенно - не работает, поскольку каждый экземпляр функции повторно использует одни и те же статические местоположения для своих якобы «частных» переменных. Некоторые компиляторы допускают ограниченное использование рекурсии (обычно реализуемой с помощью #pragmaнекоторого вида), что приведет к созданию истинного стека данных независимо от того, насколько он замедляет работу.

Кроме того, существуют архитектуры ЦП, которые вообще не имеют аппаратного стека, даже для подпрограмм / обработки прерываний, включая DEC PDP-8 и IBM System / 360. На этих машинах ПК (обратный адрес) и регистр состояния (для прерываний) были сохранены в регистрах или ячейках памяти, но в каждом случае, который я могу себе представить, машина также имела достаточно гибкие режимы адресации, которые позволяли легко создавать стек с программным обеспечением.


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

4

«поддержка стека» означает

  1. имеющий явный регистр указателя стека, и
  2. наличие примитивных инструкций машинного кода для манипулирования / использования регистра указателя стека (например, reti, который изменяет программный счетчик на основе указателя стека для возврата из вызова функции).

Вы можете эмулировать это без поддержки аппаратного обеспечения через эмуляцию, то есть код, сгенерированный компилятором, и такие же вещи в ОЗУ с использованием переменных. Редко / редко встречается отсутствие прямой поддержки стека в любой современной компьютерной архитектуре.

Семантика переменных в языках программирования почти не имеет ничего общего с целевой аппаратной архитектурой, для любого языка выше, чем прямая сборка. Работа компиляторов заключается в создании машинного кода, который соответствует семантическому контракту языка программирования.


1
Большинство ISA RISC (например, MIPS [исключая MIPS16 и microMIPS], Alpha, SPARC, PA-RISC, Power, SuperH) не имеют явного регистра указателя стека, определяющего его в ABI. ARM является исключением (частично потому, что он скрывает SP для нескольких режимов работы), как и MIP16 и microMIPS (для плотности кода).
Пол А. Клейтон,

2

Некоторые архитектуры (например, PIC) имеют аппаратный стек, который ограничен в возможностях (может использоваться только для адресов возврата, а не переменных). Некоторые очень маленькие архитектуры не имеют инструкции сохранения и приращения или PUSH, так что стек сложнее.

Переменные 'auto' в C всегда должны компилироваться во что-то с поведением инициализации 'auto', а 'static' со статическим поведением; на некоторых архитектурах вы не можете делать рекурсию, и в этом случае компилятор может статически распределить все переменные.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.