MIPS 시뮬레이터의 버그

학교에서 컴퓨터구조 수업을 듣는 중입니다.
IA-32(교수님 표현을 빌리자면 걸레-_-) 구조가 아닌 간단한 MIPS 아키텍처에 대해 배우고 있는데 MIPS Instruction set 을 이용해서 간단한 ASM 프로그래밍을 과제로 내주셨기에 어제 열심히 했더랍니다. 시뮬레이터로는 PCSpim 이라고 하는 윈도우즈 기반(이 것부터 잘못일지도 몰라요-_-) 시뮬레이터를 썼습니다. SPIM 은 Unix/Linux 기반의 콘솔 환경에서 사용할 수 있는 도구입니다. PCSpim은 그를 윈도우즈의 GUI 환경으로 만든거구요.

그런데! 아무리해도 원하는대로 답이 안나오는 겁니다!

답이 안나오면 가장 먼저 의심하는건 접니다-_-;; PC는 거짓말을 하지 않잖아요?
이거 뭔가 이상하다고! 컴파일러가 잘못되었다고! 외쳐봐야 나중에 보면 결국 자기 탓이기 마련입니다.

그런데 어제는 아니더군요.(컴파일러는 아니니 그럴 수 있는 건지도 모르겠지만요~ 😉 )
코드를 열심히 들여다보고, 내 능력이 이 거 밖에 안되나~ 한숨도 쉬어보고, 다시 아무리 코드를 들여다보면서 돌려봐도 안되는 겁니다. 난감하더군요.
결국 차례차례 나눠서 한 스텝씩 진행해보았습니다. 자세히 한스텝씩 진행하며 살펴보니 이 PCSpim 이란 놈이 자기 멋대로 Stack Pointer Register 값을 바꿔버리고 있더군요. 그래서 $SP 의 값을 가지고 리턴하는 부분에서 엉뚱한 곳으로 리턴하면서 Exception을 툭툭 뱉어내고 있는 것이었습니다.

사용자 삽입 이미지
jump전의 $SP값

사용자 삽입 이미지
$SP값이 제멋대로 바뀌었다!

그래서 바로 리눅스로 재부팅하고! 우분투의 소스리스트에 있는 SPIM 을 설치하려고 했으나 제대로 동작하지 않길래 소스를 받아다가 소스 컴파일하고 설치를 했죠.

바로 결과가 나오더군요-_-… 아까운 제 3시간은 그렇게 흘러갔습니다. 버젼이 7.3이나 되는 놈이 이럴 줄은 몰랐답니다ㅠㅠ

추가 : 다른 컴퓨터에서는 제대로 돌아가길래 PCSpim을 재설치하고 다시 해보았는데도 안됩니다. 그래서 뭔가 이상하다 생각하고는 Simulator 메뉴의 Settings… 에 있는 옵션들을 건드려보았는데 Delayed Branches 와 Delayed Load를 체크상태로 두면 (제 노트북에서만) 제대로 동작하지 않습니다. 이게 어떤 역할을 하길래 $SP 값을 마구 바꾸는 건지 모르겠네요. 게시판에 질문을 올렸는데 답변이 오면 또 추가하도록 하겠습니다.

SW Engineering – 2007.3.13

Issues of professional responsibility

– Confidentiality
– Competence
– Intellectual property rights
– Computer misuse

ACM/IEEE Code of Ethics(윤리 강령)

1. Public
   SE shall act consistenty with the public interest.
2. Client and Employer
3. Product
   가능한한 표준에 맞춰 개발해야 한다.
4. Judgment
5. Management
6. Profession
7. Colleagues
fair, supportive
8. Self

Ethical dilemmas

What is a system?

System Categories

– Technical computer-based systems.

– Socio-technical systems.

Socio-technical system characteristics

– Emergent properties
– Non-deterministic
   같은 Input에 대해서 늘 같은 Output을 생성해내지 못한다.
– Complex relationships with organizational objectives
   시스템 자체의 요소만 영향을 미치지는 않는다.

Emergent properties

   – 시스템 전체의 특성
   – 컴포넌트간의 관계로서 발생하게 되는 특성
   – 처음 integration 후 평가하고 측정 가능

Examples of emergent properties

   – Volume : 시스템의 배열에 따라 달라진다.
   – Reliability : 하나하나는 Realible할 수 있지만 하나로 integration되었을 때는 서로간의 iinteration에 대해서 영향을 받으므로 전체적으로는 달라질 수 있다.

