스택의 동작 (성장 또는 감소)은 ABI (애플리케이션 바이너리 인터페이스) 및 호출 스택 (활성화 레코드라고도 함)이 구성되는 방식에 따라 다릅니다.
평생 동안 프로그램은 OS와 같은 다른 프로그램과 통신해야합니다. ABI는 프로그램이 다른 프로그램과 통신하는 방법을 결정합니다.
다른 아키텍처의 스택은 어느 쪽이든 성장할 수 있지만 아키텍처의 경우 일관성이 있습니다. 이 위키 링크를 확인 하십시오. 그러나 스택의 성장은 해당 아키텍처의 ABI에 의해 결정됩니다.
예를 들어 MIPS ABI를 사용하는 경우 호출 스택은 다음과 같이 정의됩니다.
함수 'fn1'이 'fn2'를 호출한다고 가정 해 보겠습니다. 이제 'fn2'에 표시된 스택 프레임은 다음과 같습니다.
direction of | |
growth of +---------------------------------+
stack | Parameters passed by fn1(caller)|
from higher addr.| |
to lower addr. | Direction of growth is opposite |
| | to direction of stack growth |
| +---------------------------------+ <-- SP on entry to fn2
| | Return address from fn2(callee) |
V +---------------------------------+
| Callee saved registers being |
| used in the callee function |
+---------------------------------+
| Local variables of fn2 |
|(Direction of growth of frame is |
| same as direction of growth of |
| stack) |
+---------------------------------+
| Arguments to functions called |
| by fn2 |
+---------------------------------+ <- Current SP after stack
frame is allocated
이제 스택이 아래쪽으로 커지는 것을 볼 수 있습니다. 따라서 변수가 함수의 로컬 프레임에 할당되면 변수의 주소는 실제로 아래쪽으로 커집니다. 컴파일러는 메모리 할당을위한 변수의 순서를 결정할 수 있습니다. (귀하의 경우에는 처음 할당 된 스택 메모리 인 'q'또는 's'일 수 있습니다. 그러나 일반적으로 컴파일러는 변수 선언 순서에 따라 스택 메모리 할당을 수행합니다.)
그러나 배열의 경우 할당에는 단일 포인터 만 있으며 할당해야하는 메모리는 실제로 단일 포인터에 의해 가리 킵니다. 메모리는 배열에 대해 연속적이어야합니다. 따라서 스택이 아래쪽으로 커지더라도 어레이의 경우 스택이 커집니다.