1. 서론
많은 프로그래밍 언어 중 단연 최고는 어셈블리어라고 생각한다.
그 이유는 우리가 여러 언어로 코딩을 하더라도 결국 컴퓨터가 알아들을 수 있는 기계어로 가기 전 어셈블리어를 거치기 때문이다.
2. 문법
어셈블리어는 다시 2가지 문법을 가지고 있다.
아래 테이블만 알면 충분하다.
Intel 방식 | AT&T 방식 | |
명령어 | mov | movb, movw, movl |
인자 순서 | dest, src | src, dest |
레지스터 | eax | %eax |
상수 | 0h | $0x0 |
간접 주소 | [eax] | (%eax) |
개인적으로 AT&T 방식이 조금 더 직관적이기에 이를 사용한다.
2. 명령어
아래 정도만 알면 충분하며, 이외에는 아래 기초 명령어에서 확장된 명령어라고 생각한다.
특징은 일단 참고만 하자.
2.1. 데이터 이동
2.1.1.MOV
- 형식 : MOV src, dest
- 기능 : src위치에 있는 데이터를 복사하여 dest위치에 저장
- 특징 1) 메모리와 레지스터 사이의 데이터 이동.
2) 레지스터와 레지스터, 값을 레지스터나 메모리에 대입할 때 사용.
3) src와 dest의 크기가 같아야 함.
**movs 또한 mov와 같은 기능을 하지만 movs는 String 데이터를 복사한다는 점에 차이를 둠.
2.1.2.LEA
- 형식 : LEA src, dest //Load Effective Address
- 기능 : src 오퍼랜드에서 지정된 주소를 dest로 로드
- 특징 1) src의 오퍼랜드는 메모리에 위치해야 함.
2) mov와 비교하여 메모리 주소 표현 및 레지스터에 대한 직접적인 연산이 가능.
2.2. 연산
2.2.1.ADD
- 형식 : ADD src, dest
- 기능 : dest에 src의 값을 더해서 그 결과를 dest에 저장.
- 특징 1) 메모리끼리 덧셈 불가
2) 연산 결과에 따라 ZF(Zero), OF(Overflow), CF(Code)가 세트가 될 수 있다.
2.2.2.SUB
- 형식 : SUB src, dest
- 기능 : dest에서 src를 뺀 다음 결과를 dest에 저장.
- 특징 1) 메모리끼리 뺄셈 불가
2) 연산 결과에 따라 ZF, OF, CF가 세트가 될 수 있다.
2.2.3.INC
- 형식 : INC dest
- 기능 : dest(피연산자)에 1을 증가시키고 결과값을 다시 저장.
- 특징 1) 레지스터와 메모리만 사용 가능
2) ZF, OF가 세트가 될 수 있다.
2.2.4.DEC
- 형식 : DEC dest
- 기능 : dest(피연산자)에 1을 감소시키고 결과값을 다시 저장.
- 특징 1) 레지스터와 메모리만 사용 가능
2) ZF, OF가 세트가 될 수 있다.
2.3. 흐름 제어
2.3.1.JMP
- 형식 : JMP proc
- 기능 : 프로그램의 흐름 바꾸기, proc주소로 가서 그곳의 명령어 실행
- 특징 1) 주로 if/else문이나 loop문에서 사용됨
2) 명령어들은 16비트, 32비트 또는 세그먼트 : 오프셋 포인터를 가진다.
3) 종류로는 상대, 조건부, 절대, 간접 레지스터 점프가 있다.
2.3.2.CMP
- 형식 : CMP src, dest
- 기능 : dest피연산자에서 src연산자를 묵시적으로 빼서 값을 비교한다.
- 특징 1) 뺀 값이 0일 경우 ZF가 1로 세트 되고, 다를 경우 0으로 세트 됨.
2) 처음 상태일 때는 NZ(Not Zero)로 ZF가 0이지만, 계산 값이 0일 경우 ZF가 1로 세트 되면서 NZ가 ZR로 변경됨.
3) 혼자 사용 X, 언제나 조건 점프 혹은 조건 이동 명령어와 함께 사용됨
**조건 점프 명령어 꼭 확인.
2.3.3.CALL
- 형식 : CALL target
- 기능 : 함수 호출 시 사용, 스택 상에 CS를 다음에 오는 명령의 오프셋 주소를 PUSH 하고 주어진 주소로 제어를 옮긴다. (EIP를 변경시킴)
**JMP와 다른 점 : CALL명령어는 되돌아올 return 주소를 스택에 저장함.
2.3.4.LEAVE
- 형식 : LEAVE
- 기능 : 호출된 함수에서 호출한 함수로 복귀 전 EBP를 호출한 함수의 EBP로 재 설정
- 특징 : ESP에 있는 값을 꺼내서(pop) EBP 레지스터에 할당하며, leave 명령어 하나로 아래 두가지 동작을 함.
MOV EBP, ESP
POP EBP
2.3.5.RET
- 형식 : RET
- 기능 : 호출된 함수에서 호출한 함수로 복귀
- 특징 : LEAVE 명령어와 함께 쓰이고, ESP에 있는 값을 꺼내서(pop) EIP 레지스터에 할당하며, ret 명령어 하나로 아래 두가지 동작을 함.
POP EIP
JMP EIP
2.4. 스택 조작
2.4.1.PUSH
- 형식 : PUSH dest
- 기능 : 스택이라는 공간에 메모리 저장
- 특징 : ESP레지스터도 워드 크기(4바이트)만큼 증가한다.
2.4.2.POP
- 형식 : POP dest
- 기능 : 스택 맨 윗부분(top)에서 하나의 워드를 꺼내고 바로 그 전의 데이터를 가리킴
- 특징 : ESP레지스터도 워드 크기(4바이트)만큼 감소한다.
2.5. 인터럽트
2.5.1.INT
- 형식 : INT //interrupt:일시중지
- 기능 : 소프트웨어 인터럽트를 발생시켜 운영체제의 서브루틴을 호출
- 특징 : 상수만 사용 가능하다.
2.5.2.NOP
- 형식 : NOP
- 기능 : 아무 일도 하지 않는 명령어, 리버싱 작업에서 목적에 따라 유용하게 사용
- 특징 : ESP레지스터도 워드 크기(4바이트)만큼 증가한다.
2.5.3.LOOP
- 형식 : LOOP reg
- 기능 : 반복하고자 하는 내용을 그룹화하고, LOOP명령어를 통해 반복 내용을 묶음
- 특징 : CX 레지스터를 사용, CX레지스터 값만큼 반복
2.6. 논리
2.6.1.AND
- 형식 : ADD src, dest
- 기능 : dest와 src 피연산자의 각 비트가 AND 연산됨
- 특징 : 각 비트가 모두 1일 때만 결과도 1이 됨
2.6.2.OR
- 형식 : OR src, dest
- 기능 : dest와 src 피연산자의 각 비트가 OR 연산됨
- 특징 : 하나의 비트라도 1이면 결과 값이 1이 됨. CF, OF, ZF플래그가 세트가 될 수 있음
2.6.3.XOR
- 형식 : XOR src, dest
- 기능 : dest와 src 피연산자의 각 비트가 XOR 연산됨
- 특징 1) 각 비트가 서로 다른 값일 때만 결과가 1, 같은 값이라면 결과는 0.
2) OF, CF가 0으로 세트가 되고 결과에 따라서 ZF가 1로 세트 될 수 있음.
'Tips & theory' 카테고리의 다른 글
House of force (0) | 2022.09.14 |
---|---|
linux에서 docker 기본 사용법 (0) | 2022.09.13 |
docker <-> host 파일 전송 (0) | 2022.09.06 |
system hacking을 위한 docker 설치 및 사용법 (0) | 2022.09.05 |
Return to csu (0) | 2022.09.05 |