오픈소스?

개인적으로 오픈소스에 관심이 많습니다.
개발자라면 공개된 소스에 관심이 많은 것은 당연하겠죠.
저 역시 오픈 소스 커미터가 되었으면 하는 막연한 생각은 합니다. 일단 멋지지 않은가요? 😉

오픈 소스 애플리케이션을 쓰면서 소스코드에 주목하지 않는 것은 저 역시 마찬가지 입니다. 다만 뭔가 불편한 사항이 생겼을 때, 그리고 시간적 여유가 있을 때는 조금 다르죠.
오픈 소스 애플리케이션을 사용하다가 불편한 것이 있다면, 그리고 능력이 허락된다면, “에이~ 왜 이거 안돼!” 하면서 소스코드를 보면서 고쳐볼 수 있습니다.
제가 해본 유일한 경험은 우분투를 사용하면서 FTP 클라이언트인 gftp 프로그램의 파일이름의 원격인코딩이 제대로 적용되지 않는 것을 보고 gftp의 소스코드를 제맘대로 수정해서 원격인코딩을 구현해 본 것 뿐입니다.(나중에야 안 것이지만 비슷한 기능을 gftp 메일링 리스트에서 중국인이 패치한 것이 있다고 하더군요. 그래도 제 패치가 더 좋습니다. 😛 전 Upload & Download 시에도 원격 인코딩 설정에 맞춰서 파일이름을 변경하게 했거든요. 패치를 원 개발자에게 이메일로 보내긴 했습니다만, 코드의 품질 탓일까요? 반영되진 않는 것 같군요;;)

윗 글에서는 오픈 소스 커미터가 되어 보자고 권장하고 있습니다. 전체적인 질을 높이자는 것이죠. 찬성합니다! 저 역시 제 시간이 허락하는 한도 내에서 그렇게 하고 싶고, 막연히 생각하고 희망하는 “오픈 소스의 발전”에도 도움이 될 것 같아서 말이죠.(받은 만큼 돌려준다. 제 기본적인 마인드입니다.)

결론은 리눅스 또는 소프트웨어 개발에 관심이 있는 분들이라면 오픈 소스에 참여해 보시기를 저 역시 권하고 싶습니다.(일단 저부터 해야겠지만요; )

p.s : 윗 글의 제목과 글을 보았을 때 제목에서 나오는 오픈소스 코드가 가지는 의미는 없다는 것으로 오해할 만 하군요; 이에 관해서 KLDP 에 권순선님이 트랙백 하신 글에 달린 원 글 주인의 댓글을 인용합니다.

오픈소스코드 활용의 자유가 얼마나 큰 의미가 있고 중요하다는 것은 충분히 잘 알고 있습니다. 고객이나 주변 사람들에게 항상
그런 얘기를 하고 더 나아가 코드의 활용을 통해서 얻을 수 있는 가치가 얼마나 큰지에 대해서도 자주 강조하는 편입니다. 작년엔
마소에 “오픈소스의 소스코드는 개발자를 위한 숨겨진 보물이다”라는 내용의 글을 쓰기도 했습니다.

하지만 그런 얘기들이 점점 공허하게 느껴졌습니다.

오픈소스 제품의 사용자(많은 개발자들은 라이브러리나 프레임워크의 사용자입니다)들은 점점 자신이 사용하는 것이 오픈소스라는
것에 의미를 두지 않습니다. 소스코드의 존재여부 자체에 관심도 없습니다. Free/OSS라고 하면 대부분 “공짜”라는 것에만
관심을 둡니다.

반대로 소스코드가 뭔가 대단한 것을 줄 것이라는 환상에 빠져있는 사람도 많습니다.

의미라는 것은 결국 어떤 것이 가지는 “가치”라는 뜻입니다. 저는 의의(significance)가 없다고 한 것이 아니라
개개인에게 현실적인 의미(meaning)나 가치(value)가 없다고 얘기한 것입니다. 현실적으로 각종 차별이 견고하게 존재하는
한국에서 “평등”이라는 헌법조항이 무슨 의미가 있냐고 항변하는 것과 마찬가지 입니다. 물론 그 평등조항이 있기 때문에 넓게 보면
얼마나 큰 혜택을 받는지 알 수 있겠죠. 하지만 그것이 존재의미가 있다고 해서 현실에서 차별당하는 사람에게 “헌법에는 평등권이
있어”라고 얘기해주는 것이 현실적으로 무슨 유익이 있겠냐는 것입니다.

