'Category'에 해당되는 글 88건

  1. 2010.04.20 For higher position
  2. 2010.04.13 In my office.
  3. 2010.04.13 I sometimes go shopping...
  4. 2010.04.08 [TIP] VC++ 6.0에서 스택(STACK)의 크기 설정 3
  5. 2010.04.06 Call Gate에 관한 고찰
  6. 2010.04.05 소프트웨어 공학과 필요성 그리고 개발 프로세스 모델 1
  7. 2010.04.05 지정한 펜과 브러쉬 속성을 바꾸려면?
  8. 2010.04.04 구조체의 크기가 예상과 다른 이유는?
  9. 2010.04.04 WM_PAINT 메시지에서 처리되는 무효화의 이해 3
  10. 2010.04.03 윈도우 프로시저에서 메시지 박스를 띄울 때 런타임 에러가 발생하는 이유
2010. 4. 20. 13:31

For higher position


I'm busy with my job everyday. Recently I have studied an English hard. My

ability to speak in English is still at a beginning level, but getting better and better.

I didn't take an English class yesterday because I hung out with my friends

at the PC room a little late, but I didn't regret my decision. These days I have

had a lot of thoughts about my future. I want to continues my studies related

to my major and English. I hope to go to glad school for a high level of training.

I want to stand higher position then now. That's all. Thank you.


Written by Simhyeon, Choe

2010. 4. 13. 21:11

In my office.

I'm being alone now in my office because I'm having short project and my assignment.

