무엇이의 방향으로 스택에서 성장이 가장 현대적인 시스템의 차이점은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/664744

문제

내가 준비하는 몇몇 교육 자료 C 고 내가 원하는 예제에 맞게 전형적인 스택 모델입니다.

어떤 방향으로는 C 스택에서 성장 리눅스,윈도우,맥 os x(PPC 및 x86),Solaris,가장 최근의 유닉?

도움이 되었습니까?

해결책

스 성장하지 않는 일반적으로 운영 체제에 따라 다르지만,프로세서에 그것을 실행한다.Solaris,예를 들어,에서 실행됩 x86 및 SPARC.Macosx(당신이 언급한다)에서 실행됩 PPC 및 x86.리눅스에서 모든 것을 내 큰 honkin'시스템 z 에서 작동하는 아주 작은 작은 손목 시계.

만일 CPU 가 제공하는 모든 종류의 선택,ABI/호출 규칙을 사용하는 OS 를 지정하는 선택을 만들 필요가 있는 경우에 당신이 당신의 코드를 호출하는 모든 사람이 다른 사람의 코드입니다.

프로세서와 그 방향으로는:

  • 86:니다.
  • SPARC:선택할 수 있습니다.표준 ABI 사용합니다.
  • PPC:아래로,나는 생각한다.
  • System z:에 연결 목록이 없어(하지만 아직도 아래 이상을 위해,zlinux 의).
  • 팔:선택할 수 있지만,Thumb2 는 컴팩트한 인코딩에 대해서만 아래로(LDMIA=증가한 후,STMDB=감소하기 전에).
  • 6502:아래(하지만 256 바이트).
  • RCA1802A:어떤 방법으로,당신이 원하는 대상이 SCRT 구현합니다.
  • PDP11:니다.
  • 8051:니다.

내 나이에 그는 마지막 몇 1802 었 칩을 제어하는 데 사용되는 초 셔틀(감지하면 문이 열려,생각에 따라 처리 능력을 했:-)그리고 내 두 번째 컴퓨터 X-35 (다음과 같은 나 ZX80).

PDP11 정에서 얻 ,8051 에서 정보 .

SPARC 아키텍처를 사용하 슬라이딩 창 레지스터 모델이다.구조적으로 보이는 상세정보를 포함한 원형 버퍼 레지스터의 윈도우는 것은 유효하고 캐시된 내부적으로와 트랩을 때는 이상/언더플로우.보 자세한 내용은.로 이 SPARCv8 수동 설명, 저장 및 복구 지침과 같은 지침을 추가스 등록-창 회전입니다.를 사용하여 긍정적인 일정한 대신의 부정적인 것을 제공하는 상향-성미이다.

The afore-mentioned SCRT 기술은 다른 1802 사용되는 몇 가지 또는 그것의 16 비트 레지스터에 대한 SCRT(표준화하고 돌아 기술).하나의 프로그램 카운터로 사용할 수 있습니다 어떤로 등록 PC SEP Rn 명령입니다.하나는 스택은 포인터와 두 항상 포인트를 SCRT 코드 주,하나의 전화,위해 하나를 반환합니다. No 등록 처리에 특별한 방법입니다.마음에 이러한 내용은 메모리에서,그들은하지 않을 수 있습니다 완전히 올바른입니다.

는 경우,예를 들어,R3 었 PC,R4 었 SCRT 호출 주소,R5 었 SCRT 반환 주소와 R2 었다"stack"(따옴표로 구현에서는 소프트웨어), SEP R4 설 R4 을 PC 의 시작 실행 SCRT 전화 코드입니다.

그 다음에 저장 R3 에서 R2 에는"stack"(I think R6 사용에 대한 임시 저장장치),조정 또는 아래로 잡아 다음과 같은 두 바이트 R3 드 R3,다음 SEP R3 를 실행하는 것으로서 새로운 주소입니다.

반환하는 것, SEP R5 는 것이기도 하지 오래 된 주소 떨어져 R2 스택,추가 두다(를 건너 주소를 바이트의 통화),로드 R3 고 SEP R3 를 실행 시작 이전 코드입니다.

