본문 바로가기

Layer7

Assembly X86 Stack 관리

스택(Stack) : 함수의 호출과 관계되는 지역 변수와 매개 변수가 저장되는 영역.

  • 함수의 호출과 함께 할당되며 함수의 호출이 완료되면 사라짐.

→ 스택 영역에 저장되는 함수의 호출 정보를 스택 프레임(Stack Frame)이라고 함

  • 프로그램이 자동으로 사용하는 임시 메모리 영역
  • 메모리의 높은 주소에서 낮은 주소의 방향으로 할당됨
  • 컴파일 시에 크기가 결정됨

C 소스코드

gcc 옵션

-S : cc1으로 전처리된 파일을 어셈블리 파일로 컴파일까지만 수행하고 멈춤

-fno-stack-protector : 프로그램을 실행할 때 스택 영역에 다양한 취약점이 있다는 것을 알고 방어체계를 마련해 놓는데 그런 것을 끈 상태로 컴파일

-mpreferred-stack-boundary=4 : 64bit 운영체제 버전으로 컴파일

 

-execstack -o sum.a sum.c : sum.c라는 소스 코드 파일을 어셈블리어로 바꿔줌

 

컴파일한 후 실행

 

 

프로그램이 실행되면
① main 실행
② 이어서 sum( ) 호출
③ 매개 변수로 1과 2를 넣어서 a + b

→ 즉, 1 + 2를 반환함

 

 


main( ) 스택 프레임(Stack Frame). start 함수가 main 함수 불러옴

① main( ) 호출 → RET가 들어감

-RET(return address) : 스택이 쌓인다고 가정했을 때 가장 아래. 특정한 함수가 끝난 뒤에 돌아갈 장소 의미

RET(return address) : 스택이 쌓인다고 가정했을 때 가장 아래. 특정한 함수가 끝난 뒤에 돌아갈 장소 의미

 

② main( )이 끝나면 main( )을 불러온 위치로 돌아감 (=return adress)

③ RBP(return base pointer) : 스택이 시작하는 베이스 포인터. 위로 스택이 쌓일 것이라는 것을 알려줌

④ 그 위에 변수 c 그리고 버퍼가 존재함

▶ main( ) 실행 결과


▶ main 함수에 들어와서 변수 c를 선언하게 되고, sum이라는 함수를 불러왔을 때

 

main( ) 위로 sum( )를 호출 함으로써 차곡차곡 쌓이게 됨

→ main( )가 끝나기 전에 sum( )를 호출했기 때문에 sum( )에 대한 데이터가 위로 쌓인 것

 

★ 어떤 함수를 호출하게 되면 함수의 매개변수가 RET 아래쪽에 쌓이게 됨

 

변수 = sum( )을 실행하기 위한 도구

( x=1, y=2 또는 x=2, y=1 )

 

 

 

 

 


sum 함수가 리턴을 하게 되면

→ 변수 c에 3이 담김

실행이 끝난 sum( )는 사라지고 main( )만 남게 됨

 

 

RET는 특정 함수가 끝난 다음에 돌아가는 메모리 주소의 위치를 지정할 수 있음

 

 

 

 

 


main( )를 보면

① main( )가 호출되면 RET가 들어감

② push    %rbp : RBP가 들어감

③ movl    %rsp, %rbp : RBP와 RSP의 위치가 같음

④ subq    $16, %rsp : rsp에서 16만큼을 뺌 → 16만큼 공간 확보

⑤ movl    $2, %esi : ESI에 2를 넣음 (ESI = 2)

⑥ movl    $1, %edi : EDI에 1을 넣음 (EDI = 1)

⑦ call    sum : sum 함수 호출


sum함수를 보면

① sum( )이 호출되면 RET가 들어감

② push    %rbp : RBP가 들어감

③ movl    %edi, -4(%rbp) : -4(%rbp)의 위치에 edi 값(1)을 넣음

④ movl    %esi, -8(%rbp) : -8(%rbp)의 위치에 esi 값(2)을 넣음

⑤ movl    -4(%rbp), %edx : -4(%rbp)의 값을 edx에 넣음 (EDX = 1)

⑥ movl    -8(%rbp), %eax : -8(%rbp)의 위치의 값을 eax에 넣음 (EAX = 2)

⑦ addl    %edx, %eax : edx의 값을 eax에 더해줌 (EAX = 3)

⑧ popq    %rbp : rbp를 빼줌으로써 ret으로 돌아감

 

eax와 rax는 특정한 함수가 끝날 때 반환 값을 가지고 있음→ sum( )을 빠져나와 다시 main( )으로 돌아감


① mov    %eax, -4(%rbp) : eax의 값(3)을 -4(%rbp)의 위치에 둠

 

② mov    -4(%rbp), %eax : -4(%rbp)의 값(2)을 eax에 저장

 

③ leave : return → eax 값 즉, 3 반환

 

 

 

 

 

'Layer7' 카테고리의 다른 글

코드 분석 하기  (0) 2021.05.30
코드 분석하기  (0) 2021.05.26
Assembly X64  (0) 2021.05.22
실행파일 생성 과정  (0) 2021.05.15
C Pointer  (1) 2021.05.11