push val : val을 스택 최상단에 쌓음pop reg : 스택 최상단의 값을 꺼내서 reg에 대입call addr : addr에 위치한 프로시저 호출
; call 명령어 사용시 이루어지는 연산
push return_address ; retrun add를 스택에 저장후
jmp addr ; 호출한 주소로 점프
leave : 함수 반환 이후 스택프레임 정리
- 스택프레임 : 함수 별로 임시 값을 저장하기 위해 스택을 사용하는데, 각 함수의 영역을 구분하기 위해 사용
; leave 명령어 사용시 이루어지는 연산
mov rsp, rbp
; rbp는 기존의 스택프레임을 담고 있고, rsp는 top 역할을 함
; call 하면 rbp의 주소가 스택에 push 되어 저장됨.
; 새 스택 프레임을 만드려면 rsp를 사용해야 하므로 임시로 rbp를 rsp로 이동
; 새 스택 프레임을 할당하고 온 rsp를 rbp 위치로 이동시킴으로써 새 스택프레임 생성전 저장해 뒀던 rsp의 위치로 돌아감.
pop rbp
; 저장해뒀던 기존 스택프레임 주소를 pop
이 모든 과정을 이해 할때, rsp와 rbp가 주소를 가르키는 포인터 라는 점을 고려하지 않으면 이해하기 힘들다.
나도 처음에 이 문제를 풀때, rsp와 rbp가 가변적인 포인터가 아니라 고정된 공간이라고 생각을 해서 코드를 해석하는게 어려웠다 ㅠㅠ
저장 후에 rip을 프로시저로 이동
ret : retrun address로 반환
; ret 명령어 사용시 이루어지는 연산
pop rip ; 스택에 저장해 놓았던 retrun add를 pop
syscall 명령어 사용 → x64 기준