물론 극히 좁은 시각과 제한된 관점에서 나온 발언인 것은 인정합니다. 제 최근의 경험 때문에 그런 말을 꺼낼 수 밖에
없었습니다. 소스코드에 대해서 막연한 환상을 가지고 있다가 나중엔 그 존재 의미조차 부정할지도 모르는 사람들에게 좀 더
“현실적”이 되자는 얘기였습니다.

그리고 진정한 그 존재 의미를 이해하고 그 가치를 누리며 적극적으로 활용하는 소수의 사람들이 있겠죠. 그들을 무시한 것은 절대 아니기에 저는 이 포스트의 제목에 고쳐 쓰신 것처럼 “아무” 의미가 없다라고는 하지 않았습니다.

마지막으로 오픈소스의 소스코드는 저한테는 개인적으로는 큰 의미가 있습니다. 저는 그 가치를 충분히 누리고 있고 그 점에
대해서 항상 감사하게 생각하고 있습니다. 하지만 이제는 다른 사람에게 그렇게 너도 하라고 “강요”할 욕심은 버렸습니다.

C 코드 최적화에 관한 글

C 코드 최적화

ARM 기반의 C 코드 최적화에 대해서 다루었다고 합니다.
저 개인적으로는 회사에서 했었던 프로젝트에 적용했던 것들이 몇 개 눈에 띄네요.
17번 같은 경우는 정말 독특하군요~ 저런 방법이 있을 줄이야!
나머지들도 특정 상황에서는 꽤 도움이 될 듯 싶어 블로그에 남겨둡니다.

관심있으신 분들은 한 번쯤 읽어보세요~!
답글에 오하라 님이 남겨주신 글도 꼭 한번 봐야겠군요. 🙂

int. 하면 무엇이 떠오르시나요?

int. 하면 뭐가 떠오르시나요?

문득 한컴 사전을 띄워놓고 코딩작업을 하던 중에(한컴 사전은 마우스 포인터 위치에 있는 문자열의 사전적 의미를 보여줍니다.) 한컴 사전에 int. 의 뜻에 대해서 나오고 있더군요.

한컴 사전에서 int.에 대해서 보여주는 것은 다음과 같습니다.

int.
interest; interim; interior; interjection; internal; international; interpreter; intransitive.

저는 Machine-dependent 한 정수 자료형이 떠오릅니다만, 여러분들은 어떤 것이 떠오르시나요?(마지막에 붙은 .은 잠시 접어두죠. 😉 )

변수 초기화의 중요성

변수를 선언하고 정의할 때 초기값을 넣어 초기화한다.

기본 중의 기본입니다. 이 말을 왜 하는가 하면-_-;;

아르바이트로 VC 6로 프로그램을 하나 작성중인데 DEBUG 모드에서는 없던 문제들이 RELEASE 모드에서 빌드한 후에 마구 터져나오더군요;
역시나 쓰기전에 초기화하지 않은 변수들때문이었죠.

한가지는 윈도우 크기를 콤보박스의 선택에 따라 바꾸는 기능을 넣고 싶어서 원래 창의 크기를 m_Rect 에 기억시켜뒀다가 선택에 따라 m_Rect.Height() <-> m_Rect.Height() + 30 으로 창의 높이를 변경하려고 했습니다. 헤더에 CRect m_Rect; 를 선언하고 다음과 같이 작성했죠.

   CRect rect;
   GetWindowRect(&rect);
   if(m_Rect.Height() == 0)    {
       m_Rect = rect;
   }

이게 제대로 동작하려면 당연히 초기에 m_Rect.Height() 가 0이어야합니다.(!)
생성자에 넣어야지. 라고 생각하고 까먹었던거죠(…) 이게 없던 결과로 m_Rect.top 과 m_Rect.bottom 에는 -8203…어쩌고 하는 값이 들어가서 윈도우가 안보이더군요. 전 프로그램이 뻗은 줄 알았어요-_- DoModal() 로 띄워둔 창은 안보이고 아래 윈도우에 Focus() 가 가지 않고 모든 입력을 거부하고 있으니 어디서 무한루프를 도나? 하고 생각했던거죠.
이 문제는 생성자에 다음을 넣음으로써 간단히 해결됐습니다-_-

   m_Rect.top        = 0;
   m_Rect.bottom    = 0;

