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 함수의 에러 발생 원인을 반환(전역 메모리에 저장된 정보가 덮어 씌워짐)