2017-05-17 9 views
2

Forth에는 스택과 리턴 스택이 있습니다.하나의 스택으로 Forth와 유사한 언어를 구현할 수 있습니까?

내가 아는 한, 리턴 스택의 포인트는 프로그램 카운터의 이전 값을 저장하는 것이다.

C 프로그램은 프로그램 카운터의 이전 값을 스택에 넣고 반환 스택을 사용하지 않습니다.

Forth는 결과 스택에 결과를 반환하기 때문에 return-stack 만 필요하므로 프로그램 카운터의 이전 값을 묻을 수 있습니까?

+1

필자는 전문가는 아니지만 C에서 매개 변수의 크기 (반환 주소로 "가져 오기"위해 필요한 데이터)가 컴파일 타임에 알려져 있다고 생각합니다. 및 정적. 반환 값의 크기도 같습니다. 넷째, 둘 다 알려져 있지 않습니다. – unwind

+1

C에서 일반적으로 반환 스택과 인수 스택은 같습니다. 인수와 리턴 주소는 기계 스택에서 (대개 이것은 필요하지 않습니다.) 그러나 C는 레지스터에서 인수를 전달할 수 있으며 일반적으로 레지스터에서도 인수를 반환합니다. 그래서 C는 Forth와 같은 스택 기반 언어가 아닙니다.넷째, 스택은 언어에 매우 중요합니다. –

+1

앞서 리턴 스택은 종종 임시 저장소로 사용됩니다. 데이터 스택에서 값을 가져와 "아래"값에 더 쉽게 액세스 할 수 있습니다. 그리고 일반적으로 예외 처리에서 역할을합니다. 반환 주소를 기억하는 데 사용되는 것은 아닙니다. 사실, 그러한 반환 값이 거기에 저장되어야하는 것은 아닙니다. –

답변

5

"휴대용 어셈블리 언어"가 가까워 야합니다. 그것은 표준/전통적인 Forth와 거의 동일한 언어를위한 컴파일러의 개념입니다. 어떤 종류의 프로그램을 쓸 수 있는지에 대한 몇 가지 제한이 있습니다. 대부분 스택의 깊이를 정적으로 결정할 수없는 상황을 피해야합니다.

이 언어는 스택이 하나만 필요한 방식으로 컴파일 할 수 있습니다.

http://www.complang.tuwien.ac.at/anton/euroforth/ef13/papers/ertl-paf.pdf

3

서문 : 나는 엉망 호출 스택 몇 가지 문제를 추적하기 위해 하드웨어 디버거에 대한 확장을 서면으로 작성했습니다, 그래서 실제 C 스택의 일부 진수 덤프를 보았다.

C 스택은 리턴 주소, 로컬 변수 및 함수 매개 변수의 혼합으로 구성됩니다. 각 함수에 대해 어떤 값을 기대하는지 알 수 있지만이 지식은 함수 범위에서 중지됩니다.

이 방법은 forth으로도 가능하지만 이것은 거대한 오버 헤드를 의미합니다. 스택에 매개 변수를 배치하고 함수를 호출하여 동일한 스택의 맨 위에 반환 주소를 배치 할 수 있습니다. 문제 없음 : 각 명령은 피연산자가 스택에서 두 번째이고 뒤 따른다는 것을 안다. 그러나 이제 명령은 다음 값으로 다른 명령을 호출하려고합니다. 이렇게하면 호출 된 명령이 스택에 묻혀있는 위치를 알 수 없으므로 값을 맨 위에 다시 놓기 위해 스택의 순서를 변경해야합니다. 썼다.

컴파일러는 더 복잡한 forth 컴파일러는 각 명령이 걸리는 값의 개수를 추적하고 각 명령 호출 전에 스택을 정렬 할 수 있습니다. 그러나 어떤 비용으로!

물론 C 프로그램에도이 오버 헤드가 있습니다. 인라인 어셈블리에서 비 인라인 함수 호출을 발견하면 항상 레지스터 스와핑 오버 헤드가 있습니다. 그러나 좋은 forth 프로그램은 작은 함수로 구성되어 있으므로 더 많은 함수 호출과 더 많은 오버 헤드가 있습니다.

현대적인 컴퓨터 아키텍처에서와 같이 각 레지스터는 스택 포인터로 사용할 수 있으므로 아무 문제없이 소수의 스택을 가질 수 있습니다.

마지막으로 질문에 대한 대답은 다음과 같습니다. 예, forth의 1 스택 파생물을 구현할 수 있지만 이득이없는 고통입니다.