2011-08-28 6 views
2

일부 저수준 코드를 작성 중이며 불필요한 수준의 함수 호출을 간접적으로 인식했으며 그 간접적 인 이유가 무엇인지 알지 못합니다.이상한 수준의 함수 호출 간접 호출

 
__declspec(noinline) int test123() 
{ 
0041FA70 sub   esp,7Ch 
    char buf[123]; 
    return get_alignment(buf); 
0041FA73 lea   eax,[esp] 
0041FA76 push  eax 
0041FA77 call  get_alignment (40A38Fh) 
} 
... 
get_alignment: 
0040A38F jmp   get_alignment (41FA60h) 
... 
__declspec(noinline) int get_alignment(void * ptr) 
{ 
    return 1; 
0041FA60 mov   eax,1 
} 

그래서 : I는 ASM 모드 (Ctrl 키 +의 F11) I이 참조에 디버거 기능 검사()의 내부 코드를 단계별 나타나면

__declspec(noinline) int get_alignment(void * ptr) 
{ 
    return 1; 
} 

__declspec(noinline) int test123() 
{ 
    char buf[123]; 
    return get_alignment(buf); 
} 

, 다음은 그 동작을 보여준다 더미 코드는 , 그 질문은 간접 참조의 여분의 레벨에 관한 것입니다 : get_alignment : 0040A38F jmp get_alignment (41FA60h)

WTF는 대략입니까? 난 그냥 그것을 얻지 않는다, 그것은 dll에서 함수를 가져올 수 없습니다, 그것은 실행 파일에 정의 된 로컬 함수입니다. 이 실행 파일은 모든 종류의 최적화 (링크 타임 코드 생성 제외)로 컴파일됩니다. get_alignment의 선언에 static을 추가하면 여분의 간접 참조가 사라집니다. 그러나 나는 "고치기"를 찾고 있지 않다, 나는 그 여분의 도약이 왜 전혀 없는지 이해하고 싶었다.

내 실제 응용 프로그램에서는 실제로 .asm 파일로 작성된 함수를 사용하고 추가 점프가 생성 된 이유를 알 수 없습니다. 만약 내가 C- 모드 (C++이 아님)로 코드를 컴파일한다면 더 이상 간접적 인 수준을 보지 못할 것입니다 ...

누구나 그 이상한 행동에 대해 밝힐 수 있습니까?

감사합니다.

답변

2

이것은 링커의/INCREMENTAL 옵션의 부작용입니다. 증분 링크 및 편집 + 계속을 가능하게합니다. 점프는 프로그램이 실행되는 동안 코드를 편집 할 때 사용됩니다. 대체 함수가 다른 주소로 컴파일되고 jmp 대상이 새 함수를 가리 키도록 패치됩니다. 점진적 연결은 이진 이미지를 처음부터 다시 만들지 않아도되도록 사용합니다.

+0

/ZI를 사용하지 않습니다./Zi를 사용합니다. Rayomond가 지적한 것처럼 점진적인 연결 문제가있었습니다. – Pavel

2

아마도 증분 링크가 활성화되어있을 것입니다. 점진적으로 링크 된 모듈에는 "새 주소로 함수 재배치를 처리하기 위해 점프 썽크가 포함될 수 있습니다." http://msdn.microsoft.com/en-US/library/4khtbfyf(v=VS.80).aspx

+0

점진적 링크 또는 편집 + 계속 활성화에서 의미가 있지만, 릴리스 빌드에서는 둘 중 하나를 사용하지 않습니다. 그들의. 증분 링크가 실제로 활성화 된 것으로 보입니다. WTF, 나는 그 설정을 기본 상태로 유지했다. (아무것도 설정되지 않았다.) VS는 기본적으로이 기능을 사용한다. 내 생각에 그것은 그들의 버그, 그것은 기본적으로 활성화해서는 안됩니다. – Pavel

1

간략히 말하자면, 제 빌드에서 명시 적으로 비활성화하지 않았기 때문에 증분 링크가 활성화되었습니다. 일반적으로 링커 옵션 인 증분 링크는 추가 점프 (/ INCREMENTAL : NO 옵션)를 피하기 위해 비활성화됩니다.