블로그 이미지
fiadot_old

칼퇴근을 위한 게임 서버 개발 방법론에 대한 심도있는 고찰 및 성찰을 위한 블로그!

Rss feed Tistory
Technical Article/펌 2002. 9. 3. 20:21

Integer Pack & UnPack...

기능??
32비트 컴파일러에서는 int형이 4바이트를 차지한다.
실제로 정수를 사용할때 이만큼 많은 수가 필요한 경우는 많지않으므로..
압축해서 사용해보자~~

이 소스에서는 16비트 컴파일러를 기준으로 int가 2바이트일때...
low, high가 256이하일때만 비트연산을 통해서 둘을 압축해서 리턴한다!

int        IntergerPack(int *nPack, int nHighByte, int nLowByte)
{
        int nTmpHigh, nTmpLow;
        
        *nPack = 0;

        if ( nHighByte > 255 || nLowByte > 255 )
                return FALSE;

        nTmpHigh = 0xFF00 & (nHighByte << 8);
        nTmpLow = 0x00FF & nLowByte;
        
        *nPack = nTmpHigh | nTmpLow;
        

        return TRUE;
}

int        IntergerUnpack(int nPack, int *nHighByte, int *nLowByte)
{
        *nHighByte = (nPack & 0xFF00 ) >> 8;
        *nLowByte = (nPack & 0x00FF);

        return TRUE;
}
,
Technical Article/펌 2002. 8. 20. 02:40

m = (++i) + (++i) 에 대한 고찰....

───────────────────────────────────────
#26     Pooh    (석원홍  )
[아시는 분]간단한 계산                                       08/19 19:16     6

#include <stdio.h>

int main()
{
int i = 0;
int m = 0;
m = (++i)+(++i);

printf("%d",m);
}

과연 결과는 한 번 쯤 생각해 보구요..^^;.







결과는 4가 나오네요..ㅠㅠ..3을 예상했는데요.(리눅스에서)

그런데 다른 분이 솔라리스에서 같은 버젼에 gcc에서

컴파일하니..3이 나왔다고 하네요..


어떤 게시판에서 본 건데...저런 식으로 사용은 거의(?)
되지 않지만, 저런 질문이 흥미롭긴 한데..

어떻게 알야내야 할지...^^;.

오늘도 좋은 하루..











#27     lovydayz(이근호  )
미테 문제  풀이잡설...                                       08/20 20:02     6
일단 결론부터 말씀드리면...

컴파일러의 지능(?)차이라고...

일단 3이 나온놈이 한갑자 높은놈이라 생각하심이...

왜인지는 밑에를 쭈욱 봐주세요 ^^


연산자 우선순위로 봤을때...

()먼저... ++ ... 그담이 + 가 되겠슴다....

즉... ++i == 1.... 두번째 ++i 에서 2...

즉 1+2 = 3이 되어야 코드를 짠사람의 의도라고 할수 있겠는데...

(내 맘대로 추측한건가 ㅡㅡ;;;)



일반적인 컴파일러 결과는 조금 다르져...

(여기서 일반적이라 함은 원홍이 행님이 한것과 내가 VC6++에서 테스트한것)

몇가지 실험을 해보면...

(++i) + (--i) == 0
(++i) + (  i) == 2
(++i) + (++i) == 4
(  i) + (++i) == 2
(--i) + (++i) == 0

5가지 경우를 비교했을때...알수있는건...

괄호의 유무와 연산자의 결합우선순위와 상관없이...

같은 라인에 있는 같은변수를 ++ -- 하는 연산은...

서로 각각 처리가 됨을 알수 있습니다.



왜 이렇게 되는지 이해하려면 디스어셈블한 코드를

살짜기 보면 쉽게 알수있는데

(어셈을 제대로 공부한게 아니고 후루꾸로 해서

  제대로는 못합니다 ㅡㅡ;; 감안해줘요)


