8051( 중급 3부 - 함수 ) |
이번 강좌는 8051 C 에서 함수 사용 방법에 대한 내용이다.
일반 PC에서의 C 프로그래밍이라면 그다지 신경을 쓰지 않아도 될 사항들이지만 8비트 마이컴으로 작성하
는 C 프로그래밍에서는 최종적으로 생성될 코드의 크기와 프로그램 수행 속도를 생각치 않을수 없다.
정수형 두수의 합에 대한 프로그램을 생각해 보기로 하자.
정수형( integer - 발음 주의 )은 2바이트의 변수이다.
먼저 다음과 같은 프로그램이 있다고 하자. ( main1.c )
#include |
이 프로그램을 컴파일 해보자.
결과는 다음과 같다.
5 void main( void ) { \ 0000 main: 6 int a, b, c; 7 a = 100; \ 0000 750000 MOV $LOCBD main,#0 상위 바이트 \ 0003 750064 MOV $LOCBD main+1,#100 하위 바이트 8 b = 257; \ 0006 750001 MOV $LOCBD main+2,#1 상위 바이트 \ 0009 750001 MOV $LOCBD main+3,#1 하위 바이트 9 c = a + b; \ 000C E500 MOV A,$LOCBD main+1 \ 000E 2500 ADD A,$LOCBD main+3 하위 바이트끼리 더한다 \ 0010 F500 MOV $LOCBD main+5,A 하위 바이트의 연산 결과 저장 \ 0012 E500 MOV A,$LOCBD main \ 0014 3500 ADDC A,$LOCBD main+2 상위 바이트끼리 더한다 \ 0016 F500 MOV $LOCBD main+4,A 상위 바이트의 연산 결과 저장 10 } \ 0018 22 RET \ 0019 END |
그런데 우리의 고민은 모든 프로그램을 main 함수 안에 죄다 넣어둘수 없다는 야그다.
C 프로그램에서는 main 함수는 항상 있어야 하고 단 하나만 존재 해야 한다.
그래서 자주 사용하는 공통되는 기능을 따로 떼어내 하나의 함수로 만든다.
그럼 다음 프로그램을 보기로 하자.
#include |
위 프로그램을 컴파일 해보자.( main2.c )
5 int Add( int add1, int add2 ) { \ 0000 Add: 6 return add1 + add2; \ 0000 EF MOV A,R7 변수가 내부 레지스터에 할당( xdata가 아니므로) \ 0001 2500 ADD A,$LOCBD Add+3 하위 바이트의 덧셈 \ 0003 FF MOV R7,A 하위 바이트 덧셈 결과 저장 \ 0004 E500 MOV A,$LOCBD Add+2 \ 0006 3E ADDC A,R6 상위 바이트의 덧셈 \ 0007 FE MOV R6,A 상위 바이트의 덧셈 결과 저장 7 } \ 0008 22 RET 8 void main( void ) { \ 0009 main: 9 int a, b, c; 10 a = 100; \ 0009 750000 MOV $LOCBD main,#0 \ 000C 750064 MOV $LOCBD main+1,#100 11 b = 257; \ 000F 750001 MOV $LOCBD main+2,#1 \ 0012 750001 MOV $LOCBD main+3,#1 12 13 c = Add( a, b ); \ 0015 850000 MOV $PRMBD Add+2,$LOCBD main+2 \ 0018 850000 MOV $PRMBD Add+3,$LOCBD main+3 \ 001B AF00 MOV R7,$LOCBD main+1 \ 001D AE00 MOV R6,$LOCBD main \ 001F 120000 LCALL $REFFN Add \ 0022 8E00 MOV $LOCBD main+4,R6 Add 함수의 리턴값(상위바이트) \ 0024 8F00 MOV $LOCBD main+5,R7 Add 함수의 리턴값(하위바이트) 14 } \ 0026 22 RET 15 \ 0027 END |
main1.c 보다는 훨씬 복잡해졌다. 다만 계속되는 프로그램내에서 공통될수 있는 기능을 함수로 독립 시킨것이다.
함수를 사용할때는 서로 전달하고 전달 받아야 되는것들 때문에 프로그램 길이도 길어지고 그 만큼 수행 속도도 저하 된다.
그러면 어떻게 해야 최종으로 코딩된 프로그램 용량도 줄이고 수행 속도도 향상 시킬것인가?
그것이 마이컴 프로그래머의 고민거리이다. 한정된 메모리 크기에 죄다 집어 넣어야 하는데다
실시간에 시간 낭비 없이 프로그램이 돌아줘야 하는 상황도 봉착하게 되기 때문이다.
프로그램에는 정답이 없다. 달리 말하면 정답은 무수히 많다. 결과가 맞으면 되기 때문이다.
하지만 프로그램다운 프로그램이 되려면 다음과 같은 사항을 명심하라. 이것은 산적이 주장하는 거다.
1. 누가 보아도 쉽게 이해 할수 있게 프로그램을 작성하라.
한눈에 보아 쉽게 이해 될수 있어야 남들도 이해하기 쉽고 자신도 자신이 파놓은 함정에서 헤어나기 쉽다.
프로그램 길이만 길지 너저분하게 줄래 줄래 빨래 널듯이 기능을 널어 놓은 프로그램은 프로그램이 아니다.
보다 함축적으로 함수를 정리 하고 체계적인 방법들을 이용하라.
2. 함수에서 또다른 함수 호출을 하는 경우 세단계 이상을 넘지 않도록 하라.
위 프로그램( main2.c )를 보면 main 함수에서 Add 함수를 호출 했다.
기능을 구현하기 위해서는 다시 Add 함수에서 다른 함수를 호출 할수 있다.
보다 프로그램을 복잡하지 않게 하기 위해서는 가급적 그 이상의 함수 호출은 하지 말라는 야그다.
3. 전역 변수나 사용자 함수명은 첫문자를 대문자 처리 하라.
지역 변수와 전역 변수의 차이를 금방 알아 볼수 있고 사용자 함수와
라이브러리 함수와의 구분을 쉽게 할수 있어서 혼동을 피할수 있다.
4. 함수에 전달하는 인수나 리턴값을 가급적 줄여라.
위의 main2.c에서 보면 함수에 전달하는 인수를 위해 a 변수는 R6, R7에, b 변수는 다른 영역에 넣고
함수를 호출하고 그 결과 값을 다시 R6, R7로 되돌려 받는 방식을 취하고 있다.
main1.c 보다 복잡해졌다는것을 알수 있다. 그렇다고 함수 사용을 전혀 안할수는 없다.
그러므로 두개의 함수 이상에서 사용되는 변수는 전역 변수 처리해서 프로그램을 작성하면 보다 단순
해지고 그만큼 speed up을 시킬수 있다.( main3.c를 보면 알수 있다. )
위와 같은 내용은 C++ 이나 JAVA에서 주장하는 객체 지향과는 배치되는 내용이 많다.
하지만 상대적으로 낮은 speed와 메모리 한계를 느끼며 프로그램해야 하는 마이컴 땜쟁이들에게 권장하는 바이다.
그럼 위에 정한 규칙에 의해 다시 프로그램을 정리해 보기로 하자.( main3.c )
#include |
위 프로그램을 컴파일 해보라. 눈으로만 공부하려고 달라들면 자신에게 남는게 없다. 직접 해보라.
항상 주장하는 말이지만 똥인지 된장인지 직접 맛을 보고 확인하라. 그게 엔지니어의 철칙이다.
똥을 하도 많이 찍어 먹어 봐서 입안이 구리면 산적처럼 막걸리나 사묵어라. 산적은 사줄돈 음따.
컴파일하고서 main1.c, main2.c, main3.c간의 차이를 비교해보라.
출처 : 민이의 여행
<< 전자기기 개발 --- 건강기기, 통신기기,각종 전자회로 개발, PCB ARTWORK >>
'Programming > 8051' 카테고리의 다른 글
8051( 중급 6부 - RS485 ) (0) | 2009.11.29 |
---|---|
8051( 중급 5부 - pre-processor ) (0) | 2009.11.29 |
8051( 중급 4부 - define ) (0) | 2009.11.29 |
8051( 중급 2부 - C 프로그램 맛보기 ) (0) | 2009.11.29 |
8051( 중급 - 1부 ) (0) | 2009.11.28 |