일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- C언어
- 리눅스 커널
- pwncollege
- kernel
- 워게임
- 커널
- Leviathan
- css
- 시스템해킹
- radare2
- 알고리즘
- 시스템프로그래밍
- 시스템
- 어셈블리어
- 리버싱
- wargame
- 드론
- 리눅스
- 취약점
- write up
- px4
- Pwnable.kr
- 컴퓨터구조
- 프로그래밍
- 시스템 프로그래밍
- C++
- 리눅스커널
- Bandit
- pwn.college
- 시그널
- Today
- Total
Computer Security
#15 어셈블리 - 분기명령어 본문
프로그램 실행 흐름 제어
-IP(Instruction Pointer): 다음에 실행할 명령어의 (오프셋) 주소를 저장하는 레지스터
-IP의 값을 변경하여 프로그램의 흐름을 제어할 수 있다.
-프로세서는 이런 프로그램 제어를 위한 일련의 명령어들을 제공한다.(점프(무조건분기),조건부 분기, 서브루틴 호출명령어등등,,)
조건부 분기의 원리
-조건부 분기는 특정 조건에 따라 프로그램의 실행 흐름을 제어하는 명령어 집합을 의미한다.
-고급 언어의 if, while, for 등의 문법 구조를 구현할 때 조건부 분기 명령어를 사용한다.
-조건부 분기는 상태 플래그 값을 검사해서 분기 여부를 결정한다.
-기본적으로 조건 분기 명령어를 실행하기 전에 산술 및 논리 연산을 실행하지만, 두 값을 단순 비교하기 위해서 비교 명령어를 제공한다.
-비교 명령어는 기본적으로 뺄셈과 같은 효과를 내지만, 레지스터에 들어있는 데이터는 변경하지 않고 상태 플래그에만 영향을 미친다.
단거리, 근거리, 원거리 주소
-어셈블러는 현재의 주소로부터 떨어진 거리, 즉 변위(displacement)에 따라 세가지 유형의 주소를 지원한다.
1.단거리(short)주소: -128(80H)~127(7Fh) 바이트 까지의 거리에 제한(8비트 길이)
2.근거리(near)주소: 동일 세그먼트 내에서 -32768(8000H)~32767(7FFFH)바이트까지의 거리제한(16비트 길이)
3.원거리(far)주소: 동일 세그먼트 내에서 32K를 초과한 거리나 다른 세그먼트에 속한 주소
제어 명령어들의 거리에 대한 규칙
JMP : 단거리, 근거리, 원거리
Jnnn: 단거리, 근거리(80386+)
LOOP: 단거리
CALL: 근거리, 원거리
무조건 분기
JMP 명령어
-지정된 주소로 점프한다.
-단거리(1바이트), 근거리(2바이트) 및 원거리 주소를 지원한다.
-플래그: 아무것도 영향을 미치지 않는다.
JMP reg/mem
조건부 분기
-기본적으로 조건부 분기 명령어는 CPU의 상태 플래글르 검사하여 점프 여부를 결정한다.
-분기문을 실행하기 직전에 조건 검사가 필요한 산술 및 논리 연산을 수행하는 경우가 많다.(상태 플래그는 연산을 반영)
-두 값을 비교하는 가장 간단한 방법은 뺄셈이다.
-다음과 같이 op1에서 op2를 빼는 연산을 수행한다면, 그 결과값에 따라 두 값의 대소를 비교할 수 있을 것이다.
SUB op1, op2
결과: 양수 -> 상태: op1>op2 (상태플래그에 반영)
결과: 0 -> 상태: op1=op2
결과: 음수 -> 상태: op1<op2
비교 명령어
-x86을 포함한 다양한 프로세서들은 레지스터의 데이터를 변경시키지 않으면서도 뺄셈 연산을 한 것과 같은 효과를 상태 플래그에만 반영하는 비교 명령어를 제공한다.
CMP 명령어
-두 피연산자의 값을 비교한다. 플래그 값만 변경시키는 SUB 명령어와 같다.
-플래그:AF, CF, OF, PF, SF, ZF
CMP reg/mem , reg/mem/imm
대소 관계 CF SF ZF
op1>op2 0 0 0
op1=op2 0 0 1
op1<op2 1 1 0
동등 비교에 따르는 점프
JE 명령어: Jump if equal(op1 = op2)
-분기 조건: ZF=1
-플래그: 아무것도 영향을 미치지 않는다.
JE label
JNE 명령어: Jump if not equal (op1 /= op2)
-분기 조건: ZF=0
-플래그: 아무것도 영향을 미치지 않는다.
JNE label
JC 명령어: Jump if carry
-분기조건: CF=1
-플래그: 아무것도 영향을 미치지않는다.
JC label
JNC 명령어: Jump if not carry
-분기조건: CF=0
-플래그: 아무것도 영향을 미치지 않는다.
JNC label
JZ 명령어: Jump if zero
-분기조건: ZF=1
-JE와 동일
-플래그: 아무것도 영향을 미치지 않는다.
JZ label
JNZ명령어: Jump if not zero
-분기조건: ZF = 0
-JNE와 동일
-플래그: 아무것도 영향을 미치지 않는다.
JO 명령어: Jump if overflow
-분기조건: OF=1
-플래그: 아무것도 영향을 미치지 않는다.
JO label
JNO 명령어: Jump if not overflow
-분기조건: OF=0
-플래그: 아무것도 영향을 미치지 않는다.
JNO label
JS 명령어: Jump if sign (연산의 결과값이 부호비트(SF)가 음수(1)이면 점프)
-분기조건: SF=1
-플래그: 아무것도 영향을 미치지 않는다.
JS label
JNS 명령어: Jump if not sign
-분기조건: SF=0
-플래그: 아무것도 영향을 미치지 않는다.
JNS label
JP 명령어: Jump if even parity (짝수 페리티)
-분기조건: PF=1
-플래그: 아무것도 영향을 미치지 않는다.
JP/JPE label
JNP 명령어: Jump if odd parity (홀수 페리티)
-분기조건: PF=0
-플래그: 아무것도 영향을 미치지 않는다.
JNP/JPO label
부호 없는 비교에 따르는 점프
JA 명령어: Jump if above (op1>op2)
-분기 조건: CF=0, ZF=0
-JNBE와 동일
-플래그: 아무것도 영향을 미치지 않는다.
JA label
JAE 명령어: Jump if above or equal (op1 >= op2)
-분기 조건: CF=0
-JNB와 동일
-플래그: 아무것도 영향을 미치지 않는다.
JAE label
JNA 명령어: Jump if not above (op1<=op2)
-분기 조건: CF=1 or ZF=1
-JBE(below or equal)와 동일
-플래그: 아무것도 영향을 미치지 않는다.
JNA label
JNAE 명령어: Jump if not above or equal (op1 < op2)
-분기 조건: CF=1
-JB(below)와 동일
-플래그: 아무것도 영향을 미치지 않는다.
JNAE label
JB 명령어: Jump if below(op1<op2)
-분기조건: CF=1
-JNAE와 동일
-플래그: 아무영향 x
JB label
JBE 명령어:Jump if below or equal(op1<=op2)
-분기조건: CF=1 or AF=1
-JNA와 동일
-플래그: 아무영향 x
JBE label
JNB 명령어: Jump if not below(op1>=op2)
-분기조건: CF=0
-JAE와 동일
-플래그: 아무영향 x
JNB label
JNBE 명령어:Jump if not below or equal(op1>op2)
-분기조건: CF=0, AF=0
-JA와 동일
-플래그: 아무영향 x
JNBE label
부호 있는 비교에 따르는 점프
JG 명령어: Jump if greater(op1>op2)
-분기조건:ZF=0, SF=OF
-JNLE 와 동일
-플래그: 아무영향 x
JG label
JGE 명령어: Jump if greater or equal(op1>=op2)
-분기조건: SF=OF
-JNL과 동일
-플래그: 아무영향x
JGE label
JNG 명령어: Jump if not greater(op1<=op2)
-분기조건:ZF=1 or SF /=OF
-JLE 와 동일
-플래그: 아무영향 x
JNG label
JNGE 명령어: Jump if not greater and not equal(op1<op2)
-분기조건: SF/=OF
-JL과 동일
-플래그: 아무영향 x
JNGE label
JL 명령어: Jump if less(op1<op2)
-분기조건: SF/=OF
-JNGE와 동일
-플래그:아무영향 x
JL label
JLE 명령어: Jump if less or equal(op1<=op2)
-분기조건: ZF=1 or SF<=OF
-JNG와 동일
-플래그:아무영향 x
JLE label
JNL 명령어: Jump if not less(op1>=op2)
-분기조건: SF=OF
-JGE와 동일
-플래그:아무영향 x
JNL label
JNLE 명령어: Jump if not less and not equal(op1>op2)
-분기조건: ZF=0, SF=OF
-JG와 동일
-플래그:아무영향 x
JNLE label
루프 명령어
-고급언어의 for, while 등의 반복문은 분기 명령어와 비교 명령어를 조합하여 구현할 수 있다.
-x86은 루프 카운터(CX,ECX(386+))를 자동 감소 시키는 루프 명령어를 별도로 제공한다.
-루프 명령어 역시 일종의 분기문이라고 할 수 있다.
-x86은 루프 카운터로 CX레지스터 또는 ECX(80386+) 레지스터를 사용한다.
LOOP명령어
-CX는 루프 카운터로서 루프 횟수를 지정할 때 사용한다.
-LOOP 명령어는 매 루프마다 루프 카운터 CX를 1씩 자동 감소시킨다.
-80386이상에서 LOOP는 CX를 16비트 모드에서, ECX를 32비트 모드에서 사용한다.
-레이블로 지정 가능한 주소는 단거리 주소(-128~127)로 제한된다.
-플래그: 아무영향 x
LOOP label
-LOOPW는 16비트 CX를 지정하고, LOOPD는 32비트 ECX를 지정할 수 있다.
MOV CX, loop_count
LOOPW label
W(Word) 의 W사용
MOV ECX, loop_count
LOOPD label
D(Double word) 의 D사용
LOOPE/LOOPZ 명령어
-LOOP 명령어와 다르게 CX가 0인지 검사하는 대신, ZF=1 인지를 검사한다.
-플래그: 아무영향 x
LOOPE / LOOPZ label
LOOPNE/LOOPNZ 명령어
-LOOPE/LOOPZ와 반대로, ZF=0 인지를 검사한다.
-플래그: 아무영향x
LOOPNE/LOOPNZ label
ex)
.model small
.stack 100h
.data
arr1 db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
arr2 dw 197, 254, 242, 236, 326, 627, -1
sum1 db 0
sum2 db 0
.code
main proc
mov ax, @data
mov ds, ax
mov ax, 0
mov ax, 0 // ax : 합을 저장할 레지스터로 사용
lea si, arr1 //si는 arr1의 주소를 가져옴
mov cx, 10
arrSum1:
add al, [si] // si = arr1 인상태에서 al안에 si 0번째인 1 추가
inc si // si 1증가
loop arrSum1 //cx 가 10이므로, arrSum1 로 다시 돌아가면서 1감소 : cx=9 ... 반복 cx=0까지)
//10회 실행되면 결과 값 : al = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
mov sum1, al // al을 sum1에 넣어준다.
mov ax, 0 //ax : 합을 저장할 레지스터로 사용 초기화
lea si, arr2 //si는 arr2의 주소를 가져옴
arrSum2:
add ax, [si] //si의 0번째 index 197 을 ax에 추가
add si, 2
//si 의 주소값 2씩 증가 (arr2는 Word이므로 2바이트 증가는 옆으로 한칸씩 값나옴. 197->254. db에서 inc랑 같은 역할)
mov bx, [si] // 현재 si 값 부분을 bx에 넣는다.
cmp bx, -1 //bx= -1이 되면(si 값이 -1) , 즉 루프로 회전하다가 si 값이 -1이 되면 멈춤
loopne arrSum2 //조건 검사 루프 명령어 (loop not equal) si가 -1이 아니면 루프를 돌린다.
mov sum2, ax
//결과 값 : sum2 = [197, 254, 242, 236, 326, 627, -1]
'컴퓨터구조&어셈블리어' 카테고리의 다른 글
#17 어셈블리어 예제 (0) | 2022.06.02 |
---|---|
#16 어셈블리어-스택과 프로시저 (0) | 2022.05.30 |
#14 산술 및 논리 연산 명령어2 (0) | 2022.05.28 |
#13 산술 및 논리 연산 명령어1 (0) | 2022.05.27 |
#12 컴퓨터의 데이터표현 2 (0) | 2022.05.26 |