It is not so bad than I thought. I`m going to get off in my company at 9:20 P.M.

My ability to write in English may seem a terrible. haha. I'm entirely in agreement

with that.
I want to study English until I'm fluent. I'm not enough as ever. Yeah, I'll

be through in a few minutes. I'm going to read a book at home. haha.
Thank you,

and have a good night everyone!


Written by Simhyeon, Choe

 

2010. 4. 13. 00:20

I sometimes go shopping...


I sometimes go shopping with my friends in AK plaza by bus on weekends. Before I go

shopping, I put on clothes simply as far as possible.
I usually like to buy wearing.

Especially, I prefer wearing a bright color to a dark color.
I have bought many kind of

shirts that have been a bright color.
When It looks good on me, This is as good as it

gets. 
I think that I don't waste money. I'm going to try to buy new products better

than products which I bought.



Written by Simhyeon, Choe

2010. 4. 8. 13:14

[TIP] VC++ 6.0에서 스택(STACK)의 크기 설정

독자는 때때로 대용량 배열을 지역으로 선언하고 사용하길 원할 수도 있습니다.

하지만, 툴에서 설정된 기본 스택의 크기는 1MB로 제한되어 있습니다.

이것은 컴파일러 옵션을 통해 스택의 크기를 설정해 줄 수 있습니다.

[Project]-[Project Settings]-[Link] 탭에서 설정하시면 됩니다.

위에 빨간색 동그라미 에디트 윈도우에 할당할 크기를 직접 주시면 됩니다.


Written by Simhyeon, Choe

2010. 4. 6. 00:24

Call Gate에 관한 고찰

 Call Gate권한이 다른 레벨 사이(예 : 낮은 특권 레벨 -> 높은 특권 레벨)에서 프로그램
 
수행의 제어 흐름을 변경하기 위해 이용되는 게이트웨이라고 정의할 수 있습니다.
 
다시 정리하면, 유저 권한에서 관리자 권한으로의 제어를 이행하기 위한 수단이 됩니다.
 
물론, Call Gate 이외에도 특권 레벨 권한의 변경은 다음과 같은 방법이 있습니다.
 
 
1. SOFTWARE INTERRUPT(INT n 명령어)
 
2. TASK GATE 이용
 
3. SYSENTER 이용
 
 
콜 게이트는 시스템 프로그래머가 여러가지 용도로 정의하여 사용할 수 있습니다만,
 
일반적으로 시스템 콜을 구현시, 콜 게이트를 사용할 수도 있습니다.
 
대표적인 운영체제인 윈도우즈와 리눅스에서 시스템 콜 사용시, 권한 레벨의 변경은
 
다음의 방법을 사용하고 있습니다.
 
리눅스에서는 소프트웨어 인터럽트 0x80SYSENTER,
윈도우즈에서는 소프트웨어 인터럽트 0x2ESYSENTER
 
 
콜 게이트 디스크립터의 구조체 정의는 다음과 같습니다.
 
(숫자는 그 필드의 비트 범위를 의미)
 
Offset in Segment - 63 : 47
P - 46
DPL - 45 : 44
S : 43
TYPE - 42 : 39
000 - 38 : 36
Parameter Count - 35 : 32
Segment Selector - 31 : 16
Offset in Segment - 15 : 0
 
INTEL MANUAL에서 보면, 시스템 디스크립터(S=0)에서 콜 게이트 디스크립터의
 
타입 비트는 1100로 정의되어 있습니다.
 
콜 게이트로 제어를 이행하는 절차는 다음과 같습니다.
 
1. far CALL 혹은 far JMP 인스트럭션을 사용한다. 즉, 오퍼랜드에 셀렉터:오프셋과
 
같은 형태로 콜 게이트의 셀렉터를 선택하여 호출한다.
 
(여기서, 사용자 오프셋은 무시된다. 이유는 오프셋으로 인접한 커널 영역의 세그먼트
 
 코드에 접근하여 실행할 수 있는 가능성이 존재하기 때문이다. 몰론 접근하고자 하는
 
 시스템 콜의 물리 주소 오프셋은 콜 게이트 디스크립터에 정의되어 있다)
 
 
- 다음 순서부터 프로세서가 접근 권한을 체크한다.
 
2. CPL과 RPL을 콜 게이트 디스크립터의 DPL을 비교한다.
 
(CPL은 현재 CS 레지스터에서 가지고 있는 권한을 의미하며,
 RPL은 무조건 far JMP 혹은 far CALL 오퍼랜드의 셀렉터가 된다.
 빨간색이 RPL, [ex] CALL 0x33:0)
 
Privilege Check Rules은 intel manual에 정의되어 있다.
[ CPL <= Call Gate DPL, RPL <= Call Gate DPL ]
 
 
3. 예를 들어, 호출자의 RPL 값이 3이고 콜 게이트 디스크립터의 DPL 값이 3이면
 
   접근이 허용되며, 여기서 콜 게이트 디스크립터의 세그먼트 셀렉터를 참조하게 된다.
 
   이것의 의미는 현재 CS 레지스터의 값커널 코드 세그먼트 셀렉터로 변경된다.
 
   (바로 여기서 접근 권한 레벨이 변경되었다고 표현한다. 결론은 현재 CS가 가진 권한이
 
   11이었지만, 커널 코드 세그먼트 셀렉터를 지시하게됨에 따라 CPL이 00으로 바뀌게 된다.
 
   (따라서, 콜 게이트 디스크립터 참조 이후에 권한 레벨의 변경이 이루어 집니다)
 
    다만, 프로세서에 의해 권한 체크 및 변경이 이루어지기 때문에 프로그래머 입장에서는
 
    전혀 신경 쓸 필요가 없음을 의미하기도 한다.
 
 
4. 이후의 흐름은 커널 코드 세그먼트의 물리 위치에서 콜 게이트 디스크립터의 오프셋을
 
    참조하여 시스템 콜을 수행하게 된다(제어의 이행이 완료된 상태에서).
 
 
콜 게이트를 테스트하기 위한 방법으로는 운영체제를 직접 구현하여 테스트해보는것이 가장
 
효과적입니다만, 윈도우즈에서도 이를 테스트하기 위한 디바이스 드라이버를 작성할 수 있습니다.
 
특권 레벨 RING0에서만 사용할 수 있는 INSTRUCTION의 조합으로 특정 루틴을 제작하여
 
동적으로 콜 게이트 셀렉터와 디스크립터를 생성하고 정의하여 맵핑한 후에 테스트할 수도

있습니다.
정리는 여기까지 하도록 하겠습니다.
 

Written by Simhyeon, Choe
2010. 4. 5. 23:47

소프트웨어 공학과 필요성 그리고 개발 프로세스 모델

오늘은 소프트웨어 개발의 프로세스 모델에 대하여 알아 봅시다.

이미 대학교에서 소프트웨어 공학을 전공하신 많은 독자들은 프로세스 개발 모델에 대해 잘 이해하고

계실 겁니다. 저도 오랜만에 다시 한번 관련 자료를 찾아 보면서 나름대로 학습하고 정리를 해 보았습니다.

간단하게 소프트웨어 공학의 개념과 필요성 그리고 개발 프로세스 모델, 이 두가지 이슈에 대하여 알아

보겠습니다.


I. 소프트웨어 공학(Software Engineering)이란 무엇이고 왜 필요한가?

  소프트웨어 공학소프트웨어를 설계, 개발 그리고 유지보수하기 위한 체계적인 이론과 기술을 다루는

학문
입니다. 소프트웨어를 개발하고 유지하는 전체적인 라이프 사이클을 관리하기 위한 이론의 집합체라고

볼 수 있습니다. 소프트웨어 공학이 정립되지 않았던 과거에는 하드웨어가 단순하고 저사양이었기 때문에

탐재된 소프트웨어의 크기 역시 작았고 설사 하드웨어의 수정이 있다고 하더라도 소프트웨어는 큰 수정없이

작성이 가능하였습니다. 하지만 어느 순간부터 하드웨어의 성능이 급격하게 성장함으로써 이에 따라 소프트

웨어 역시 복잡해지고 규모가 커졌으며, 단가는 올라가기 시작하였습니다. 개발된 소프트웨어를 유지보수

하는 과정중에 많은 문제가 발생하는 즉, 재사용이 어려워지고 개발이 힘들어지는 문제점을 야기하였습니다.

이때, 소프트웨어 위기론(Software Crisis)이 대두되기 시작하였지요(1968 NATO SE Conference).

이러한 위기를 벗어나고자 소프트웨어 개발 프로세스에 대한 연구가 지속되었고 오늘날의 소프트웨어 공학

이 집대성되었습니다.


II. 개발 프로세스 모델

  프로세스 모델은 하나의 소프트웨어 개발 프로세스를 정립하기 위한 일련 과정의 방법론입니다. 개발 프로

세스는 일반적으로 요구 사항의 분석, 설계, 구현, 테스트, 유지보수의 단계를 포함하고 있습니다.


1) 폭포수 모델(Waterfall Model)

wikipedia(http://en.wikipedia.org/wiki/Waterfall_model)에서 다음과 같이 정의되어 있습니다.
------------------------------------------------------------------------------------------
"The waterfall model is a sequential software development process, in which progress is seen

as flowing steadily downwards (like a waterfall) through the phases of Conception, Initiation,

Analysis, Design (validation), Construction, Testing and Maintenance."
------------------------------------------------------------------------------------------

위의 정의와 같이, 폭포수 모델은 순차적인 소프트웨어 개발 프로세스를 의미합니다. 이 모델의 진행 흐름이

폭포수와 같이 아래로 내려가는 형상과 비슷하여 명명된 모델입니다. 요구사항 분석, 설계, 구현, 테스트, 유

지보수의 단계를 순차적으로 하나씩 진행(완료될 때까지)합니다. 현재까지도 가장 널리 애용되고 있는 방법

론입니다.

이 모델의 장점은 단계별로 체계적인 정리와 문서화가 용이하다는 것이고 단점은 하나의 단계가 완전히 끝날
 
때까지 대기해야하고 요구 사항 재수정이 발생하면, 프로세스는 다시 이전까지 무효화되는 문제점을 가지고

있습니다.


2) 원형 모델(Prototyping Model)

폭포수 모델에서 고객의 잦은 요구 사항에 대한 유연성이 떨어지는 단점을 보완하기 위해 고안된 모델입니

다. 각각의 단계에서 고객의 요구 사항을 고려하여 신속한 설계/구현을 하고 고객에게 피드백에 따라 반영

하고 처리하도록 합니다. 이 과정을 각각의 단계 모두 동일하게 반복하여 수행하는 것입니다. 장점이라면

예상치 못했던 기능과 불완전한 요구 사항을 발견할 수 있으며, 완성될 제품의 질과 형태를 미리 가늠할 수

있습니다. 단점은 고객의 평가로 기존 요구사항에 비해 크게 변질될 우려가 있고 규모가 비대해 지거나 개발

비용이 초기보다 증가할 수가 있다는 점입니다.


3) 나선형 모델(Spiral Model)

폭포수 모델과 원형 모델의 장점을 기반으로 하고 위험 분석을 포함하는 모델이라고 할 수 있습니다. 고객과

발생할 수 있는 오해를 규명하고 프로젝트에서 발생할 수 있는 위험을 관리 및 최소화하는 것이 목적이고

일반적으로 대규모 시스템에 적합한 개발 방법론이 되겠습니다. 장점은 고객 역시 각 단계의 위험을 파악하

기 쉽고 이에 따른 피드백을 줄 수가 있으며, 개발에 발생할 수 있는 문제점을 사전에 캐치할 수 있습니다.

단점은 폭포수 모델과 원형 모델에 비해 복잡하고 단계의 진행 절차가 까다로워지며, 보다 많은 개발 비용을

요구합니다.


Written by Simhyeon, Choe


2010. 4. 5. 08:35

지정한 펜과 브러쉬 속성을 바꾸려면?

개발 포럼 게시판에서 어떤 유저가 질문한 내용에 대한 저의 답변입니다.

--------------------------------------------------------------------
안녕하세요.

브러쉬와 펜을 이용해서 동그라미나 네모를 그려주는데요.

이그림을 제가 마우스왼쪽버튼으로 클릭하였을 때 제가 임의로 지정한 펜과

브러쉬 속성으로 바꾸게 하고싶습니다. 어떤 내용을 참고하면 될까요?
--------------------------------------------------------------------

CBrush 클래스에서 CreateHatchBrush() 브러쉬의 여러가지 속성과 색상을 지정하실 수 있습니다.

기본 색상은 CreateSolidBrush()에서 지정하시면 됩니다.

CPen 클래스에서 팬의 굵기나 색상 등을 마찬가지로 지정하실 수 있습니다.

당연히 마우스 버튼을 클릭해서 속성을 지정해 주어야 하기 때문에

OnButtonDown()에서 위의 함수로 처리해주시면 되겠지요.

단, 새로운 속성을 가진 오브젝트를 생성하기 위해서는 당연히 이전에 오브젝트를

파괴하고 새로 오브젝트를 생성하셔야 합니다.

ex)

OnButtonDown()
{

     MyPen.DeleteObject( CPen의 이전 객체 ); 

     MyBrush.DeleteObject( CBrush의 이전 객체 );

     MyPen.CreatePen( 속성 지정 );

     MyBrush.CreateSolidBrush( 색상 지정 );
}


Written by Simhyeon, Choe
2010. 4. 4. 16:11

구조체의 크기가 예상과 다른 이유는?

이것도 예전에 데브피아에서 어떤 유저가 기고하였던 질문에 대한 저의 답변입니다.

------------------------------------------------------------------------------

구조체에서..
 
char a;
int b;
float c;

이것은 아는 대로 12바이트가 할당 됩니다.

char a;
int b;
double c;


이것은 16바이트가 할당이 되구요..

헌데, 

char a;
double b;
float c;

는 24바이트가 할당이 되네요.

구조체는 시스템의 메모리의 한 워드 단위로 할당이 되는거 아닌가요?

그러면 4바이트 단위니깐 16바이트가 맞는것 같은데..

답변 부탁드리겠습니다.

------------------------------------------------------------------------------

Structure Alignment는 시스템 cpu에 따라 의존적입니다.

이러한 구조체 정렬을 하는 근본적인 이유는 데이터 타입을

버스의 크기만큼 처리하는 것이 가장 효율적이기 때문이죠.

그러니까 예를 들면, 32Bit CPU에서는 데이터 버스도 32Bit의

크기를 가지는데, 한번에 처리할 수 있는 크기 단위로 처리하는

것이 성능면에서 당연히 효율적일 겁니다. 보다 작으면 데이터를

처리하기 위해서는 쉬프트 연산으로 인한 오버헤드가 크다는 겁니다.

차라리 몇 바이트를 낭비하는 대신, 성능상의 이점을 충분히 얻겠다는 의도입니다.

VC 컴파일러는 기본적으로 8Byte 정렬을 하는데요..

컴파일러 옵션으로 정렬 단위를 바꿔 줄 수 있습니다.

Structure Alignment는 그 구조체 멤버에서 가장 큰 데이터

타입을 기준으로 정렬하게 됩니다.

그럼 님께서 예를 들었던 구조체들을 다시 한번 살펴 보도록 하겠습니다.
 

char a;
int b;
float c;
 

1) 위의 구조체에서 가장 큰 멤버의 크기는 4Byte입니다.
 

■■■
■■■■
■■■■

그렇기 때문에 4 바이트를 기준으로 정렬하게 되며,

첫번째 멤버 char a는 3byte의 Empty Block이 생기게 되겠죠.
 

///////////////////////////////////////////////////////////////

 
char a;
int b;
double c;
 

2) 위의 구조체에서 가장 큰 멤버의 크기는 8Byte입니다.

 
■■■■■■■
■■■■■■■■
 

char a와 int b는 둘다 8Byte 블럭안에 포함될 수 있습니다.
 
단, 두번째 멤버 int b는 4Byte기 때문에, 앞의 공간을 사용한
 
char a에 의해서 3Byte 공간만 남아 정렬될 수 없기 때문에

int b 자신의 데이터 크기만큼 띄워 나머지 공간에 padding되게 됩니다.
 

///////////////////////////////////////////////////////////////

char a;
double b;
float c;

3) 위의 구조체에서 가장 큰 멤버의 크기는 마찬가지로 8Byte입니다.

■■■■■■■
■■■■■■■■
■■■■■■■■

첫번째 멤버 char a가 위치한 후에 8Byte에서 나머지 7Byte 공간에

double b가 들어갈 수 없기 때문에, 자신의 블럭 크기로 padding되게 됩니다.

마찬가지입니다. float c도 위의 8Byte(double b의 공간)이 모두 채워졌기

때문에 다시 8Byte만큼 정렬한 공간에서 나머지 4Byte크기로 padding되게 됩니다.

 
 

※ 메모리 위치가 수시로 변할 수 있는 근본적인 이유는 Allocation Segment Alignment 때문입니다.

    그러니까 힙 영역을 할당할 때, os에서 heap allocation을 처리하는 알고리즘에서 새로이 할당되는

    메모리 영역을 순차적으로 검색하다가 충분히 할당할 수 있는 공간이라고 판단되면, 이전에 할당된

    메모리 공간을 보다 앞으로 위치시킬 수 있는 그러한 이유가 있기 때문이죠.


Written By Sim-Hyeon, Choe
 

2010. 4. 4. 15:25

WM_PAINT 메시지에서 처리되는 무효화의 이해


예전에 데브피아에서 어떤 유저가 기고하였던 질문이 있었는데, 거기에 대한 저의 답변입니다.

-------------------------------------------------------------------------------------

(환경 : VS 2005 MFC)

LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{

    // TODO: Add your specialized code here and/or call the base class 
   

    switch( message )

    {  

    case WM_PAINT:

        // 페인트 메시지에서 메박을 띄웠습니다. 
        MessageBox(_T("이상하다"), _T("case WM_PAINT:"), MB_OK);

        // 그런데 여기서 실제로 이 메박은 뜨지 않습니다. 쾅쾅거리는 소리만 요란하게 납니다.

        // 0.1초 쯤 아주 조금의 시간이 지난 뒤에 실행창은 뜹니다
        // 그런데 실행창이 투명처리가 되어 나타납니다.

        // 그리고 컴터가 다운은 아니지만 다운 비슷함니다. 다른 메시지가 전혀 먹히지 않습니다.

        return 0;          // 이런 이유가 무엇인가요?

    }

     return CFrameWnd::WindowProc(message, wParam, lParam);

}
-------------------------------------------------------------------------------------

원인이 발생하는 가장 큰 이유는 무효화후에 유효화가 일어나지 않기 때문에

커널단에서 무한하게 WM_PAINT 메시지를 발생시키는 겁니다.
 
다시 설명을 드리자면, WM_PAINT 메시지는 무효화가 일어났을 때 즉,

다시 그려야 할 경우에 발생하는 메시지입니다.

여기서 다시 그려야 할 경우라면 바로 메시지 박스를 의미하겠지요.

메시지 박스를 다시 그려라고 WM_PAINT 메시지를 주었는데, 그곳에는

어디에도 메시지 박스를 다시 그리는 작업(유효화)하는 부분이 존재

하지 않습니다.

 

님께선 이런 의문을 가지시겠지요.

case WM_PAINT:

    MessageBox(_T("이상하다"), _T("case WM_PAINT:"), MB_OK);

    return 0;


위의 코드처럼 WM_PAINT에서 MessageBox()를 호출하게 하였는데 무슨 소리냐..고요.

중요한 것은 그리기 작업을 하기 위한 DC를 발급받지 않은 상태에서 어떤 호출은
 
커널상에서 무시가 된다는 것입니다.

그러니까 커널 내부적으로 무효화된 부분이 다시 그려졌는지 확인해보고

그려져 있지 않으니까 또다시 호출하고 이런 과정이 무수히 반복되는 것입니다.

위의 코드가 님이 의도하신대로 제대로 동작하려면 두가지 방법으로 처리해야 합니다.


CDC *pDC;

PAINTSTRUCT ps;
 

case WM_PAINT:

    pDC = BeginPaint( &ps );

    MessageBox(_T("이상하다"), _T("case WM_PAINT:"), MB_OK);

    EndPaint( &ps );

    return 0;

 
와 같이 처리하시면 무효화가 발생할 때마다 메시지 박스가 정상적으로 호출될 겁니다.
 
혹은 부모 클래스 CFrameWnd의 WindowProc()으로 디폴트로 처리해 주신다면

님의 의도대로 호출될 수 있습니다.
 

case WM_PAINT:

    MessageBox(_T("이상하다"), _T("case WM_PAINT:"), MB_OK);

    break;

 

부모 클래스 CFrameWnd의 WindowProc()를 호출해주면 거기에서

다시 DefWindowProc()을 호출하게 되는데요.
 
DefWindowProc()에서 BeginPaint()와 EndPaint()처리를 기본적으로 해주게 됩니다.
 

※ WM_PAINT메시지는 Queued Message지만, WM_PAINT 하나의 메시지만 큐에 저장됩니다.


Written By Sim-Hyeon, Choe

2010. 4. 3. 14:24

윈도우 프로시저에서 메시지 박스를 띄울 때 런타임 에러가 발생하는 이유


다음의 예제를 한번 살펴 봅시다.

--------------------------------------------------------------------------------

LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{

 ① MessageBox( _T("error"), _T("error"), MB_OK ); // 여기서는 런타임에러가 난다. 

    switch( message )
    {
        case WM_NCLBUTTONDOWN :
            // 여기서는 에러없이 잘된다.
         ② MessageBox( _T("success"), _T("success"), MB_OK );
            break;

        .......
    }
}

--------------------------------------------------------------------------------


1번과 2번은 어떤 차이가 있을까요?

WindowProc()이 호출될 시점을 생각해 봅시다. 당연히 모든 이벤트가 발생할 때마다

WindowProc()가 호출되겠지요. 그중에서도 최초 CMainFrame 클래스의 윈도우를 생성

중인 시점이라면 WM_CREATE 메시지가 발생합니다. WM_CREATE 메시지는 윈도우를 만들

고 있는중에 처리할 수 있는 메시지입니다. 문제의 핵심은 이것입니다. 윈도우가 아직

만들어진 상태가 아니라는 점입니다. 부모 윈도우인 CMainFrame 윈도우가 아직 만들어

지지 않았기 때문에 부모 윈도우(CMainFrame)의 핸들값이 유효하지 않습니다. 그 유효

하지 않은 핸들값을 참조하는 일종의 자식 윈도우인 MessageBox()가 부모 윈도우의 핸

들값을 참조하기 때문에 런타임에 에러가 발생하는 것입니다. (MFC의 MessageBox()는

내부적으로 부모 윈도우의 핸들을 참조합니다) switch()문 밖에 있는 MessageBox()와

특정한 메시지에 위치한 MessageBox()는 그러한 차이가 있습니다. 제가 이렇게 확신해서

말씀드릴 수 있는 이유가 만약에 우리가 원하는 의도대로 MessageBox()가 호출될 수 있

다면 정신없이 무수히 많은 메시지 박스가 팝업될텐데 WM_CREATE 메시지를 처리하기전에

그런 경우는 절대 발생할 수 없기 때문입니다.

Written By Sim-Hyeon, Choe