스택 변수 저장방식에 대해 질문이 있습니다.
글쓴이: grupy / 작성시간: 월, 2019/04/08 - 12:32오전
현재 visual studio 2017 사용중입니다.
void fun()
{
int a[2] = {1,2};
int b[2] = {1,2};
}
int main(void)
{
fun();
return 0;
}
해당 함수 실행시, fun 스택 적재 순서는
9. b[0] (한 단계당 4바이트라고 가정)
8. b[1]
7. 0xcccccccc
6. 0xcccccccc
5. a[0]
4. a[1]
3. 0xcccccccc
2. main 함수 ebp
1. main return 주소
이렇게 되는걸로 알고 있습니다.
나머진 다 이해가는데, 왜 굳이 변수 양 사이드에 0xcccccccc값을 남겨둔채
적재하는지 이해가 가질 않습니다.
6. b[0]
5. b[1]
4. a[0]
3. a[1]
2. main 함수 ebp
1. main return 주소
이렇게 적재하면 무슨 문제가 생기는 건가요?
아시는분 답변 해주시면 정말 감사드리겠습니다.
Forums:
귀하께서 그렇게 하라고 했기 때문이죠. 아마 디버그
귀하께서 그렇게 하라고 했기 때문이죠. 아마 디버그 모드로 빌드하셨을 겁니다.
1. 디버그 모드에서 VS는 프로그램 코드와 바이나리 사이의 연관성을 상당히 많이 유지해 주려고 합니다. 그 결과 적용되는 컴파일러 최적화 기법이 상당히 제약됩니다.
2. 디버그 모드에서 컴파일러는 대체로 스택을 필요한 것보다 넓게 잡습니다. 그리고 스택 공간을 미리 0xcc로 채우는데, 이는 x86에서 0xcc가 1바이트 중단점(breakpoint) 명령어이기 때문입니다. 혹시 모를 이상한 이유로 스택 영역을 실행하게 되었을 때 바로 알 수 있게 만든 것이죠. 요즘은 W^X니 뭐니 해서 꼭 이렇게 해야만 할 이유는 없지만요. 그 밖에도 초기화되지 않은 변수를 참조할 때 바로 문제가 드러나게 하고자 하는 목적도 있을 겁니다.
네, 스택에 미리 0xcc를 채울 필요가 없습니다. 뿐만 아니라,
1. ebp도 스택에 있을 필요 없습니다.
2. a와 b도 스택에 있을 필요 없습니다.
3. 사실 main함수는 fun 함수를 호출할 필요도 없습니다.
실제로 적절한 최적화 옵션을 걸어서 빌드를 해 보면, 컴파일러는 1~4와 같은 필요없는 동작은 전혀 하지 않고,
fun과 main 함수 모두 그냥 바로 return 0 하는 함수로 만들어버리곤 합니다. 직접 확인해보세요.
fun 함수가 static으로 선언되어 있었다면, 컴파일러는 fun 함수를 아예 제거해 버릴 수도 있습니다.
자세한 답변 정말 감사드립니다
자세한 답변 정말 감사드립니다
댓글 달기