[C++]_S1-08_분기문

신치우·2023년 12월 10일

CPP

목록 보기
8/62

분기문 (if)
특정 조건에 따라서 코드 흐름을 제어하는 것
ex) 스킬 버튼을 눌렀는가? YES -> 스킬 사용
ex) 제한 시간 내에 던전 입장 수락 버튼을 눌렀는가? Yes -> 입장, No -> 던전 취소
분기문과 반복문으로 코드의 대다수를 만들 수 있다.

분기문을 위한 어셈블리 함수
CMP dst, src
비교를 한 결과물은 Flag Register에 저장
JMP [label] 시리즈
JMP : 무조건 jump
JE : JumpEquals 같으면 jump
JNE : JumpNotEquals 다르면 jump
JG : JumpGreater 크면 jump
JGE : JumpGreaterEquals 크거나 같으면 jump
JL : JumpLess 작으면 jump
JLE : JumpLessEquals 작거나 같으면 jump

위 함수를 이용해 rax와 rbx를 비교하는 코드를 작성했다. cmp를 통해 0이면 LABEL_EQUAL로 점프하고 그렇지 않으면 LABEL_EQUAL_END로 바로 점프하는 코드이다.
결과를 보면 1이 출력된 것을 알 수 있고, 이는 조건을 만족해서 LABEL_EQUAL 을 탔다는 의미이다. 디버그 모드에서 확인하면 eflags에 ZF (PF, IF는 배우는대로 추가 하도록 하겠다.) 가 켜져있는 것을 확인할 수 있다. 0x246bin형태로 변환후 elag register와 비교하면 ZF1로 켜져있는 것을 확인할 수 있고, bin형태에 맞춰 IF, PF가 같이 켜져있는 것을 확인할 수 있다.

연습 문제 : 어떤 숫자가 (1~100)가 짝수면 1, 홀수면 0을 출력하는 프로그램 작성

    GET_DEC 1, ax
    mov bl, 2
    div bl
    
    cmp ah, 1
    je LABEL_ODD
    mov rcx, 1
    
    jmp LABEL_ODD_END
    
LABEL_ODD:
    mov rcx, 0
LABEL_ODD_END:
    PRINT_HEX 1, rcx
    NEWLINE  

위 코드는 힌트를 듣기전에 작성한 코드이다.

정상 동작하는 것을 확인했고 여기에 추가로 주어진 숫자가 1~100 범위 안에 포함되지 않는 경우를 추가해봤다.

    GET_DEC 1, ax
    
    cmp ax, 100
    jg LABEL_BIGGER_ERROR
    cmp ax, 1
    jl LABEL_SMALLER_ERROR
    mov bl, 2
    div bl
    
    cmp ah, 1
    je LABEL_ODD
    mov rcx, 1
    
    jmp LABEL_ODD_END
    
LABEL_BIGGER_ERROR:
    PRINT_STRING Bmsg
    NEWLINE
    jmp LABEL_END
    
LABEL_SMALLER_ERROR:
    PRINT_STRING Smsg
    NEWLINE
    jmp LABEL_END
    
LABEL_ODD:
    mov rcx, 0
LABEL_ODD_END:
    PRINT_HEX 1, rcx
    NEWLINE
    jmp LABEL_END

LABEL_END:
    xor rax, rax
    ret


section .data
    Bmsg db 'the input is bigger than 100', 0x00
    Smsg db 'the input is smaller than 1', 0x00

결과 :

모두 잘 작동하는 것을 확인할 수 있었다.

오늘은 여기까지
어셈블리든 뭐든 코드는 역시 직접 짜봐야 재미가 있다.
아니면 나머지를 한 것에 대해서 몫과 나머지를 이용해 100보다 크고 0보다 작은 숫자를 거르는 것도 하나의 방법일 수 있다고 생각했다. 다음에 적용해봐야겠다.

profile
https://shin8037.tistory.com/

0개의 댓글