또 다른 문제는 같은 역할을 하는 double형 값을 입력받는 Edit 창 10개를 만든 후 개수에 따라 Visible 한 Edit의 개수를 변경해서 값을 입력받는 것이었습니다. 먼저 헤더에

   double    m_dDip[10];
   double    m_dDipDirection[10];

과 같이 선언하고, DoDataExchange 변수에

   DDX_Text(pDX, IDC_EDIT_JOINT_DIP01, m_dDip[0]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP02, m_dDip[1]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP03, m_dDip[2]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP04, m_dDip[3]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP05, m_dDip[4]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP06, m_dDip[5]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP07, m_dDip[6]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP08, m_dDip[7]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP09, m_dDip[8]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP10, m_dDip[9]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP_DIRECTION_01, m_dDipDirection[0]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP_DIRECTION_02, m_dDipDirection[1]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP_DIRECTION_03, m_dDipDirection[2]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP_DIRECTION_04, m_dDipDirection[3]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP_DIRECTION_05, m_dDipDirection[4]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP_DIRECTION_06, m_dDipDirection[5]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP_DIRECTION_07, m_dDipDirection[6]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP_DIRECTION_08, m_dDipDirection[7]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP_DIRECTION_09, m_dDipDirection[8]);
   DDX_Text(pDX, IDC_EDIT_JOINT_DIP_DIRECTION_10, m_dDipDirection[9]);

와 같은 코드를 작성했더랍니다.

근데 다이얼로그를 띄우면 “숫자를 입력하세요” 란 메시지가 나타나면서 IDOK를 거부하는 겁니다-_- 역시나 멤버 변수의 값들의 초기화 문제 때문이었습니다.
이문제도 생성자에 다음을 넣어서 간단히 해결되었습니다-_-

   int i = 0;
   for(i = 0; i < 10; i++)    {
       m_dDip[i]            = 0;
       m_dDipDirection[i]    = 0;
   }

아고.. 암튼 삽질의 연속입니다. 역시 기본을 충실히 지키지 않으면 언젠가 댓가가 따르는 법입니다. 전 그 댓가로 3시간 자고 일어나서 전화받고 깨서 버그 잡고 있습니다. ㅡㅜ

OpenDWG 라이브러리 참고?

학교 토목과 랩의 동아리 선배의 의뢰로 프로그래밍 아르바이트를 하고 있는 중입니다.
이제 시작하는 단계인데 AutoCad 의 DWG 포멧을 읽어서 정보를 얻어달라고 하시네요.
저는 CAD 프로그램은 전혀, 하나도 다룰 줄 모릅니다;
선배님의 친구분이 그 비슷한 업무를 하셨다고 하시는데 소스포지의 자료를 참고해서 하셨다고 전해들으셨답니다. 전화상으로 거기 있는 것을 참고하면 별로 어렵지 않을 것이라고 하시더군요.

제가 지금까지 소스포지에서 찾아본 것으로는 OpenDWG 라는 DWG 포멧을 다루는 라이브러리를 사용한 프로그램이 있더군요. OpenDWG 사이트를 가보니 크게 네 종류의 멤버로 구분하고 있고 Associate member를 제외한 나머지는 비용을 내야 하는 것으로 되어 있네요.

일단 Associate member로 신청해놓았습니다만 양식을 채워서 다시 보내야할지 말아야 할지 고민이 됩니다.(다운로드 할 수 있는 양식을 채워 이메일이나 팩스로 다시 보내야만 최종 회원으로 승인됩니다.) 제가 하는 것은 아르바이트이지만 랩 내에서만 쓰이는 프로그램 같지는 않고 어느 곳의 프로그램을 제작해주는 형식이지 않을까 하는데 그렇게 되면 라이센스 문제를 피할 수 없겠죠.(Associate member는 educational이나 free형식의 사용만 가능한 것으로 이해했습니다.)