하 주위에 당신의 머리를 감싸는 처음 이후의 모든 6502/6809/z80 스택에 기반 코드 하지만 아직도 우아한에서 강타-당신의 머리에 종류의 방법입니다.또한 하나의 큰 판매하는 기능의 칩이트 16 16 비트 레지스터 사실에도 불구하고,당신은 즉시 7 개의 그(5SCRT,두을 위한 DMA 고 인터럽트 메모리에서).Ahh,의 승리는 마케팅을 통해 현실:-)

시스템은 실제로 매우 유사,를 사용하여 R14 및 R15 등록에 대한 호출/반환합니다.

다른 팁

C ++에서 (C에 적응할 수 있음) stack.cc:

static int
find_stack_direction ()
{
    static char *addr = 0;
    auto char dummy;
    if (addr == 0)
    {
        addr = &dummy;
        return find_stack_direction ();
    }
    else
    {
        return ((&dummy > addr) ? 1 : -1);
    }
}

자라는 장점은 오래된 시스템에서 스택은 일반적으로 메모리 맨 위에 있습니다. 프로그램은 일반적으로 바닥에서 시작하여 메모리를 채우기 때문에 이러한 종류의 메모리 관리는 스택의 바닥을 현명한 곳에 측정하고 배치 할 필요성을 최소화했습니다.

스택은 x86에서 자라며 (아키텍처로 정의, 팝 증분 스택 포인터, 푸시 감소).)

MIPS에는 없습니다 push/pop 지침. 모든 푸시/팝은 스택 포인터에 상대적으로로드/저장으로 명시 적으로 수행 한 다음 수동으로 조정합니다. $sp 바늘. 그러나 모든 레지스터 (제외) $0)는 이론적으로 범용입니다 어느 레지스터는 스택 포인터 일 수 있으며 스택은 프로그래머가 원하는 방향으로 성장할 수 있습니다. Mips Abis는 일반적으로 아래쪽으로 자랍니다.

Intel 8051에서 스택이 자라서 메모리 공간이 너무 작기 때문에 (원래 버전의 128 바이트) 힙이없고 스택을 위에 올려 놓을 필요가 없기 때문에 힙 성장에서 분리 될 필요가 없기 때문일 것입니다. 바닥에서.

프로그램에 할당 된 메모리에는 "영구 데이터", 즉 맨 아래의 프로그램 자체에 대한 코드가 있고 중간에있는 힙이 있기 때문에 자랍니다. 스택을 참조 할 또 다른 고정 지점이 필요하므로 상단을 남길 수 있습니다. 이는 스택이 힙의 물체에 인접 해있을 때까지 스택이 자라다는 것을 의미합니다.

대부분의 시스템에서 스택은 자라며 내 기사는 https://gist.github.com/cpq/8598782 그것이 자라는 이유를 설명합니다. 그 이유는 두 개의 성장하는 메모리 영역 (힙 및 스택)의 최적 레이아웃 때문입니다.

내가 볼 수있는 한이 점을 만지지 않은 다른 답변에 작은 추가 사항이 있습니다.

스택이 아래쪽으로 커지면 스택 내의 모든 주소가 스택 포인터에 비해 양의 오프셋을 갖습니다. 미사용 스택 공간을 가리키기 때문에 음의 오프셋이 필요하지 않습니다. 이는 프로세서가 스택 포인터 관련 주소 지정을 지원할 때 스택 위치에 액세스하는 것을 단순화합니다.

많은 프로세서에는 일부 레지스터에 비해 양수 전용 오프셋으로 액세스 할 수있는 지침이 있습니다. 여기에는 많은 현대 건축물뿐만 아니라 오래된 건축물이 포함됩니다. 예를 들어, ARM Thumb ABI는 단일 16 비트 명령어 단어 내에서 인코딩 된 양의 오프셋으로 스택 포인터 관련 액세스를 제공합니다.

스택이 위쪽으로 성장하면 스택 포인터에 대한 모든 유용한 오프셋은 음수 일 것이므로 직관적이지 않고 덜 편리합니다. 또한 구조물의 필드에 액세스하기위한 등록 관련 주소 지정의 다른 응용 프로그램과도 상충됩니다.

이 매크로는 UB없이 런타임에이를 감지해야합니다.

#define stk_grows_up_eh() stk_grows_up__(&(char){0})
_Bool stk_grows_up__(char *ParentsLocal);

__attribute((__noinline__))
_Bool stk_grows_up__(char *ParentsLocal) { 
    return (uintptr_t)ParentsLocal < (uintptr_t)&ParentsLocal;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top