본문 바로가기
System_Security

05. 분기문,반복문

by Jnamelight 2017. 7. 24.

분기문


어셈블리에서는 분기문, 반복문이 차이가 없다. 

일단 분기문을 살펴보자. 분기문에는 대표적으로 if, switch 문이 존재한다.


우리는 IF 문만 알면 자연스럽게 switch 문도 알게된다. 


일단 분기문을 사용하기 위해서는 비교문을 알아야하는대


어셈블리어에서 비교문을 나타내는 명령어는 cmp 가 있다.


이것을 이용해서 if문을 표현할수가 있는대.


여기서 한가지 더 알아야하는 표현이 eflags 이다. flag는 cmp에서 나온 결과값을 저장해주는 역할을 하는대



결과 자체를 저장하는 것이아니라,


연산이 완료 되었을때 플레그의 값이 바뀌는 것을 이용하는 것이다.


1. 음수 : 2번째 인자가 더 크다.

   SF = 1

   ZF = 0


2. 양수 : 1번째 인자가 더 크다.


   SF = 0

   ZF = 0


3. 0 : 같다.


   SF = 0

   ZF = 1



이런식으로. 간단한 예제를 알아보자.



extern printf

segment         .data
int_prompt      db      '%d',10,00

segment         .bss

segment         .text
global          main

main:
        mov     eax,    20
        mov     ebx,    20

        cmp     eax,    ebx

        pushf
        push    int_prompt
        call    printf


여기서 pushf 를 이용 하면 플레그의 값을 push 할수 있다.

확인 결과 



582 라는 값이 나오고 이것을 비트로 표현하면 1001000110


 

위의 eflag 레지스트를 살펴보면 zero 플레그가 1로 되어있는 것을 확인 할수 있다.


즉 비교 결과 0이 나온것으로 똑같다 라는 뜻이된다.


주의할점은 문자열 비교는 불가능하다이다. 

어셈블리에서는 문자열을 시작주소로 넘겨서 읽어들이기 때문에, 적으로는 주소비교가 된다..! 


그럼 cmp 를 비교해서 어떤식으로 값을 비교해서 넘기는지 알아볼려면

조건 분기문( 자주 사용하는 ) 것들을 외우던가, 찾아야하는대, 몇개만 외우고 나머지는 찾아보는것이 좋다.


	je	jz 	 //두개 같음
	jne	jnz	// 두개 같음 
			
	jg		//크다
	jge	
	jng

	jl		//작다
	jle
	jnl


자주 사용되는 명령어인대 그냥  n 이 붙으면 not 즉 아니다 라는거


l 은 작다

g 는 크다

e 는 같다 만 알면된다.


실전예제

C 로된 표현을 한번 어셈블리로 해보자.

if (eax > 10 )
	   ecx++;



어셈블리


extern printf
extern scanf

segment         .data
msg     db      '%d',10,00
pr      db      'no',10,00
rd      dd      '%d',00

segment         .bss
num     resd    1

segment         .text
global  main

main:
        push    num
        push    rd
        call    scanf


        mov     eax,    dword [num]
        mov     ecx,    0

        cmp     eax,    10
        jle     nnnn


        inc     ecx
        push    ecx
        push    msg
        call    printf
        jmp     yyyy

nnnn:
        push    ecx
        push    msg
        call    printf

yyyy:

이런식으로 표현이 가능하다, 이게 정답은 아니다, 이건 프로그래머 취향이기 때문에 정답은 없지만


어떤식으로 동작하는지 이해가 중요하다.



더 어려운 분기문도 가능하다.


C


if ( eax == 0 || ebx >=1 || ecx < 2)
	edx = 1
else
	edx = 0 

어셈블리




extern printf
extern scanf

segment         .data
pr      db      '%d',10,00
rd      dd      '%d %d %d',00

segment         .bss
num1    resd    1
num2    resd    1
num3    resd    1


segment         .text
global  main

main:

        push    num3
        push    num2
        push    num1
        push    rd
        call    scanf

        mov     eax, dword [num1]
        mov     ebx, dword [num2]
        mov     ecx, dword [num3]
        mov     edx,    0

        cmp     eax,    0
        je      yyyy

        cmp     ebx,    1
        jge     yyyy

        cmp     ecx,    2
        jl      yyyy

        mov     edx,    0
        push    edx
        push    pr
        call    printf
        jmp     nnnn


yyyy:
        mov     edx,    1
        push    edx
        push    pr
        call    printf

nnnn:





'System_Security' 카테고리의 다른 글

07. 메인 함수  (0) 2017.08.01
06. 프로세스 메모리 구조  (0) 2017.07.26
04. 비트연산자 & 형변환  (0) 2017.07.20
03. 어셈블리 사칙연산  (0) 2017.07.19
02. 레지스트 개념  (0) 2017.07.15

댓글