본문 바로가기

Assembly

6-2강 - Conditional Processing 2 (conditional jump, loop)

2. Conditional Jumps

특정 register나 flag 조건을 만족하면 conditional jump instruction가 label로 branch

 

0) Examples:
- JB, JC jump to a label if the Carry flag is set.
- JE, JZ jump to a label if the Zero flag is set.
- JS jumps to a label if the Sign flag is set.
- JNE, JNZ jump to a label if the Zero flag is clear.
- JECXZ jumps to a label if ECX equals 0.

 

1) Flag에 의한 Jump

 

2) equality에 의한 Jump

 

3) unsigned comprision에 의한 Jump

4) signed comprision에 의한 Jump

 

4) unsigned comprision에 의한 Jump

 

5) 예시

1> 예시 1

가정 : unsigned EAX

cmp eax, ebx
ja Larger

eax > ebx → 왼쪽이 커서 JA 작동 → Larger로 이동

 

2> 예시 2

가정 : signed EAX

cmp eax, ebx
jg Greater

eax > ebx → 왼쪽이 더 커서 JG 작동 → Greater로 이동

 

3> 예시 3

가정 : unsigned EAX

cmp eax, Val1
jbe L1          ; below or equal

eax <= Val1 → 왼쪽이 작거나 같아서 JBE 작동 → L1으로 이동

 

4> 예시 4

가정 : signed EAX

cmp eax, Val1
jle L1          ; less or equal

eax <= Val1 → 왼쪽이 작거나 같아서 JLE 작동 → L1으로 이동

 

5> 예시 5

가정 : unsigned AX, Large라는 변수

	mov Large,bx
	cmp ax,bx
	jna Next
	mov Large,ax
Next:

ax > bx → 왼쪽이 오른쪽을 넘으므로 JNA 작동 X → Large에 큰 수인 ax 할당

ax < bx → 왼쪽이 오른쪽을 넘지 못하므로 JNA 작동 → NEXT label로 이동 (초기에 Large에 큰 수인 bx 할당되고 종료)

 

6> 예시 6

가정 : signed AX, Small이라는 변수

	mov Small,ax
	cmp bx,ax
	jnl Next
	mov Small,bx
Next:

bx > ax → 왼쪽이 오른쪽보다 작지 않으므로 JNL 작동 → NEXT로 이동 (초기에 Small로 작은 수인 ax가 할당되고 종료)

bx < ax → 왼쪽이 오른쪽보다 작으므로 JNL 작동 X → Small에 작은 수인 bx 할당

 

7> 예시 7

cmp WORD PTR [esi], 0
je L1

ESI가 가리키는 곳에 0이 들어 있다

→ 그러면 cmp에서 0과 0으로 같기 때문에

→ JE 작동

→ L1 label로 이동

 

8> 예시 8

test WORD PTR [edi], 1
jz L2

EDI가 가리키는 곳에 짝수가 들어 있다.

→ PTR [EDI](...0)와 1의 TEST 연산 결과 0이니 zero flag는 1로 설정 

→ JZ 작동

→ L2 label로 이동

 

9> 예시 9

and al, 00001011b   ; clear unwanted bits
cmp al, 00001011b   ; check remaining bits
je L1               ; all set? jump to L1

bit 0, 1, 3이 모두 켜져 있으면 L1으로 jump

 

3. Conditional Loop Instructions

1) LOOPZ, LOOPE

1> 사용 

LOOPZ destination

LOOPE destination

2> 논리

ECX = ECX - 1

if (ECX > 0 && ZF == 1 ) JUMP to destination 

array에서 주어진 조건을 만족하지 않는 첫 element를 찾을 때 유용하다.

3> counter

- 16 bit : CX

- 32 bit : ECX

- 64 bit : RCX

 

2) LOOPNZ, LOOPNE

1> 사용 

LOOPNZ destination

LOOPNE destination

2> 논리

ECX = ECX - 1

if (ECX > 0 && ZF == 0 ) JUMP to destination 

 

array에서 주어진 조건을 만족하는 첫 element를 찾을 때 유용하다.

3> counter

- 16 bit : CX

- 32 bit : ECX

- 64 bit : RCX

 

4> 예시 1

.data
array    SWORD -3, -6, -1, -10, 10, 30, 40, 4
sentinel SWORD 0

.code
    mov esi, OFFSET array
    mov ecx, LENGTHOF array
next:
    test WORD PTR [esi], 8000h  ; test sign bit
    pushfd                      ; push flags on stack
    add esi, TYPE array
    popfd                       ; pop flags from stack
    loopnz next                 ; continue loop
    jnz quit                    ; none found
    sub esi, TYPE array         ; ESI points to value
quit:

- [...] 는  ...이 가리키고 있는 값을 의미 => 즉, 맨 처음에는 -3을 의미한다.

- WORD PTR [esi] : [esi]의 값을 little endian order([esi]이므로 가장 끝 4자리가 온다.)에 따라 WORD 자료형으로 변환

- 8000h : 해당 음수 중 가장 작은 수

- TEST WORD PTR [esi], 8000h :

결국 이진수로 봤을 때 맨 끝자리(부호)가 0이면 (양수)

-> 연산 결과가 0이어서

-> zero flag = 1

-> loopnz next에서 zero flag=0 조건을 만족하지 못해

-> jnz quit으로 간다.

 

결국 이진수로 봤을 때 맨 끝자리(부호)가 1이면 (음수)

-> 연산 결과가 1이어서

-> zero flag = 0

-> loopnz next에서 zero flag=0 조건을 만족해서 양수가 나올 때까지 loop를 돈다.

 

5> 예시 2

.data
array SWORD 50 DUP(?)
sentinel SWORD 0FFFFh

.code
    mov esi, OFFSET array
    mov ecx, LENGTHOF array
L1: cmp WORD PTR [esi], 0
    pushfd
    add esi, TYPE array
    popfd
    loope L1
    jz quit
    sub esi, TYPE array
quit: