asm 정리
이젠 진짜 이 정도면 된거같다
- si : source register
- di : destination register
register 기초
- rax : return value
- rbx : 호출당하는 함수에서 저장하는 rsp
- rcx : 4th 인자
- rdx : 3rd 인자
- rsi : 2nd 인자
- rdi : 1st 인자
- rbp : stack frame base pointer 함수 호출 직후 스택포인터의 값을 저장하여 사용
- rsp : stack pointer 스택의 가장 아래 주소
- r8 : 5th arg
- r9 : 6th arg
- r10 : callee saved
- r11 : callee saved
- r12: callee saved
- r13 : callee saved
- r14 : callee saved
- r15 : callee saved
- rcx, rdx, r8, r9 : Windows 64bit에서 함수를 호출할 때 필요한 인자들을 순서대로 저장
- rip(PC) : 다음에 실행될 명령어가 위치한 주소
Data Size
- x 16bit
- e~ 32bit
- r~ 64bit
함수 호출 방법
- jmp 명령어
- call 사용
함수 인자는 뒤에서부터 넣는다.
함수의 스택 방향.
- sub sp => 지역변수 공간 할당.
- add sp -> 할당한 공간 (지역변수, stack frame) 삭제
calling convention
cdecl vs stdcall
가장 큰차이 sp 복구하는 곳의 위치
caller vs callee ⇒ stdcall 이 실행파일 크기가 더작음. (but 가변인자사용 불가)
this pointer를 함수안에서 cx레지스터로 계속 들고있음.
추가적으로 vectorcall도 존재
스택 프레임
가운데 a, b로 접근이 가능한이유 프롤로그 에필로그를 컴파일러가 알아서 만들어 줬기 때문
스택포인터쌓을때는 값을 뺌 sub → 주소 값이 작아짐
- ebp + a ⇒ 인자
- ebp - b ⇒ 지역변수
규칙상 esi edi ebx는 보호되어야하는 레지스터
사용하려면 push 복구때 pop
X64에서의 변경점
https://learn.microsoft.com/en-us/cpp/build/stack-usage?view=msvc-170
기존 push 네번대신 레지스터 네개가지고 전달
근데 32byte 스택포인터 값을 빼버리고 디버거에서 사용
argument home area라고 부름
18h(24) 뺀이유 로컬변수 C를 확보하기위함.
return address 값이 저장되면서 sp의 16byte align이 깨짐 그래서 시작주소를 16byte align하기위해 추가. local 변수 c도 16byte align이 아니라서 추가적인 메모리 할당 존재
레지스터 전체
Posted 2023-03-07