asm 정리

이젠 진짜 이 정도면 된거같다

Untitled

  • 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

함수 호출 방법

Untitled

  1. jmp 명령어
  2. call 사용

함수 인자는 뒤에서부터 넣는다.

Untitled

함수의 스택 방향.

  • sub sp => 지역변수 공간 할당.
  • add sp -> 할당한 공간 (지역변수, stack frame) 삭제

calling convention

Untitled

cdecl vs stdcall

가장 큰차이 sp 복구하는 곳의 위치

caller vs callee ⇒ stdcall 이 실행파일 크기가 더작음. (but 가변인자사용 불가)

this pointer를 함수안에서 cx레지스터로 계속 들고있음.

추가적으로 vectorcall도 존재

스택 프레임

Untitled

Untitled

가운데 a, b로 접근이 가능한이유 프롤로그 에필로그를 컴파일러가 알아서 만들어 줬기 때문

Untitled

스택포인터쌓을때는 값을 뺌 sub → 주소 값이 작아짐

  • ebp + a ⇒ 인자
  • ebp - b ⇒ 지역변수

규칙상 esi edi ebx는 보호되어야하는 레지스터

사용하려면 push 복구때 pop

X64에서의 변경점

Untitled

https://learn.microsoft.com/en-us/cpp/build/stack-usage?view=msvc-170

Untitled

기존 push 네번대신 레지스터 네개가지고 전달

근데 32byte 스택포인터 값을 빼버리고 디버거에서 사용

argument home area라고 부름

Untitled

Untitled

18h(24) 뺀이유 로컬변수 C를 확보하기위함.

return address 값이 저장되면서 sp의 16byte align이 깨짐 그래서 시작주소를 16byte align하기위해 추가. local 변수 c도 16byte align이 아니라서 추가적인 메모리 할당 존재

Untitled

레지스터 전체

Untitled

Posted 2023-03-07