8:        m = (++i) + (++i);
00401036   mov         eax,dword ptr [ebp-8]
00401039   add         eax,1
0040103C   mov         dword ptr [ebp-8],eax
eax레지스테어 i의 주소를 넣고.. 1을 더해주죠...
그담에 다시 i에다가 값을 넘깁니다.

0040103F   mov         ecx,dword ptr [ebp-8]
00401042   add         ecx,1
00401045   mov         dword ptr [ebp-8],ecx
ecx에 i의 주소를 넘기고 1증가시키고...다시 i에 넣고
위에랑 똑같은데 레지스터만 ecx써  

00401048   mov         edx,dword ptr [ebp-8]
edx에 i의 주소를 넘기구요...

0040104B   add         edx,dword ptr [ebp-8]
요기가 압권!!!
즉 i + i 에서 뿌라스 기호 부분인데...
현재i는 2인데...이놈을 edx에 다시 더해서..
즉 4 ㅡㅡ;;; 여기서 바로 4가 나오는 이유가 밝혀진것임다...으흐흐흐

0040104E   mov         dword ptr [ebp-4],edx
이게 마지막의 m = 이 구문..


즉.... 한라인에서 대입문에 들어가는 연산문에서 (말이 좀 어렵네 ㅡㅡ;;)

i의 주소를 바탕으로 각각의 증가(++) 감소(--)연산자는 제대로 연산이 되지만

마지막에 인자의 합을 더하는 부분에서...

주소를 통해 합이 도출되기   문에...

4가 나온다는 말씀이 되겠슴다.


그럼 3이 나온놈은 무엇이냐 ... 대강은 짐작하셨겠지만...

(아직 3이 나온놈을 디스어셈블 못해봐서 뭐라 말하기는 그렇지만...)

컴파일러에서 바이너리코드를 생성할때...

새로운 레지스터를 등록해서 eax, ecx를 더해서...

그걸 edx에 넘겨주는걸로 사료됩니다.

그렇게 하면 3이 나오겠죠 ^^



역시 심오한 C ^^

이샹 =3=3=3=3=3
,
Technical Article/펌 2002. 7. 31. 19:31

[펌] array[i] 와 *(array+i)의 차이

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

Technical Article/펌 2002. 7. 31. 12:31

[펌] 서버 접속인원의 한계

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

Diary/Photo 2002. 7. 30. 23:47

4월 29일 도찰당한거 ㅡㅡ;;;;;;

하드 정리하다 보니...

민성이 아저씨가 예전에 도찰하고 보내줬던게 보이네요.....

으흐흐흐......

디쟈너 언니의 프라이버시를 위하야..... Crop~~~

^^


쟈철안에서도 공부하는 나의 모습을 보라..

그 얼마나 웅비한가......ㅡㅡv;;;;;;;
,
Diary/Photo 2002. 7. 29. 18:22

내 노트북 사진...

으하하하하..

,
Technical Article/펌 2002. 7. 24. 13:55

[펌] 문자열을 원하는데로 자르자.. - Split함수 구현

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

Technical Article/펌 2002. 6. 24. 10:17

[펌] dbgprintf 예~

이제 F9, F5 키는 잊어 먹으세요..

제가 MSDN에서 파다가 나온 황금같은 소스를 걍 올릴께엽..

void dbgprint(const PCHAR lpszFmt,...)
{
    CHAR szBuf[512];
    va_list vargs;

    va_start(vargs,lpszFmt);
    vsprintf(szBuf, lpszFmt, vargs);
    va_end(vargs);
    OutputDebugString(szBuf);
    return;
}

아웃풋창에 걍 뜹니다.

실시간 디버깅시에 무척 유용하겠죠...

다만 실행시간이 좀 느려진다는 단점도 있으니깐

ifdef을 잘 이용하세요....
,
Technical Article/펌 2002. 6. 24. 10:15

[펌] 스트링 파싱예

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

Technical Article/펌 2002. 6. 24. 10:14

[펌] Internet Explorer의 주소창 Hooking하기

