[architecture] 스택이 일반적으로 아래쪽으로 커지는 이유는 무엇입니까?

개인적으로 익숙한 아키텍처 (x86, 6502 등)에서 스택은 일반적으로 아래로 커집니다 (즉, 스택에 푸시 된 모든 항목은 증가 된 SP가 아닌 감소 된 SP가됩니다).

이것에 대한 역사적 근거가 궁금합니다. 통합 된 주소 공간에서는 데이터 세그먼트의 반대쪽 끝에서 스택을 시작하는 것이 편리하다는 것을 알고 있습니다 (예를 들어). 따라서 두면이 중간에서 충돌하는 경우에만 문제가 발생합니다. 하지만 왜 스택이 전통적으로 최상위 부분을 차지합니까? 특히 이것이 “개념적”모델의 반대 인 점을 감안할 때?

(또한 6502 아키텍처에서 스택은 단일 256 바이트 페이지로 제한되어 있어도 아래쪽으로 성장하며이 방향 선택은 임의적으로 보입니다.)



답변

역사적 근거에 관해서는 확실히 말할 수 없습니다 (제가 디자인하지 않았기 때문에). 이 문제에 대한 내 생각 은 초기 CPU가 원래 프로그램 카운터를 0으로 설정했고 다른 쪽 끝에서 스택을 시작하고 코드가 자연스럽게 위로 성장하기 때문에 아래로 성장하려는 자연스러운 욕망이었습니다.

제쳐두고, 리셋시 프로그램 카운터를 0으로 설정하는 것은 모든 초기 CPU에 해당하는 것은 아닙니다 . 예를 들어 Motorola 6809는 주소에서 프로그램 카운터를 가져 오므 0xfffe/f로 해당 주소 (일반적으로 ROM에 국한되지 않음)에 제공된 항목에 따라 임의의 위치에서 실행할 수 있습니다.

일부 역사적 시스템이 수행하는 첫 번째 작업 중 하나는 기록 된 동일한 값을 다시 읽을 위치를 찾을 때까지 메모리를 스캔하여 실제 RAM이 설치된 것을 알 수 있도록하는 것입니다 (예 : 64K 주소 공간이있는 z80). 64K 또는 RAM이 반드시 필요하지는 않았습니다. 사실 64K는 초기 에 방대 했을 것 입니다.) 최상위 실제 주소를 찾으면 스택 포인터를 적절하게 설정하고 서브 루틴 호출을 시작할 수 있습니다. 이 스캔은 일반적으로 시작의 일부로 ROM에서 코드를 실행하는 CPU에 의해 수행됩니다.

스택 성장과 관련하여 모든 스택이 아래쪽으로 성장하는 것은 아닙니다 . 자세한 내용 은 이 답변 을 참조하십시오.


답변

내가 들었던 한 가지 좋은 설명은 과거에 일부 기계는 서명되지 않은 오프셋 만 가질 수 있었기 때문에 스택이 아래쪽으로 커져서 네거티브 오프셋을 가짜로 만드는 추가 명령을 잃지 않고 로컬을 공격 할 수 있기를 원한다는 것입니다.


답변

Stanley Mazor (4004 및 8080 설계자)는 “Intel Microprocessors : 8008 to 8086” 에서 8080 (그리고 결국 8086)에 대해 스택 성장 방향이 어떻게 선택되었는지 설명합니다 .

스택 포인터는 사용자 프로그램에서 스택으로의 인덱싱 (양수 인덱싱)을 단순화하고 전면 패널에서 스택의 내용을 간단하게 표시하기 위해 “내리막”(스택이 더 낮은 메모리로 이동)을 실행하도록 선택되었습니다.


답변

한 가지 가능한 이유는 정렬을 단순화하기 때문일 수 있습니다. 4 바이트 경계에 배치해야하는 스택에 로컬 변수를 배치하는 경우 스택 포인터에서 객체의 크기를 뺀 다음 두 개의 하위 비트를 0으로 제거하여 올바르게 정렬 된 주소를 얻을 수 있습니다. 스택이 위로 커지면 정렬을 확인하는 것이 약간 까다로워집니다.


답변

IIRC 힙이 위쪽으로 커지기 때문에 스택이 아래쪽으로 커집니다. 그 반대 일 수도 있습니다.


답변

순전히 디자인 결정이라고 생각합니다. 그들 모두가 아래로 성장하는 것은 아닙니다 . 다른 아키텍처에서의 스택 성장 방향에 대한 좋은 논의는 이 SO 스레드 를 참조하십시오 .


답변

이 대회는 IBM 704와 그 악명 높은 “감소 레지스터”에서 시작되었다고 생각합니다. 현대 연설 명령의 오프셋 필드를 부를 것이다, 그러나 요점은 그들이 갔다이다 다운 , 하지 까지 .