• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

stack 쌓는 순서

23.12.13 16:38 작성 조회수 207

0

 안녕하세요.
우분투 disas main으로 어셈블리어로 stack 이 어떻게 쌓는지 공부하는 중인데요.


어셈블리어로 연산코드가 mov라서 제 해석이 틀린건가요?
지역변수는 선언한 순서로 Push된다고 이해했는데 실제로 해보니 달라서 질문드립니다. int type으로 정의한 $0x1, -0x30에서 주소가 -0x3a로 멀어져서 이해가 안돼서 질문 드렸습니다.
그 이후 부터는 stack이 하나씩 지워지면서 rbp 포인터로 가까워 지는 모양으로 이해했는데 char 형태에서 오히려 더 밀려나서 주소가 왜 밀린건지 이해가 되지않습니다.

물론 함수 호출이 아닌 변수를 정의한 거지만 결은 비슷할 거라 생각이 들어서 질문 드립니다.
너무 궁금해서 엉뚱한 질문이지만 알려주시면 감사합니다...

 

답변 1

답변을 작성해보세요.

1

디스어셈블 코드는 디스어셈블러에 따라 조금씩 다르게 표기 될 수 있습니다. 그러나 지금 질문에서는 신경쓸 주제는 아닌 것 같습니다. 지역변수는 보통 선언한 순서대로 스택에 Push되는 것이 항상 옳은 것은 아닙니다. 일반적인 컴파일러 언어들은 최소 2회 이상 컴파일을 하는데 첫 번째 단계에서 지역변수 목록을 확보하고 소요될 Stack의 량을 계산합니다. 이 때 선언된 순서에 따라 스택 메모리 위치를 지역변수 + 자동변수에게 배치 할 수도 있고 아닐 수도 있습니다. 보통은 선언된 순서대로 스택에 Push되거나 아니면 선언된 순서의 역순으로 Push되는경향이 있습니다.

그리고 소모되는 스택 메모리의 크기는 보통 지역변수의 크기보다 더 큰 값이 할당 됩니다. 메모리 패킹 때문입니다. 이는 구조체 멤버 정렬과 비슷한 원리 입니다.

끝으로 지역변수로 인식되는 함수의 매개변수는 또 다릅니다. 무엇보다 64비트 환경에서는 fastcall 호출 규약이 늘 적용된다고 볼 수 있습니다. 해서 아예 스택에 메모리 공간이 표시되지 않을 수 있습니다.

참고하시기 바랍니다. :)

답변 감사드립니다. 굳이 안 봐도 되는 부분인데 계속 궁금해서 한번 질문했습니다. 핵심부터 다시 쌓아가겠습니다.