Нужна ли основной процедуре в программе сборки стековый фрейм? - PullRequest
0 голосов
/ 17 июня 2019

Если основная процедура имеет локальные переменные и изменяет указатель стека, следует ли вам создавать кадр стека, как в обычной процедуре?

Ответы [ 2 ]

2 голосов
/ 17 июня 2019

Нужна ли основной процедуре в программе сборки стековый фрейм?

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

В нижней части этой башни находятся машинные коды - числа, где аппаратные средства (ЦП) реагируют определенным образом на разные числа.На этом уровне нет процедур и нет стека;только инструкции (например, call), которые могут или не могут использоваться для реализации процедур и инструкций (например, push, pop), которые могут или не могут использоваться для реализации стека.

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

Следующий уровень - это набор соглашений, которые обычно похищаются из реализацииязык более высокого уровня.Это процедуры / функции, стек, соглашения о вызовах и т. Д. Конечно, это может быть совершенно разным для разных языков и разных реализаций одного и того же языка;и (по крайней мере, в теории - например, язык, разработанный для «стиля передачи продолжения» и ничего более), может все еще не включать такие вещи, как процедуры и (по крайней мере, в теории - например, может быть, функциональный язык программирования с компилятором, предназначенным для преобразования всего кода всправочные таблицы) могут не включать в себя стек, и если имеется стек, на самом деле это может быть два (или более?) стека (например, один стек для потока управления и другой стек для данных для целей обеспечения безопасности / потока управления).

Следующий уровень - куча соглашений для отладки.Вот откуда появились указатели фреймов (от желания добавить отладку до реализаций старых компиляторов Си).Конечно, для более современных систем отладчики перешли на «менее глупые» подходы (смещение информационных отладчиков нужно из машинного кода, где это проблема производительности / оптимизации, и в специальные таблицы - например, «Таблица информации о кадре вызова» для DWARF).

По существу;для самой сборки не может быть ни процедур, ни стека, ни указателя кадра;но если программист на ассемблере пытается написать код, который соответствует «соглашениям об окружающей среде», он, вероятно, будет использовать процедуры и может использовать указатели фреймов.

Например, вот некоторая «псевдосборка» для простого калькулятора:

start:
    mov r7,doNextOperator        ;r7 = address "get number" code should jump to
    jmp getNumber

doNextOperator:
    mov r0,r1                    ;r0 = accumulator = result
    out diplay,r0                ;Display the current accumulator
    in r2, nextChar              ;r2 = next operator from user
    mov r7,[operatorTable+r2*4]  ;r7 = address "get number" code should jump to
    jmp getNumber

operatorTable:
    dd doAddition
    dd doSubtraction
    dd doMultiplication
    dd doDivision


;Do addition
;========================
;Input
; r0    Accumulator
; r1    Number to add
;
;Output
; r1    Result

doAddition:
   add r1,r0
   jmp doNextOperator

;Do subtraction
;========================
;Input
; r0    Accumulator
; r1    Number to add
;
;Output
; r1    Result

doAddition:
   sub r1,r0
   jmp doNextOperator


;Get a number from the user
;========================
;Input
; r7    Address to jump to when finished
;
;Output
; r1    Number entered by the user 

getNumber:
    mov r1,0
    in r2, nextChar
    sub r2,'0'
    jc .done
.next:
    mul r1,10
    add r1,r2
    in r2, nextChar
    sub r2,'0'
    jnc .next
.done:
    jmp r7
1 голос
/ 17 июня 2019

Простой ответ: это зависит

Ответ оптимальной практики: вероятно

Ленивый ответ: если он не падает, это достаточно хорошо.(/ сарказм)

Подробный ответ:

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

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

Итак, на самом деле вам не нужен кадр стека.Вам даже не нужен стековый фрейм, если вы намереваетесь действительно вернуться из своей функции, если указатель стека такой же, как и при вводе.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...