3.4) 프로그램 흐름 제어
다음은 CIL의 코드 제어 명령 중 하나인 점프문이다.
Jump.c |
#include "CIL.h" STRING sHello = "HelloWorld\n"; STRING sNice = "NiceToMeetYou\n"; STRING sBye = "GoodBye\n"; PROC(main) // main 프로시저의 정의가 시작되는 지점입니다.
PUSH(sHello) INVOKE(print_str)
JMP(label) // label 레이블로 점프합니다.
PUSH(sNice) INVOKE(print_str)
label: // label 레이블의 정의입니다.
PUSH(sBye) INVOKE(print_str)
ENDP // 프로시저의 정의를 마칩니다. |
실행 결과 |
HelloWorld GoodBye |
프로그램을 실행하면 JMP 문장이 실행된 지점과 label 레이블이 정의된 문장 사이의 명령이 모두 생략되었음을 알 수 있다. 이렇듯 JMP 문장은 C의 goto 명령과 같다(실제로 헤더에 그렇게 정의되어있다).
이제 CIL의 조건문을 보자.
Condition.c |
#include "CIL.h" PROC(main) // main 프로시저의 정의가 시작되는 지점입니다.
// a = 10, b = 20 MOVL(a, 10) MOVL(b, 20)
// a와 b를 서로 비교하고 결과를 flag에 저장합니다. CMP(a, b)
// a와 b의 차이가 0이 아니라면 elseif 레이블로 점프합니다. JNZ(lbl_elseif)
// elseif 레이블로 점프하지 않으면 a = 30을 수행한 후 MOVL(a, 30) // endif 레이블로 점프합니다. JMP(lbl_endif)
// elseif 레이블로 점프했다면 lbl_elseif: // a = 40을 수행합니다. MOVL(a, 40);
lbl_endif: PUSH(a) INVOKE(print_int)
ENDP // 프로시저의 정의를 마칩니다. |
CIL은 조건 분기할 때 플래그 변수를 참조한다. CMP 명령은 인자로 넘어온 두 값을 비교해서 결과를 플래그 변수에 저장하는데, 이떄 저장하는 정보는 두 값이 서로 같은지, 왼쪽이 더 큰지(부호)와 같은 것들이다. 이 예제에서는a와 b의 값이 서로 다르므로 lbl_elseif 레이블로 이동하고 a에는 40이 저장된다.
다음은 조건문과 점프문을 이용하여 구성한 반복문이다.
Loop.c |
#include "../CIL/CIL.h" STRING sNewLine = "\n"; STRING sEnd = "Program end\n";
PROC(main) // main 프로시저의 정의가 시작되는 지점입니다.
MOVL(c, 5); // c = 5
// 루프의 시작을 뜻하는 레이블을 정의합니다. loop_start:
// c의 값을 0과 비교합니다. CMP(c, 0);
// c가 0이라면 반복문을 탈출합니다. JZ(loop_end)
// c의 현재 값을 출력합니다. PUSH(c); INVOKE(print_int); PUSH(sNewLine); INVOKE(print_str);
// c-- DEC(c);
// 루프의 처음으로 되돌아가 반복문을 다시 실행합니다. JMP(loop_start);
// 루프의 끝을 뜻하는 레이블을 정의합니다. loop_end:
PUSH(sEnd); INVOKE(print_str);
ENDP // 프로시저의 정의를 마칩니다. |
실행 결과 |
5 4 3 2 1 Program end |
위 프로그램은 카운터 변수 C를 이용하여 5부터 0이 아닐 때까지 반복하여 수를 출력한다. 이 예제를 이해한다면C를 배울 때 연습하던 별 찍기와 같은 문제들도 모두 CIL을 이용해 해결할 수 있다. 심심할 때 연습 삼아 풀어보면 재미있을 것이다.