[어셈블리어(Assembly Language)]
어셈블리어란 프로그래밍 언어 중 하나로, 기계어와 함께 저급언어(Low-level Langauge)에 속한다.
0과 1로만 이루어진 기계어는 인간의 관점에서 이해하고 다루기 매우 어렵기 때문에 이를 보안하기 위해 개발되었으며, 기계어와 1대1로 대응한다는 특징이 있다. 고급언어와 마찬가지로 컴퓨터가 이해할 수 있도록 번역하는 과정을 거친다는 점에서 고급 언어와 기계어 사이에 있는 '중간 언어'라 불리기도 한다.
어셈블리어가 어렵다고 평가되는 것 중 하나가 CPU가 채택한 명령어셋(ISA)에 따르는 기계어와 1대1 대응을 하기 때문에 어셈블리어 역시 표준 규격화가 되어있지 않다는 것이다. 그 말인 즉슨, 문법 아키텍처와 CPU 아키텍처에 따라, 그리고 어셈블러의 종류에 따라 문법/매크로 등이 제각각이다.
[Intel 사의 마이크로 아키텍처]
x86과 x86_64 마이크로 아키텍처에서는 문법 아키텍처가 크게 인텔 방식과 AT&T 방식으로 나뉜다. 인텔 방식은 가독성이 뛰어나고, AT&T 방식은 가독성은 떨어지나, 인텔 방식보다 좀 더 많은 정보를 포함하고 있다.
보통 윈도우 플랫폼에서 사용하는 'IDE'들은 인텔 문법 기반의 어셈블러(NASM, MASM)을 기본으로 하는 경우가 많고, 리눅스에 기반한 오픈소스 진영에서는 스탠다드 컴파일러셋에 포함된 'GNU 어셈블러(GAS)'가 AT&T 방식을 사용하고 있다.
현재 공부하는 방향으로 보아 윈도우 플랫폼의 'IDE'를 주로 사용할 것 같아서 인텔 문법 위주로 정리해보았다.(수정 가능성 O)
1. Intel 어셈블리 기초(Intel 문법)
Intel문법에서의 어셈블리 명령어는 다음과 같은 구조를 하고 있다.
라벨: <명령어><피연산자1><피연산자2> ;주석
여기서 라벨은 기계어로 직접 번역되지는 않으며, jmp 명령어를 사용하거나 메모리 주소의 참조가 필요할 때 사용된다.
- 라벨: 명령어의 집합. 명령어 또는 데이터의 주소를 나타낸다.
- 명령어: mov, jmp 등의 동작을 지시한다.
- 피연산자: 명령어의 피연산자(operand), 레지스터, 숫자, 문자, 메모리 주소 등이 포함된다.
- 주석: 앞에 세미콜론(;)를 붙여 주석처리 한다.
1) 데이터 이동 명령: mov, push, pop, lea, movsx, movzx
2) 산술 및 논리 명령: add, sub, inc, dex, imul, idiv, and, or, xor, not, neh, shl, shr
3) 특수 명령어: rep, stosb, stosw, stosd,
4) 흐름 제어 명령: cmp, je, jne, jz, jnz, ja, jae, jna, jnae, jb 등
- Unsigned 계열(부호가 없는 값)
- je: jump equal - 비교 결과가 같을 때 점프
- jne: jump not equal - 비교 결과가 다를 때 점프
- jz: jump zero - 결과가 0일 때 점프, je와 같음(cmp 명령에서 결과가 같으면 0을 출력합니다).
- jnz: jump not zero - 결과가 0이 아닐 때 점프
- ja: jump above - cmp a, b에서 a가 클 때 점프
- jae: jump above or equal - 크거나 같을 때 점프
- jna: jump not above - 크지 않을 때 점프
- jnae: jump not above or equal - 크지 않거나 같지 않을 때 점프
- jb: jump below - cmp a, b에서 a가 작을 때 점프
- jbe: jump below or equal - 작거나 같을 때 점프
- jnb: jump not below - 작지 않을 때 점프
- jnbe: jump not below or equal - 작지 않거나 같지 않을 때 점프
- jc: jump carry - 캐리 플래그가 1일 때 점프
- jnc: jump not carry - 캐리 플래그가 0일 때 점프
- jnp/jpo: jump not parity / parity odd - 패리티 플래그가 0일 때 / 홀수일 때 점프
- jp/jpe: jump parity / parity even - 패리티 플래그가 1일 때 / 짝수일 때 점프
- jecxz: jump ecx zero - ecx 레지스터가 0일때 점프
- Signed 계열(부호가 있는 값)
- jg: jump greater - cmp a, b에서 a가 클 때 점프
- jge: jump greater or equal - 크거나 같을 때 점프
- jng: jump not greater - 크지 않을 때 점프
- jnge: jump not greater or equal - 크지 않거나 같지 않을 때 점프
- jl: jump less - cmp a, b에서 a가 작을 때 점프
- jle: jump less or equal - 작거나 같을 때 점프
- jnl: jump not less - 작지 않을 때 점프
- jnle: jump not less or equal - 작지 않거나 같지 않을 때 점프
- jo/jno: jump overflow / not overflow - 오버플로 플래그가 1일 때 / 0일 때 점프
- js/jns: jump sign / not sign - 사인(부호) 플래그가 1일 때(음수) / 0일 때(양수) 점프
4. Status Flags(상태 플래그): C, O, S, Z, A, P
https://dsearls.org/courses/C391OrgSys/IntelAL/8086_instruction_set.html - 각 명령어의 상세 설명/예시
https://riptutorial.com/x86/example/6976/flags-register - x86 상태 플래그 정리 사이트
[ARM 사의 마이크로 아키텍처]
arm, arm64 마이크로 아키텍처는 내부적으로 32bit의 데이터 버스와 32bit의 어드레스 버스를 제공한다. ARM는 대표적인 RISC 코어이며, 명령어의 종류가 적으면서도 다양하게 적용시킬 수 있다는 특징이 있다. intel CPU의 경우 명령어에 따라 대략 1~7byte까지 있는데, ARM는 모든 명령어를 한 Word(32bit)로 처리한다. (RISC의 특징)
Immediate 오퍼랜드를 지정할 경우 좀 번거롭고, 코딩 시에 몇몇 제한을 따르긴 하나, 모든 명령어를 같은 사이즈로 처리해 파이프라인 구현이 용이하며, 명령어 해석기를 설계할 경우 예회 처리부분이 없으므로 쉽고 고속으로 처리할 수 있다는 장점이 있다.
1. ARM 어셈블리 기초
ARM 어셈블리의 문법
OP Code<cond> Rd, Rn, Rm
OP Code: ADD, SUB, MOV, LDR, STR 같은 어셈블리 명령어.
cond: 조건부로 명령을 실행해야 할 경우 명령문의 추가 옵션.
Rd: Destination Register, Register R0~R15만 올 수 있다. 연산 작업의 결과값을 저장.
Rn: Operand1 Register, 반드시 Register R0~R15만 올 수 있다.
Rm: Operand2, 레지스터 뿐만 아니라 상수, 주소, 쉬프트 연산식 등 다양한 값을 사용한다.
다시 말해 Rd, Rn는 무조건 Register(R0~R15)만 올 수 있고 Rm은 상수(#), 주소([]), 쉬프트 연산식 등의 다양한 값이 사용될 수 있다.
ARM에서는 Rm이 ALU로 입력되기 전에 Barrel Shifter를 사용하여 시프트 연산을 끝낸 값을 ALU으로 입력할 수 있다.
1) 산술 연산: ADD, ADC, SUB, SBC, RSB, RSC
2) 비트 연산(논리 연산): AND, ORR, EOR, BIC
3) 대입 연산: MOV, MVN
4) 비교 연산: CMP, CMN, TST, TEQ
5) 분기 명령: B, BL
6) 메모리 접근 명령: LDR, STR
7) 상태 플래그: N, Z, C, Z
- N: 연산 결과가 음의 값을 가질 경우
- Z: 연산 결과가 Zero인 경우
- C: 연산 결과가 Carry를 가질 경우
- V: 연산 결과에 Overflow가 발생한 경우
참고자료
'System & Reversing > 필기' 카테고리의 다른 글
dll 파일이란? (+ lib과의 차이점) (0) | 2023.03.10 |
---|---|
어셈블리 핸드레이와 함수 프롤로그/에필로그(+ 스택 프레임) (0) | 2023.03.10 |
메모리 구조 (+ 일반PC, 임베디드 시스템) (0) | 2023.03.10 |
아키텍처의 개념, 종류, 특징(통합본) (0) | 2023.03.10 |
프로그램 언어의 종류(기계어, 저급언어, 고급언어) (0) | 2023.03.09 |