문제

C에는 다음 코드 조각이 있습니다.

int a;
a = 10 + 5 - 3

나는 묻고 싶다:(10+5-3)은 어디에 저장되어 있나요?(내가 아는 한, a 스택에 위치합니다. 어떻습니까? (10+5-3)?이 rvalue는 어떻게 계산되나요?)

도움이 되었습니까?

해결책

일반적으로 R- 값은 프로그램 자체 내에 "저장"됩니다.

다시 말해, 컴파일러 자체 (프로그램이 실행되기 전에)는 10 + 5-3 값을 계산합니다 (모두 일정한 즉각적인 값을 기반으로하므로 할 수 있습니다). 어셈블리 코드를 제출 하여이 계산 결과를 할당에 대한 L- 값으로 저장합니다. 컴파일러가 아마도 데이터 세그먼트 원점에 대한 상대 주소로 알고있는 a라는 변수의 경우).

따라서 12 값을 가진 r- 값은 프로그램의 이진 내에서만 발견되며 어셈블리 명령 내에서 발견됩니다. 외모 처럼

  mov <some dest, typically DS-relative>, $0C 

$ 0C는 "R- 값"입니다.

r- 값이 런타임에만 수행 할 수있는 계산의 결과 인 경우, 기본 C 코드가 다음과 같은 경우 : a = 17 * x; // x 일부 실행 시간 var, r- 값은 프로그램 바이너리 내의 일련의 지침으로 "저장"(또는 오히려 구체화)됩니다. 위의 간단한 "mov dest, imm"과의 차이점은 축합기에 변수 x를로드하는 데 몇 가지 지침이 필요하다는 것입니다. 17을 곱하고 변수 a가있는 주소에 결과를 저장합니다. 컴파일러가 "승인";-) 일부 중간 결과에 스택을 사용하는 것이 가능할 수 있습니다.
a) 완전히 컴파일러 종속
b) 트랜스 앙
c) 그리고 일반적으로 만 포함됩니다 부분 R- 값의
따라서 R- 값은 프로그램의 일부 (데이터가 아닌)에 캡슐화되고 프로그램 바이너리에 저장되지 않은 컴파일 타임 개념이라고 말하는 것이 안전합니다.

Paxdiablo에 대한 응답으로 : 위에서 제시 한 설명은 C 표준이 효과적으로 수행하기 때문에 가능성을 실제로 제한합니다. ~ 아니다 그 성격의 모든 것을 지시하십시오. 절대, 대부분의 r- 값은 결국 적어도 부분적으로 부분적으로 구체화되어 (실행 시간에) 계산 되든 즉시 적절한 값이 제대로 해결 될 수 있도록 물건을 설정하는 일부 지침에 의해 구체화됩니다.

다른 팁

상수는 컴파일 시간에 단순화 될 수 있으므로 문자 그대로 제기 된 질문은 도움이되지 않을 수 있습니다. 그러나 말하는 것과 같은 i - j + k CPU 아키텍처에 따라 컴파일러가 좋아하는 곳에서 "저장"될 수 있습니다. 컴파일러는 일반적으로 레지스터를 사용하기 위해 최선을 다하려고합니다.

 LOAD AX, i
 SUB AX, j
 ADD AX, k

그러한 표현식을 계산하려면 Accumulator 레지스터 도끼에 "저장"을 계산하려면 일부 메모리 위치에 할당하기 전에 STORE AX, dest 또는 같은. 합리적으로 간단한 표현식을 위해 메모리에 레지스터를 유출하는 데 필요한 반명의 CPU 아키텍처 (예, x86 포함!-)에서 현대 최적화 컴파일러가 필요하다면 놀랍습니다!

이것은 컴파일러 종속입니다. 일반적으로 값 (12)은 컴파일러에 의해 계산됩니다. 그런 다음 코드에 저장되며, 일반적으로 부하/이동 즉시 어셈블리 명령의 일부로 저장됩니다.

그것이 보관하는 곳은 실제로입니다 완전히 컴파일러까지. 표준은이 행동을 지시하지 않습니다.

전형적인 실제로 코드를 컴파일하고 어셈블러 출력을 보면 장소를 볼 수 있습니다.

int main (int argc, char *argv[]) {
    int a;
    a = 10 + 5 - 3;
    return 0;
}

생산 :

        .file   "qq.c"
        .def    ___main;
            .scl    2;
            .type   32;
        .endef
        .text
.globl _main
        .def    _main;
            .scl    2;
            .type   32;
        .endef
_main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        addl    $15, %eax
        addl    $15, %eax
        shrl    $4, %eax
        sall    $4, %eax
        movl    %eax, -8(%ebp)
        movl    -8(%ebp), %eax
        call    __alloca
        call    ___main
        movl    $12, -4(%ebp)         ;*****
        movl    $0, %eax
        leave
        ret

관련 비트가 표시됩니다 ;***** 그리고 값이 컴파일러에 의해 생성되고 직접 삽입 된 것을 알 수 있습니다. mov 유형 지침.

표현식이 일정한 값이기 때문에 단순히 간단합니다. 비 스턴트 값 (변수와 같은)을 소개하자마자 코드가 조금 더 복잡해집니다. 그 변수들이 메모리에서 (또는 이미 레지스터에있을 수 있음) 값을 조작해야하기 때문입니다. 실행 시간, 아니다 컴파일 타임.

컴파일러가 값이 무엇인지 계산하는 방법에 관해서는 표현 평가와 관련이 있으며 완전히 다른 질문입니다 :-)

  • RHS (오른쪽)의 계산 결과는 "상수 전파"라고하는 단계에서 컴파일러에 의해 계산됩니다.
  • 그런 다음 값을 a

다음은 MSVC의 분해입니다.

  int a;
  a = 10 + 5 - 3;

0041338E  mov         dword ptr [a],0Ch 

귀하의 질문은 잘못된 전제를 기반으로합니다.

의 정의 속성 lvalue C에서는 저장 공간에 위치한다는 것입니다. 저장. 이것이 LValue를 차별화하는 것입니다 rvalue. rvalue입니다 ~ 아니다 어디서나 저장됩니다. 그것이 그것이 rvalue로 만드는 이유입니다. 그것이 저장되면, 그것은 될 것입니다 lvalue 정의에 따라.

"lvalue"와 "rvalue"라는 용어는 표현의 세계를 양분하는 데 사용됩니다.그건, (10+5-3) rvalue가 되는 표현식입니다(& 연산자를 적용할 수 없기 때문입니다. C++에서는 규칙이 더 복잡합니다).런타임에는 표현식, lvalue 또는 rvalue가 없습니다.특히 어디에도 저장되지 않습니다.

값 12가 어디에 저장되어 있는지 궁금했지만 값 12는 lvalue도 rvalue도 아닙니다. 12 이는 rvalue가 되지만 12 프로그램에는 나타나지 않습니다).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top