BLOG
Tracefield · 02
Tracefield · 01
블로그 · 14
Vibe Audit · 04
Vibe Audit · 03
Vibe Audit · 02
Vibe Audit · 01
출판편집자 · 01
StudyTree · 01
SecurityOps · 02
SecurityOps · 01
AI챗봇 · 04
AI챗봇 · 03
AI챗봇 · 02
AI챗봇 · 01
퍼플심 · 04
퍼플심 · 03
퍼플심 · 02
퍼플심 · 01
블로그 · 13
rootscan · 07
rootscan · 06
블로그 · 12
블로그 · 11
블로그 · 10
블로그 · 09
블로그 · 08
블로그 · 07
블로그 · 06
블로그 · 05
블로그 · 04
블로그 · 03
블로그 · 02
블로그 · 01
rootscan · 05
rootscan · 04
rootscan · 03
asmspeak · 03
asmspeak · 02
rootscan · 02
asmspeak · 01
rootscan · 01
웹보안도구 · 02
웹보안도구 · 01
루트캠프 · 02
루트캠프 · 01
All notes 167
명령어 집합과 제어 흐름
어셈블리에는 if, while 같은 고수준 제어문이 없다. 대신 비교와 점프 명령을 조합해서 흐름을 만든다. 결국 분기 구조를 읽는 핵심도 이 두 개다.
1. 기본 명령어
먼저 자주 보는 기본 명령어부터 익히면 된다.
- MOV A, B: B 값을 A로 복사한다.
- ADD / SUB: 덧셈과 뺄셈을 수행한다.
- INC / DEC: 값을 1씩 증가시키거나 감소시킨다.
- LEA(Load Effective Address): 메모리 안의 값이 아니라 주소 자체를 계산한다. 포인터 계산이나 간단한 산술에 자주 쓰인다.
2. 분기문의 원리: CMP와 JMP
조건문은 보통 두 단계로 처리된다. 먼저 CMP로 플래그를 세팅하고, 그다음 Jcc 계열 명령으로 분기한다.
(1) 비교: CMP(Compare)
cmp rax, rbx
두 값의 차이(rax - rbx)를 계산하지만, 결과 자체를 저장하지는 않는다. 대신 RFLAGS 안의 상태 비트만 갱신한다.
- ZF(Zero Flag): 결과가 0이면, 즉 두 값이 같으면 1이 된다.
- SF(Sign Flag): 결과가 음수면 1이 된다.
Note: TEST 명령어와의 차이
리버싱을 하다 보면CMP대신TEST명령어가 자주 보인다. (예:test rax, rax)
CMP는 뺄셈 연산(-)을 통해 차이를 확인하지만,TEST는 논리곱(AND) 연산을 수행한다. 주로 "값이 0인지 아닌지" 또는 **"NULL 포인터 체크"**를 할 때CMP보다 효율적이라서 자주 사용된다.
(2) 분기: Jcc(Jump Condition)
Jcc 계열 명령은 플래그 상태를 보고 흐름을 바꾼다.
| 명령어 | 의미 | 조건 |
|---|---|---|
| JE | Jump if Equal | 값이 같을 때 (ZF=1) |
| JNE | Jump if Not Equal | 값이 다를 때 (ZF=0) |
| JG | Jump if Greater | 클 때 |
| JL | Jump if Less | 작을 때 |
3. If-Else 구현 패턴
고수준 언어의 if-else는 어셈블리로 내려오면 대체로 이런 모양이 된다.
cmp rax, 10
je is_ok ; 조건 만족 시 점프
; [Else 블록]
call fail
jmp finish ; 필수: 여기서 점프하지 않으면 아래 코드로 흘러내림(Fall-through)
is_ok:
; [If 블록]
call ok
finish:
; 종료
Else 블록 끝에 jmp가 없으면, 아래 is_ok 블록까지 그대로 흘러 들어가는 fall-through가 생길 수 있다. 제어 흐름을 읽을 때 이 점을 항상 봐야 한다.

