시작은 미미하나 끝은 쥬쥬하리라.

Study/Windows System Programming

[Window System Programming] Chapter 03. 64비트 기반 프로그래밍

코딩뚜벅이 2024. 1. 6. 20:24

1-3 64비트 기반 프로그래밍

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

WIN32 vs WIN64

32비트와 64비트의 차이 

한 번에 송수신 가능한 데이터의 크기, 데이터의 처리 능력 즉, 버스 시스템의 능력과 CPU의 차이가 주요

 

ex) 32비트 시스템에서는 32비트 명령어를 한 번에 fetch(명령어 이동) 한다고 하면 64비트 시스템에서는 64비트 명령어를 한번에 fetch 하면서 한 번에 fetch 할 수 있는 데이터의 크기가 증가

-> 같은 시간에 32비트 명렁어를 64비트는 2번 fetch 할 수 있다고 생각할 수 있으나, 보통 64비트 시스템에서는 64비트 명령어 길이를 사용하는 것이 일반적

 

하드웨어 관점에서 WIN32 vs WIN64

버스 인터페이스가 한 번에 이동시킬 수 있는 데이터의 크기 그리고 CPU가 데이터를 저장하고 컨트롤 유닛에 의해 해석되고 ALU에 의해 처리되는 일련의 과정을 처리 할 수 있는지에 대한 여부가 두 시스템의 차이를 결정

-> 만약 데이터 이동은 64비트로 이루어지는데 CPU의 처리는 32비트로 이루어진다면 불완전한 64비트

-> 데이터의 이동과 CPU의 처리 모두 64비트를 지원할 때, 64비트 시스템

 

프로그래머 관점에서의 WIN32 vs WIN64

32비트에서 64비트로 비트수가 증가하면서 표현할 수 있는 메모리의 전체 크기가 증가

-> 포인터의 크기는 크면 좋지만, 버스 시스템이 한 번에 전송 가능한 범위 내에서의 최대 크기가 좋은 메모리 크기

-> 위의 포인터의 크기가 크면 좋다는 의미는 32비트 시스템에서는 메모리의 주소를 나타내기 위한 비트수는 32비트이고 포인터 역시 동일한 크기인 4Byte로 표현, 즉 포인터가 늘어난다는 의미는 메모리가 증가한다는 의미

 

프로그램을 실행할 때 마다 각 프로그램은 가상 메모리 주소공간을 가지고, CPU는 프로그램을 작동시키기 위해 프로그램 내부의 명령어와 코드들을 주소로 표현

-> 만약 가상 메모리 공간이 부족해서 코드를 주소화하지 못한다면 프로그램을 실행시킬 수 없음

-> 비트수가 증가하면 가상 메모리의 공간 역시 증가

-> 32비트 PC는 2의 32승, 64비트 PC는 2의 64승까지 표현이 가능하며 동일한 크기를 가상 메모리의 크기로 제공 가능

 

WIN32 -> WIN64

1. 비트수 즉, 포인터 크기가 증가하면서 표현할 수 있는 메모리 크기 증가

2. 메모리 크기가 증가하면서 가상 메모리 공간 증가

3. 가상 메모리 공간이 증가하면서 더 많은 양의 코드를 포함한 프로그램의 실행이 가능

 


프로그램 구현 과점에서의 WIN32, WIN64

LP64, LLP64

 

프로그램 구현 과점에서의 64비트 프로그래밍 : LP64, LLP64를 고려한다는 의미

64비트 시스템으로 넘어가며 해당 시스템에 맞는 자료형을 재구성

-> Windows 64비트 자료형 체계 = LLP64

-> UNIX 64비트 자료형 체계 = LP64

-> LLP64와 LP64의 차이는 long 자료형이 4Byte, 8Byte라는 차이

-> 포인터 크기가 4Byte에서 8Byte로 증가했다는 것 이외에 32비트 시스템과 차이가 거의 없는데 이는 기존 시스템 호환성을 위함

-> 포인터는 8Byte 처리

 

 

ex) 만약 arr이라는 포인터(배열)을 int형으로 강제 형변환하는 경우

-> 32비트 시스템에서는 둘 다 4Byte로 처리하였으므로 문제 없음

-> 64비트 시스템에서는 포인터를 8Byte로 처리하기 때문에 4Byte인 int형으로 변환하는 경우 데이터 손실 발생

 

-> 포인터를 기본 자료형으로 캐스팅하는 것은 매우 안좋은 습관

 

Polymorphic 자료형

Windows 스타일 자료형 : 가장 큰 차이를 보이는 자료형

다형성(관점에 따라서 분류되는 방법이 다른 것을 의미)를 지님

-> 기존 32비트와 64비트 시스템에서 포인터 연산 처리를 하는 경우 발생하는 데이터 손실 문제 해소

-> _WIN64 매크로를 통해 자료형 사용

 

 

_WIN64 매크로는 윈도우 프로그래밍 시 기본적으로 들어가는 매크로

-> 매크로 정의 시, long_ptr, ulong_ptr  등의 자료형을 사용하는 경우 64비트형 데이터로 처리

-> 매크로 미 정의 시, 데이터를 32비트로 처리

 

오류 확인

오류 자체를 수정하거나 어떠한 오류가 발새했는지에 따라 흐름의 분기를 달리하기 위함

윈도우 시스템에서 오류가 발생하면 전역 메모리에 error 발생 이유를 저장

-> 저장된 오류 데이터를 해석만 하면 오류 확인 가능

 

GetLastError() : Windows가 저장한 오류 데이터 전역 메모리에 접근하기 위한 함수

-> 에러가 발생한 구간에 해당 함수를 사용하면 숫자를 반환

 

 

ex) 534 에러 발생

-> aritimetic_overflow : 계산 혹은 연산이 시스템이 처리하기 너무 큰 결과값을 산출할 때 발생하는 에러

 

 

ex) ABC.DAT라는 파일을 Read Mode로 오픈하려는 코드 : 비정상 실행 시 error code 메시지와 함께 함수 호출

-> GetLastError() 함수는 에러 발생 여부를 확인하는 함수가 아닌 에러 발생 시 마지막으로 발생한 에러의 원인을 파악하는 함수로 다른 어떠한 함수보다 우선시 되어 사용되어야만 에러 원인을 보장받을 수 있음

-> 만약 A 함수 호출 직후 B 함수가 호출되고 나는 A 함수에서의 에러 발생 원인을 알고 싶은데, B 함수에서 예외가 발생한다면 A 함수와 B 함수 사이에 GetLastError() 함수를 호출해주어야 함 : B 함수 뒤에 선언한다면 B 함수의 에러 발생 원인을 반환(전역 메모리에 저장된 정보가 덮어 씌워짐)