ㅁ x64 어셈블리 언어
동사에 해당하는 명령어(Operation Code, Opcode)
목적어에 해당하는 피연산자(Operand)로 구성
x86-64 어셈블리어 문법 구조
명령어
명령 코드 | |
데이터 이동(Data Transfer) | mov, lea |
산술 연산(Arithmetic) | inc, dec, add, sub |
논리 연산(Logical) | and, or, xor, not |
비교(Comparison) | cmp, test |
분기(Branch) | jmp, je, jg |
스택(Stack) | push, pop |
프로시져(Procedure) | call, ret, leave |
시스템 콜(System call) | syscall |
피연산자
- 상수(Immediate Value)
- 레지스터(Register)
- 메모리(Memory)
메모리 피연산자는 []으로 둘러싸인 것으로 표현됌
앞에 크기 지정자(Size Directive) TYPE PTR이 추가될 수 O.
타입에는 BYTE, WORD, DWORD, QWORD가 올 수 있으며, 각각 1바이트, 2바이트, 4바이트, 8바이트의 크기를 지정
메모리 피연산자의 예
QWORD PTR [0x8048000] | 0x8048000의 데이터를 8바이트만큼 참조 |
DWORD PTR [0x8048000] | 0x8048000의 데이터를 4바이트만큼 참조 |
WORD PTR [rax] | rax가 가르키는 주소에서 데이터를 2바이트 만큼 참조 |
+) 자료형 WORD의 크기가 2바이트인 이유
인텔은 WORD 자료형의 크기를 16비트로 유지했다. 왜냐하면, WORD 자료형의 크기를 변경하면 기존의 프로그램들이 새로운 아키텍처와 호환되지 않을 수 있기 때문
인텔은 기존에 사용하던 WORD의 크기를 그대로 유지하고, DWORD(Double Word, 32bit)와 QWORD(Quad Word, 64bit)자료형을 추가로 만듬
ㅁ 어셈블리 명령어
데이터 이동
어떤 값을 레지스터나 메모리에 옮기도록 지시.
:: mov dst, src : src에 들어있는 값을 dst에 대입
mov rdi, rsi | rsi의 값을 rdi에 대입 |
mov QWORD PTR[rdi], rsi | rsi의 값을 rdi가 가리키는 주소에 대입 |
mov QWORD PTR[rdi+8*rcx], rsi | rsi의 값을 rdi+8*rcx가 가리키는 주소에 대입 |
:: lea dst, src : src의 유효 주소(Effective Address, EA)를 dst에 저장
lea rsi, [rbx+8*rcx] | rbx+8*rcx 를 rsi에 대입 |
산술 연산
덧셈, 뺄셈, 곱셈, 나눗셈 연산 지시.
:: add dst, src : dst에 src의 값을 더합니다.
add eax, 3 | eax += 3 |
add ax, WORD PTR[rdi] | ax += *(WORD *)rdi |
:: sub dst, src: dst에서 src의 값을 뺍니다.
sub eax, 3 | eax -= 3 |
sub ax, WORD PTR[rdi] | ax -= *(WORD *)rdi |
:: inc op: op의 값을 1 증가시킴
inc eax | eax += 1 |
:: dec op: op의 값을 1 감소 시킴
dec eax | eax -= 1 |
논리 연산 - and & or
:: and dst, src: dst와 src의 비트가 모두 1이면 1, 아니면 0
:: or dst, src: dst와 src의 비트 중 하나라도 1이면 1, 아니면 0
논리 연산 - xor & not
:: xor dst, src: dst와 src의 비트가 서로 다르면 1, 같으면 0
:: not op: op의 비트 전부 반전
비교
: 두 피연산자의 값을 비교하고, 플래그를 설정
분기
: rip를 이동시켜 실행 흐름을 바꿈
- jmp addr: addr로 rip를 이동시킨다.
- je addr: 직전에 비교한 두 피연산자가 같으면 점프 (jump if equal)
- jg addr: 직전에 비교한 두 연산자 중 전자가 더 크면 점프 (jump if greater)
스택
- push val: rsp를 8만큼 빼고, 스택의 최상단에 val을 쌓는다
- pop reg: 스택 최상단의 값을 reg에 넣고, rsp를 8만큼 더한다.
프로시저
- call addr: addr의 프로시저를 호출
- leave: 스택 프레임을 정리
- ret: 호출자의 실행 흐름으로 돌아김
시스템콜
syscall: 커널에게 필요한 동작을 요청
'Ping!_linux' 카테고리의 다른 글
Python 기초 문법 (2) (3) | 2024.03.16 |
---|---|
Python 기초 문법 (1) (1) | 2024.03.15 |
기본 명령어 및 vi 에디터 (0) | 2024.01.28 |
2. 리눅스 메모리 구조 (Linux Memory Layout) (0) | 2024.01.28 |
1. 컴퓨터구조 (0) | 2024.01.28 |