스택을 사용하면 유한 한 수의 레지스터에 의해 부과 된 한계를 우아하게 우회 할 수 있습니다.
정확히 26 개의 전역이 "z를 등록"한다고 생각한다고 상상해보십시오 (또는 8080 칩의 7 바이트 크기 레지스터 만 포함).이 앱에서 작성하는 모든 기능은이 플랫리스트를 공유합니다.
순진한 시작은 첫 번째 몇 개의 레지스터를 첫 번째 함수에 할당하는 것입니다. 두 번째 함수의 경우 "d"로 시작하여 3 개만 걸린다는 것을 알고 있습니다.
대신, 튜링 머신과 같은 은유 적 테이프를 사용하는 경우, 사용하는 모든 변수를 테이프 에 저장 하고 전달 하여 () 테이프를 사용하여 각 함수가 "다른 함수 호출"을 시작하도록 할 수 있습니다. 원하는대로 등록합니다. 수신자가 완료되면 필요에 따라 수신자의 출력을 잡아야 할 위치를 알고있는 부모 기능으로 제어를 리턴 한 다음 테이프를 뒤로 재생하여 상태를 복원합니다.
기본 호출 프레임은 바로 그 것이며 컴파일러가 한 함수에서 다른 함수로 전환하는 표준화 된 기계 코드 시퀀스에 의해 생성 및 삭제됩니다. (C 스택 프레임을 기억해야한지 오래되었지만 X86_calling_conventions 에서 누가 무엇을 떨어 뜨릴 지에 대한 의무를 다양한 방법으로 읽을 수 있습니다 .)
(재귀는 훌륭하지만 스택없이 레지스터를 저글링해야한다면 스택에 정말로 감사 할 것 입니다.)
프로그램을 저장하고 컴파일을 지원하는 데 필요한 하드 디스크 공간과 RAM이 증가했기 때문에 콜 스택을 사용하는 이유라고 생각합니다. 그 맞습니까?
요즘 더 많이 인라인 할 수는 있지만 ( "더 빠른 속도"는 항상 좋습니다. "더 적은 kb의 어셈블리"는 비디오 스트림의 세계에서는 거의 의미가 없습니다.) 주요 제한 사항은 특정 유형의 코드 패턴에서 평탄화하는 컴파일러의 능력에 있습니다.
예를 들어, 다형성 객체-처리 할 객체의 유일한 유형을 모르면 평평 할 수 없습니다. 객체의 기능 테이블을보고 그 포인터를 호출해야합니다 ... 런타임에하는 것은 쉽지만 컴파일 타임에는 인라인 할 수 없습니다.
최신 툴체인은 호출자가 충분히 펑크하면 obj가 어떤 풍미 인지 정확히 알 수 있을 때 다형성으로 정의 된 함수를 행복하게 인라인 할 수 있습니다 .
class Base {
public: void act() = 0;
};
class Child1: public Base {
public: void act() {};
};
void ActOn(Base* something) {
something->act();
}
void InlineMe() {
Child1 thingamabob;
ActOn(&thingamabob);
}
위의 컴파일러는 InlineMe에서 act () 내부의 모든 것을 통해 정적으로 인라인을 유지하거나 런타임에 vtable을 만질 필요가 없도록 선택할 수 있습니다.
그러나 동일한 기능의 다른 호출 이 인라인되어 있어도 객체의 풍미에 대한 불확실성으로 인해 개별 함수에 대한 호출로 남을 수 있습니다.