2012-10-02 3 views
9

일부 C 프로그램을 디스 어셈블하여 생성 된 일부 어셈블리를보고 있는데 자주 반복되는 단일 최적화로 혼란 스럽습니다.GCC에서 빼기를 위해 "sub"대신 "lea"를 방출하는 이유는 무엇입니까?

나는 GCC 컴파일러에 더 최적화가없는 뺄셈의 subl 명령을 사용하지만, 내가 가진 않을 때 최적화 컴파일러가 대신 뺄셈의 leal 명령을 사용한다 (정확히 말하면 -O3) 켜져 아래 예 :

없이 최적화 : 최적화와

83 e8 01  subl $0x1, %eax 

8d 6f ff  leal -0x1(%edi), %ebp 

이 두 명령어는 모두 길이가 3 바이트이므로 여기서 최적화를 보지 않을 것입니다. 누군가 나를 도우려고 컴파일러의 선택을 설명하려고 할 수 있습니까?

도움을 주시면 감사하겠습니다.

답변

13

이것을 생성하는 원래의 C 코드를 보지 않고도 말하기는 어렵습니다.

그러나 추측해야만한다면 leal은 원본 레지스터를 손상시키지 않고도 빼기 작업을 수행 할 수 있기 때문입니다.

이렇게하면 추가 레지스터 이동을 절약 할 수 있습니다.


첫 번째 예 :

83 e8 01  subl $0x1, %eax 

함으로써 원래의 값을 덮어 파괴 %eax.

번째 예 :

8d 6f ff  leal -0x1(%edi), %ebp 

저장 %ebp으로 %edi - 1. %edi은 나중에 사용할 수 있도록 보존됩니다.

+0

최적화되지 않은 버전은 빼기에 즉시 값만 사용하므로이 관점에서는 고려하지 않았습니다. 고마워, 이것은 매우 도움이되었다. –

10

lea은 플래그에 영향을주지 않지만 sub은 플래그에 영향을주지 않습니다. 따라서 후속 명령어가 뺄셈에 의해 업데이트되는 플래그에 의존하지 않으면 이 아닌 플래그를 업데이트하는 것이 더 효율적입니다.

+0

'lea'가 플래그에 영향을주지 않는다면 어떻게'sub'와 같은가? 'sub'와 같은 효과를주는 플래그에 영향을 미치지 않아야합니까? – crisron

+1

@crisron 그들은 동등하지 않고 다른 용도로 사용됩니다. 부작용을 원하지 않거나 부작용이 필요하다면 lea를 사용하십시오. 그렇지 않으면 sub를 사용하십시오 –