제    목  Internet Explorer의 주소창 Hooking하기  
작 성 자  송은희(song82)   첨 부
파 일  
작성시간  2002-06-18 오전 11:06:53
조 회 수  151

데브피아의 Q&A에서 찾은 방법으로 작성한 것을 정리해서 올립니다.
여기 예제는 주소창의 Keyboard와 윈도우 Message를 hooking하는 예제입니다.

아래의 변수들을 Global로 선언합니다.

static HHOOK g_hKeyHook = NULL;
static HHOOK g_hMsgHook = NULL;
static HWND g_hAddrComboBox = NULL;
static HWND g_hAddrEdit = NULL;

헤더파일에 다음의 함수를 선언합니다.

// Address Bar hooking
void IEAddressBarHook();
static LRESULT CALLBACK AddrBarKeyHookProc(int nCode, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK AddrBarMsgHookProc(int nCode, WPARAM wParam, LPARAM lParam);

위 세개의 함수 구현은 다음과 같습니다.

void CMyclass::IEAddressBarHook()
{
    HWND hwndIEFrame = NULL;
    HWND hWorker = NULL;
    HWND hComboBoxEx = NULL;
    HWND hRebar = NULL;

    g_pThis = this;

    hwndIEFrame = ::FindWindow("IEFrame", NULL);

    if(hwndIEFrame != NULL)
        hWorker = ::FindWindowEx(hwndIEFrame, NULL, "WorkerW", NULL);

    if(hWorker == NULL)
        hWorker = ::FindWindowEx(hwndIEFrame, NULL, "WorkerA", NULL);

    if(hWorker != NULL)
        hRebar = ::FindWindowEx(hWorker,NULL, "ReBarWindow32", NULL);

    hComboBoxEx = ::FindWindowEx(hRebar, NULL, "ComboBoxEx32", NULL);
    g_hAddrComboBox = ::FindWindowEx(hComboBoxEx, NULL, "ComboBox", NULL);
    g_hAddrEdit = ::FindWindowEx(g_hAddrComboBox, NULL, "Edit", NULL);

    g_hKeyHook = SetWindowsHookEx(WH_KEYBOARD,
            reinterpret_cast<HOOKPROC>(AddrBarKeyHookProc),
            NULL,
            ::GetCurrentThreadId());

    g_hMsgHook = SetWindowsHookEx(WH_GETMESSAGE,
            reinterpret_cast<HOOKPROC>(AddrBarMsgHookProc),
            NULL,
            ::GetCurrentThreadId());
}

LRESULT CALLBACK CMyClass::AddrBarKeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < 0)
        return CallNextHookEx(g_hKeyHook, nCode, wParam, lParam);

    if ((lParam & 0x80000000) || (lParam & 0x40000000))
        return CallNextHookEx(g_hKeyHook, nCode, wParam, lParam);

    if (wParam == VK_RETURN)
    {
// 여기서 주소창에서 엔터키를 사용했을 경우의 처리를 할 수 있습니다.
    }

    return CallNextHookEx(g_hKeyHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CMyClass::AddrBarMsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if(((PMSG)lParam)->hwnd == g_hAddrEdit || ((PMSG)lParam)->hwnd == g_hAddrComboBox)
    {
        if (((PMSG)lParam)->message == WM_PAINT)
        {
// 주소창의 내용이 변할때를 인식해 낼 수 있습니다.
        }
    }

    return CallNextHookEx(g_hMsgHook, nCode, wParam, lParam);
}


IEAddressBarHook()함수를 원하는 위치에서 호출해 주면, 상황에 따랄 Callback함수들이 호출되게 됩니다.

주소창 윈도우을 찾아낼 때 FindWindow()함수를 사용했는데요..
확인은 안해 봤지만, classname이 IE의 버전에 따라 차이가 있을수도 있을거 같습니다.
혹, 더 좋은 방법을 알고 계신 분들은 리플 달아주세요. ^^;


[데브피아 펌]
,
TOTAL TODAY