HotFoxy
불여우의 전직 이야기
게임 서버 개발자가 되어 보죠!
전체 방문자
오늘
어제
  • 분류 전체보기 (135)
    • 연구한 이야기 (26)
      • 깊게 공부해보기 (7)
      • 문제 해결 이야기 (12)
      • 맡은 업무 이야기 (6)
    • 전직 이야기 (0)
      • 1년이라는 시간 (5)
      • 프로카데미 이야기 (5)
    • 공부한 이야기 (87)
      • 알고리즘 (7)
      • 리눅스 (11)
      • 클라우드 (24)
      • 윈도우 OS (17)
      • 윈도우 소켓 프로그래밍 (11)
      • 네트워크 (16)
      • Docker & K8S (0)
      • 기타 (1)
    • 자격증 이야기 (12)
  • MSB : Mad Square's Brawl
  • GITHUB

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
HotFoxy

불여우의 전직 이야기

공부한 이야기/윈도우 OS

III : 64비트 기반 프로그래밍

2023. 4. 29. 21:50

III : 64비트 기반 프로그래밍

뇌를 자극하는 윈도우즈 시스템 프로그래밍 을 읽고 정리한 문서입니다 ;)

WIN32 vs WIN64

시스템이 어떤 비트 환경에서 동작하는지 구분하는 것은 두 가지로 판별할 수 있는데, 하나는 한 번에 전송 및 수신할 수 있는 데이터의 크기이고, 이는 즉 IO 버스의 대역폭을 의미한다.

또한, CPU가 데이터를 처리함에 있어 한 번에 처리 가능한 데이터의 크기가 비트 판별의 기준이 된다.

32비트 환경에서는 주소값의 표현을 가장 효율적인 32비트로 하였기에 최대 4GB의 메모리를 가질 수 있는 시스템이 되었고, 64비트 환경에서는 64비트로 메모리를 표현하기에 최대 16EB의 메모리를 가질 수 있는 시스템이다.

프로그램 구현 관점에서의 WIN32 vs WIN64

마이크로소프트는 64비트 기반의 운영체제를 내놓으면서 프로그래밍 스타일에 대한 가이드를 제공하고 있기에, 이에 따르는 것이 64비트 기반 프로그래밍의 첫걸음이다.

윈도우는 LLP64 데이터 표현 모델을 따르기에, long long 형과 pointer 형이 64비트이다. 이는 LP64를 쓰기에 long, long long, pointer 형을 쓰는 유닉스와는 long 자료형의 크기가 차이가 난다.

이에 따라 가장 첫 번째로 유의해야 할 점이 생기는데, 다음 코드를 보자.

int arr[10] = {0,};
int arrAddress = (int)arr;
printf("array address : %d", arrAddress);

위 코드는 32비트 환경에서는 전혀 문제 없지만, 64비트 환경에서는 메모리 주소 (8바이트)를 int 형 데이터 공간에 넣게 되어 데이터 손실이 발생한다.

따라서, 64비트 시스템에서는 포인터가 가지고 있는 주소값을 다른 형으로 저장할 때 주의하자.

윈도우 프로그래밍에 사용되는 자료형은 기본 자료형을 명칭을 바꾸고 조금 더 확실히 하여 사용한다.

윈도우 자료형 의미 정의 형태
BOOL Boolean Value typedef int BOOL
DWORD 32bit unsigned integer typedef unsigned long DWORD
DWORD32 32bit unsigned integer typedef unsigned int DWORD32
DWORD64 64bit unsigned integer typedef unsigned __int64 DWORD64
INT 32bit signed integer typedef int INT
INT32 32bit signed integer typedef signed int INT32
INT64 64bit signed integer typedef signed __int64 INT64
UINT 32bit unsigned integer typedef unsigned int UINT
PINT INT32에 대한 포인터 typedef int* PINT
PLONG LONG에 대한 포인터 typedef LONG* PLONG

이처럼 윈도우 프로그래밍에는 DWORD, INT, LONG과 같은 자료형이 많이 사용되며, 64비트가 되며 기존 자료형 뒤에 32, 64가 붙은 것은 기존 시스템을 유지하며 명확성을 줄 수 있기 위함이다.

마이크로소프트는 또한 Polymorphic 자료형을 정의하고 있는데, 이는 다양한 모습을 가지는 자료형으로서, 환경에 따라, 즉 32비트, 64비트에 따라 다르게 정의되는 자료형이다. 이를 통해 32비트와 64 비트 간 호환성을 높일 수 있다.

대표적으로 LONG_PTR, INT_PTR 등이 존재하는데, 이는 비트 환경에 따라 포인터의 크기가 다른 것을 아래 예시처럼 다형 자료형으로 쉽게 처리할 수 있게 해준다.

UINT_PTR CalDistance(UINT_PTR a, UINT_PTR b) {
    return a-b;
}

...
_tprintf(_T("distance : %d"), CalDistance((UINT_PTR)&val1, (UINT_PTR)&val2));
...

오류의 확인

오류가 발생하는 것은 전혀 이상한 것이 아니다. 다만 그에 따라 오류의 원인을 파악하고 문제를 해결할 수 있어야 한다.

윈도우 시스템 함수를 호출하는 과정에서 문제가 생기면, **GetLastError() 함수 호출**을 통해 오류의 원인을 알 수 있다. 많은 수의 윈도우 시스템 함수는 오류가 발생했을 때 NULL을 리턴한다.

윈도우 시스템 함수가 호출될 때마다 GetLastError 함수가 반환하는 에러 코드는 갱신되기 때문에, 오류 발생 직후에 바로 코드 확인 및 알맞을 처리를 해야 한다.

이것만은 알고 갑시다

  • 64비트 시스템과 32비트 시스템의 구조적 차이
    • 한 번에 송수신할 수 있는 데이터 크기와, 한 번에 처리할 수 있는 데이터 크기
  • 주소값 표현에 사용되는 바이트 수가 지니는 의미
    • 주소를 표현하는데 64비트 시스템은 32비트가 아닌 64비트를 사용하므로, 프로그래머가 표현할 수 있는 값의 범위가 늘어났다.
  • Polymorphic 자료형
    • 환경에 따라 다른 의미를 가짐으로서 더욱 유연한 프로그래밍을 가능하게 해준다.
  • LLP64와 LP64
    • 윈도우에서는 LLP64를 사용하고, 유닉스에서는 LP64를 사용하므로, long 이 가지는 크기에 차이가 존재한다.
  • GetLastError 함수의 사용방법
    • 윈도우 시스템 함수가 정상 코드를 리턴하지 않았다면, 바로 GetLastError 함수 호출을 통해 오류를 확인하자
저작자표시 (새창열림)

'공부한 이야기 > 윈도우 OS' 카테고리의 다른 글

V : 프로세스의 생성과 소멸  (0) 2023.04.29
IV : 컴퓨터 구조에 대한 두번째 이야기  (0) 2023.04.29
II : 아스키코드 VS 유니코드  (0) 2023.04.29
I : 컴퓨터 구조에 대한 첫번째 이야기  (0) 2023.04.29
프로세스 기초  (0) 2022.08.12
    '공부한 이야기/윈도우 OS' 카테고리의 다른 글
    • V : 프로세스의 생성과 소멸
    • IV : 컴퓨터 구조에 대한 두번째 이야기
    • II : 아스키코드 VS 유니코드
    • I : 컴퓨터 구조에 대한 첫번째 이야기
    HotFoxy
    HotFoxy
    1년 동안의 고군분투 전직 이야기! ..가 완료되어, 게임개발자로 살아남는 이야기!

    티스토리툴바