또 다른 고민으로는 과연 오픈소스 프로그램을 “참고”하는 것을 어떻게 보아야 하는 건가 하는 겁니다.(OpenDWG가 오픈소스이냐 아니냐는 일단 차치해두고라도 말이죠) 오픈소스 프로그램 코드 전체 혹은 일부를 Copy & Paste 한다면 당연히 프로그램의 라이센스에 따라야겠죠. 그렇다면 소스를 보고 이해한 후 다시 작성한다면 어떤걸까요? 소스 코드를 보고 재작성한다 하더라도 역시 머리속에서 루틴을 Copy & Paste 하는 것이나 마찬가지 아닐까요? 그렇다면 소스코드를 보는 것 만으로 라이센스에 따라야 할까요? “참고”라는 애매한 단어를 어떻게 보아야 할까요? 국내 많은 업체들이 괜찮은 오픈소스 프로젝트를 따와서 자신들의 프로그램을 만들고 상용으로 판매하고 있다고 합니다.(언젠가 MS의 DevDays에 갔다가 들은 이야기) 이 업체들은 라이센스 문제를 어떻게 이해하고 적용한 걸까요?(자신들의 소스코드를 공개하지 않으니 누가 뭐라든 증거가 없다는 식일지도..) 단지 “참고용”이었을 뿐일까요?

일단 선배형의 친구분이 어떤 프로젝트를 참고하셨는지는 아직 확실치 않습니다만, OpenDWG를 사용하셨을 확률이 높을 것 같습니다. 만약 OpenDWG를 사용해서 하자고 하시면 일단 안된다고 해야겠죠.(프로젝트 성격이 다르다면 모르겠지만요) 이리저리 찾아본 결과 DXF 파일 포멧은 공개 포멧인 것 같으니 제작방향은 일단 그 쪽으로 설정하고 이야기해 보아야겠습니다.

C의 가변인자

IRC의 #ubuntu 에서 어제밤에 놀다보니 sakuragi 님께서 가변인자 포인터에 대해 공부하고 계신 다고 하더군요. 가변인자 포인터가 무슨 뜻일까하고 혹시 … <- 요거요? 하고 여쭤봤더니 그게 맞는 모양이더라구요. ㅎㅎ
뭐 제가 알고있던 몇가지를 정리하자면 가변인자 포인터는 매크로 함수라는 것. 함수 호출시 인자의 포인터를 가리키게 해서 인자들을 순서대로 읽어온다는 것 정도로 알 수 있습니다. 디버거등으로 함수 호출 시의 메모리 안을 들여다보시면 쉽게 이해하실 수 있을 거예요.
저도 디버깅 함수를 만들때라던가 할 때 유용하게 써먹곤 하는데요. 뭐 vsprintf 를 사용해서 디버깅 메시지를 원하는 데로 포멧팅해서 원하는 곳에 출력한다던가 하는 정도로 사용합니다.
C99 에서는 전처리기로 처리할 수 있도록 지원하기도 하는데(이게 정확한 표현이 아닐수도 있습니다; 뭐라고 써야할지 정확히 생각나진 않네요.) 제가 사용했던 ARM Development Suite 1.2 에 들어가 있는 ARMCC 에서 다음과 같이 작성해서 쓴 적이 있습니다. 코드 일부를 옮기자면..

// 디버그 함수
#ifndef        _DEBUG_
#define        DBG_OUT(…)    ;
#else
#define        DBG_OUT(…)    at91_usart_printf(&USART0_DESC, __VA_ARGS__)
#endif

이런 식으로 선언해서 써주었었죠. at91_usart_printf 함수는 제가 구현해서 썼던 함수인데 함수 내부에서 vsprintf 를 사용해서 가변인자 형식을 받아 printf처럼 포멧팅해서 내부시리얼로 전송하는 함수였습니다. 디버깅 메시지를 시리얼로 표시하고 싶을 땐 그냥 DBG_OUT(“값: %d\r\n”, value); 형식으로 써주면 됐었죠. 저는 매우 게으르므로 디버깅시마다 같은 글자를 매번 타이핑하기가 귀찮았거든요. 줄여쓰면 좋잖아요? ㅎㅎㅎ

처음 C 배울 때 printf 함수 정의의 … 으로 처리된 저건 어떻게 쓰는 걸까 하고 생각했던 기억이 떠오르기도 하네요. 궁금하신 분들은 서적이나 MSDN 등을 한번 뒤져보시는 것도 좋습니다.
제가 그렇게 배웠거든요 :D(하수의 이야기;)