x86 Assembly

x64 어셈블리 언어

기본 구조: 명령어(opcode) 연산자(operand)

Operand

  1. 상수
  2. 레지스터
  3. 메모리
    크기 지정자+[] 형식: []의 데이터를 크기 지정자만큼 참조
    참고: [rbx+8]이면 rbx부터 8바이트가 아니고 rbx+8부터 참조임

Opcode

1. 데이터 이동(Data Transfer)

  • mov dst, src : src 값을 dst에 대입
  • lea dst, src : src의 유효 주소를 dst에 저장

2. 산술 연산(Arithmetic)

  • add dst, src : dst에 src 더함
  • sub dst, src : dst에 src 뺌
  • inc op : op의 값 1 증가
  • dec op : op의 값 1 감소

3. 논리 연산(Logical)

  • and dst, src : and 연산, f는 그대로 0은 0
  • or dst, src : or 연산, f는 f 0은 그대로
  • xor dst, src : xor 연산
  • not op : 비트 반전

4. 비교 (Comparison)

피연산자 값 비교 후 플래그 설정

  • cmp op1, op2 : 두 피연산자를 빼서 비교
  • test op1, op2 : 두 피연산자를 AND연산해서 비교

5. 분기(Branch)

rip 이동시킴, 다양함

  • jmp addr : addr로 점프
  • je addr : 직전 비교한 두 피연산자 같으면 점프 (jump if equal)
  • jg addr : 직전 비교한 두 연산자 중 전자가 더 크면 점프 (jump if greater)

6. 스택(Stack)

운영체제 핵심 자료구조

  • push val : val을 스택 최상단에 쌓음
  • pop reg : 스택 최상단 값 꺼내서 reg에 대입

7. 프로시져(Procedure)

C언어 함수에 대응
반복되는 연산 -> 프로시저 호출로 대체 가능
프로시저를 호출하고 반환, call 다음 명령어 주소를 스택에 저장하고 rip로 이동시킴
call addr : addr에 위치한 프로시저 호출, push return_address(call 다음 주소임) -> jmp addr
여기까지 하면 스택 rsp에 리턴 주소(call 다음 명령어 주소) 저장됨
기존 스택 프레임 저장을 위해 rbp를 push함
그리고 새로운 스택 프레임 생성… rbp를 rsp로 옮김, 공간 확장을 위해 rsp를 빼줌(아래로 자라니까)
이제 새로운 스택 프레임이 생성되었으니 지역변수 할당하고 연산 처리

leave : 스택프레임 정리, mov rsp, rbp -> pop rbp
rbp를 꺼내서 원래의 스택 프레임으로 돌아감

ret : return address로 반환, pop rip
반환 주소 꺼내서 원래의 실행 코드로 돌아감

8. 시스템 콜(System call)

x