속기는 아닙니다.
이 +=
기호는 1970 년대에 C 언어로 나타 났으며, "스마트 어셈블러"라는 C 개념은 분명히 다른 기계 명령 및 어드레싱 모드에 해당합니다.
" i=i+1
", "i+=1
"및" ++i
"와 같은 것은 추상적 수준에서는 동일한 효과를 생성하지만 낮은 수준에서는 프로세서의 다른 작동 방식에 해당합니다.
특히 i
변수가 CPU 레지스터에 저장된 메모리 주소에 있다고 가정하면 (이름을 D
"포인터에 대한 포인터"로 간주) 프로세서 의 ALU 는 매개 변수를 사용하여 결과를 반환합니다. "누적 기"(A라고 부릅니다-정수라고 생각하십시오).
이러한 제약 조건 (해당 기간의 모든 마이크로 프로세서에서 매우 흔함)으로 인해 번역이 발생할 가능성이 높습니다
;i = i+1;
MOV A,(D); //Move in A the content of the memory whose address is in D
ADD A, 1; //The addition of an inlined constant
MOV (D) A; //Move the result back to i (this is the '=' of the expression)
;i+=1;
ADD (D),1; //Add an inlined constant to a memory address stored value
;++i;
INC (D); //Just "tick" a memory located counter
이를 수행하는 첫 번째 방법은 최적이 아니지만 상수 ( ADD A, B
또는 ADD A, (D+x)
) 대신 변수를 사용하여 조작 하거나 더 복잡한 표현식을 변환 할 때 (일반적 으로 스택에서 우선 순위가 낮은 푸시 조작에서 모두 종료 됨) 모든 주장이 없어 질 때까지 반복하십시오.)
두 번째는 "상태 머신"의보다 전형적인 예입니다. 우리는 더 이상 "표현식을 평가하는"것이 아니라 "값을 조작하는 것"입니다. 우리는 여전히 ALU를 사용하지만 매개 변수를 대체 할 수있는 결과로 값을 옮기지 마십시오. 더 복잡한 표현이 필요한 경우에는 이러한 종류의 명령을 사용할 수 없습니다 . 더 많은 시간이 필요 i = 3*i + i-2
하므로 제자리에서 조작 할 수 없습니다 i
.
세 번째-더 간단한 방법은 "추가"라는 개념을 고려하지 않고 카운터에 대해 더 "기본적"(계산적 의미) 회로를 사용합니다. 조합 네트워크가 카운터를 작게 만들기 위해 레지스터를 개조해야하므로 풀 가산기보다 빠르기 때문에 명령이 짧아지고 빠르게로드되며 즉시 실행됩니다.
현대의 컴파일러 (현재 C 참조)에서 컴파일러 최적화를 가능하게하면 편의성에 따라 해당 내용을 교체 할 수 있지만 의미에는 여전히 개념적 차이가 있습니다.
x += 5
방법
- x로 식별되는 장소 찾기
- 그것에 5를 더하십시오
그러나 다음을 x = x + 5
의미합니다.
- x + 5를 평가하십시오
- x로 식별되는 장소 찾기
- x를 누산기에 복사
- 누산기에 5 추가
- 결과를 x에 저장
물론 최적화는
- "찾기 x"에 부작용이없는 경우 두 "찾기"를 한 번 수행 할 수 있습니다 (x는 포인터 레지스터에 저장된 주소가 됨)
- ADD가
&x
대신 어큐뮬레이터에 적용되면 두 복사본을 제거 할 수 있습니다.
따라서 최적화 된 코드가 일치하도록 x += 5
만듭니다.
그러나 "finding x"에 부작용이없는 경우에만 수행 할 수 있습니다.
*(x()) = *(x()) + 5;
과
*(x()) += 5;
x()
부작용 (admting x()
은 이상한 일을하고을 반환하는 함수 int*
)이 두 번 또는 한 번 생성 되므로 의미 적으로 다릅니다 .
간의 등가 x = x + y
및 x += y
인하여 특별한 경우에 따라서 인 +=
과 =
직접 L 값에 적용된다.
파이썬으로 옮기기 위해 C에서 구문을 상속했지만 해석 된 언어로 실행하기 전에 번역 / 최적화가 없기 때문에 일이 밀접하게 관련되어 있지는 않습니다 (파싱 단계가 적기 때문에). 그러나 인터프리터는 세 가지 유형의 식에 대해 서로 다른 실행 루틴을 참조 할 수 있으며 식의 형성 방식과 평가 컨텍스트에 따라 다른 기계 코드를 활용합니다.
더 자세한 정보를 좋아하는 사람은 ...
모든 CPU에는 본질적으로 명령의 opcode에 따라 입력 및 출력이 레지스터 및 / 또는 메모리에 "플러그 된"조합 네트워크 인 ALU (산술 논리 단위)가 있습니다.
이진 연산은 일반적으로 "어딘가에 입력이있는 어큐뮬레이터 레지스터의 수정 자로 구현됩니다. 여기서 어딘가에-명령 흐름 자체 내부 (표현 적 상수에 대해서는 ADD A 5)-다른 레지스트리 내부 (일반적으로 식 계산에 사용) 임시 : 예 : ADD AB)-메모리 내부, 레지스터에 의해 주어진 주소 (일반적으로 데이터 페칭 예 : ADD A (H))-H,이 경우 역 참조 포인터처럼 작동합니다.
이 의사로, x += 5
이다
ADD (X) 5
반면이 x = x+5
있다
MOVE A (X)
ADD A 5
MOVE (X) A
즉, x + 5는 나중에 할당 된 임시를 제공합니다. x += 5
x에서 직접 작동합니다.
실제 구현은 프로세서의 실제 명령어 세트에 따라 다릅니다. ADD (.) c
opcode 가 없으면 첫 번째 코드가 두 번째 코드가됩니다.
이러한 opcode가 있고 최적화가 활성화 된 경우 두 번째 표현식은 역 이동을 제거하고 레지스터 opcode를 조정 한 후 첫 번째 표현식이됩니다.
x += 5
보다x = x + 5
? 아니면 당신이 제안한대로 진정으로 구문 설탕입니까?