: 64비트 기반 프로그래밍에 대한 이해를 갖도록 한다.
1. WIN32 vs WIN64
* 64비트와 32비트
: I/O버스를 통해 한번에 전송 및 수신할 수 있는 데이터의 크기 & 한번에 처리할 수 있는 데이터 크기에 따라서 32비트 시스템과 64비트 시스템이 나뉘게 된다.
* 프로그래머 입장에서의 64비트 컴퓨터
: 프로그래머 입장에서보면, 표현할 수 있는 주소값의 범위가 넓으면 넓을수록 좋다. 메모리 공간만 충분하다면 주소값의 범위가 넓은 만큼 더 넓은 메모리 공간을 활용할 수 있기 때문이다.
: 주소값을 표현하기 위해서 4비트가 사용된다면, 메모리에 할당할 수 있는 주소값의 개수는 2의 4승에 해당하는 16개(16바이트)가 전부이다. 따라서 16바이트가 사용할 수 있는 최대 메모리 크기가 된다.
2. 프로그램 구현 관점에서의 WIN32 vs WIN64
: windows 64는 32와의 호환성을 중요시했다.
* LLP64 vs LP64
: Windows 에서는 LLP64 모델을 채택하고 있고 UNIX 에서는 LP64 모델을 채택하고 있다.
: LLP64는 long이 4byte이고 LP64는 long이 8byte이다.
: 포인터는 둘다 8byte를 사용한다.
: 이는 windows64에서 32와 동일하게 long을 4byte를 사용함으로써 호환성을 중요시 여겼다는 것을 알 수 있다.
* 64bit와 32bit 공존의 문제점
: 64bit에서 포인터를 int형으로 형변화 시킬 경우 8byte가 4byte로 변환됨에 따라 데이터 손실이 발생하게 된다.
: 64bit에서는 포인터를 형변환 하지 말자.
* Windows 스타일 자료형
: 다른 시스템으로의 이식성을 고려한다면 기본 자료형 보다 새로운 이름으로 자료형을 정의하는 것이 보다 좋은 방법이다.
: windows에는 기존 32bit 자료형에 더하여 64bit 자료형을 만들어 두었다. 따로 수정하지 않고 추가적으로 만들었기 때문에 호환이 된다. 즉, 유니코드와 아스키코드가 호환되면서 64비트 시스템에서 새롭게 정의된 자료형을 사용하지않는 64비트 프로그램을 만들 수 있다.
: 하지만, 포인터가 사용되어진다면, WIN64 상황에 적절히 대응할 수 있는 조건부 컴파일을 해야한다.
* Windows 자료형 확인하기
: 선언된 곳을 찾아 들어가자, 보통 바로 찾아 들어갈 수 있도록 프로그래밍 툴내에 제공하는 기능들이 있다.
* Polymorphic 자료형
: WIN64로 넘어가면서 Polymorphic 자료형을 정의하고 있다. 다양한 모습이 있는, 다형적이라는 뜻이다.
: 조건부 컴파일을 사용하여 32bit 시스템에서는 32bit로 64bit시스템에서는 64bit로 자동 선언되게 하는 것.
3. 오류의 확인
* GetLastError 함수와 에러코드
: Windows 시스템 함수들은 오류가 발생했을 때 NULL을 반환한다.
: 오류가 발생했을 때 GetLastError 함수를 실행시키면 Error 코드를 얻을 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /* GetLastError.cpp */ #include <stdio.h> #include <windows.h> int _tmain(void) { HANDLE hFile = CreateFile( _T("ABC.DAT"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hFile == INVALID_HANDLE_VALUE) { _tprintf( _T("error code: %d \n"), GetLastError() ); return 0; } return 0; } | cs |
result : error code : 2
: 오류확인은 오류가 발생한 직후에 바로해야 한다.
4. System Programming Project Design
* 명령 프롬프트 프로젝트의 제안과 EXIT 명령어의 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | /* CommandPrmpt_One.cpp 프로그램 설명: 명령 프롬프트의 골격. */ #include <stdio.h> #include <stdlib.h> #include <locale.h> #include <windows.h> #define STR_LEN 256 #define CMD_TOKEN_NUM 10 TCHAR ERROR_CMD[] = _T("'%s'은(는) 실행할 수 있는 프로그램이 아닙니다. \n"); int CmdProcessing(void); TCHAR * StrLower(TCHAR *); int main(int agrc, TCHAR * argv[]) { // 한글 입력을 가능케 하기 위해. _tsetlocale(LC_ALL, _T("Korean")); DWORD isExit; while(1) { isExit = CmdProcessing(); if(isExit == TRUE) { _fputts(_T("명령어 처리를 종료합니다. \n"), stdout ); break; } } return 0; } TCHAR cmdString[STR_LEN]; TCHAR cmdTokenList[CMD_TOKEN_NUM][STR_LEN]; TCHAR seps[] = _T(" ,\t\n"); int CmdProcessing(void) { _fputts( _T("Best command prompt>> "), stdout ); _getts(cmdString); TCHAR * token = _tcstok(cmdString, seps); int tokenNum = 0; while(token != NULL) { _tcscpy ( cmdTokenList[tokenNum++], StrLower(token) ); token = _tcstok(NULL, seps); } if( !_tcscmp(cmdTokenList[0],_T("exit")) ) { return TRUE; } else if ( !_tcscmp(cmdTokenList[0],_T("추가 되는 명령어 1")) ) { } else if ( !_tcscmp(cmdTokenList[0],_T("추가 되는 명령어 2")) ) { } else { _tprintf(ERROR_CMD, cmdTokenList[0]); } return 0; } TCHAR * StrLower(TCHAR *pStr) { TCHAR *ret = pStr; while(*pStr) { if(_istupper(*pStr)) *pStr = _totlower(*pStr); pStr++; } return ret; } | cs |
- 1. 명령어를 추가할 때 변경되는 부분
- 2. 명령어의 대,소문자를 구분하지 않기 위해서 고려된 부분
- 3. 명령어 EXIT가 입력되었을 때 프로그램 종료방식
: 다음에는 이를 구현해볼 것이다.
|
'독후감 > 컴퓨터구조+운영체제+시스템프로그래밍' 카테고리의 다른 글
6. 커널 오브젝트와 오브젝트 핸들 (0) | 2017.03.06 |
---|---|
5. 프로세스의 생성과 소멸 (0) | 2017.03.03 |
4. 컴퓨터구조에 대한 두번째 이야기 - Part2 프로세스와 IPC (0) | 2017.03.03 |
2. 아스키코드 vs 유니코드 (0) | 2017.03.02 |
1. 컴퓨터 구조 - Part 1 컴퓨터 구조와 프로그래밍 모델 (0) | 2017.03.02 |