64bit 프로그래밍 정성태(kevin13@chol.net) MSDN Magazine 2006-05 x64 Primer – Everything You Need to Know To Start Programming.

Slides:



Advertisements
Similar presentations
.Net History. Visual Studio.Net 2002 /.Net Framework 1.0 제품의 버전 / 특징 2002 년 - Visual Studio.Net 2002 /.Net Framework 1.0 첫 통합 개발 환경 - C# 언어 등장 (C# 1.0)
Advertisements

컴퓨터와 인터넷.
Image & Video processing
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
마이크로소프트 64bit 윈도우 컴퓨팅 구조와 로드맵
X64 아키텍쳐 분석과 x64와 x86 비교 분석 손충호 (StolenByte).
제 9 장 구조체와 공용체.
Report #2 - Solution 문제 #1: 다음과 같이 프로그램을 작성하라.
컴퓨터 프로그래밍 기초 [Final] 기말고사
제7강 학습 내용 주소지정 방식의 예 값 즉시 지정 방식과 실행 예 레지스터 직접지정 방식 메모리 직접지정 방식과 실행 예
08. 디바이스 드라이버의 읽기와 쓰기 김진홍
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 12. 포인터의 이해.
어셈블리 문법 보강 4월 10일.
제 6장. 생성자와 소멸자 학기 프로그래밍언어및실습 (C++).
시스템 보안 [Buffer Overflow] DEC, 15, 2013 By 박동혁.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express Slide 1 (of 13)
4장. 웹로직 서버상에서의 JDBC와 JTA의 운용
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
07. 디바이스 드라이버의 초기화와 종료 김진홍
CHAPTER 02 OpenCV 개요 PART 01 영상 처리 개요 및 OpenCV 소개.
Root Filesystem Porting
리버스 엔지니어링 안녕하십니까? 리버스 엔지니어링 발표를 맡은 정창하입니다. 지금부터 리버스 엔지니어링 발표를
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
Root Filesystem Porting
                              데이터베이스 프로그래밍 (소프트웨어 개발 트랙)                               퍼스널 오라클 9i 인스톨.
23장. 구조체와 사용자 정의 자료형 2.
WinCE Device Driver 실습 #3
WinCE Device Driver 실습 #2
10장. 예외처리.
C#.
C 프로그래밍 C언어 (CSE2035) (Chap11. Derived types-enumerated, structure, and union) (1-1) Sungwook Kim Sogang University Seoul, Korea Tel:
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
Chap 6.Assembler 유건우.
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
이름 : 황 상 두 전화번호 : 이메일 : PinTool 이름 : 황 상 두 전화번호 : 이메일 :
27장. 모듈화 프로그래밍.
메모리 관리 & 동적 할당.
HTTP 프로토콜의 요청과 응답 동작을 이해한다. 서블릿 및 JSP 를 알아보고 역할을 이해한다.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
Flash Communication Server
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
2장. 변수와 타입.
데이터베이스실험실 석사 2학기 조정희 TCP/IP Socket Programming… 제 18장 윈도우 기반 쓰레드 사용하기 데이터베이스실험실 석사 2학기 조정희
Lab 8 Guide: 멀티스레딩 예제 2 * Critical Section을 이용한 멀티스레딩 동기화 (교재 15장, 쪽)
ARM Development Suite v1.2
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
PMIS 서버 설정 환경설정 작성자 : 배경환.
Fucntion 요약.
CHAP 21. 전화, SMS, 주소록.
Canary value 스택 가드(Stack Guard).
( Windows Service Application Debugging )
STS 에서 웹 서버 설치 방법.
DK-128 직렬통신 실습 아이티즌 기술연구소
3장 JSP프로그래밍의 개요 이장에서 배울 내용 : JSP페이지의 기본적인 개요설명과 JSP페이지의 처리과정 그리고 웹 어플리케이션의 구조에 대해서 학습한다.
ARM Development Suite v1.2
TVM ver 최종보고서
발표자 : 이지연 Programming Systems Lab.
3.2 분기 명령어.
Numerical Analysis Programming using NRs
과제 4: Thread (5월 9일까지) 4장 연습문제 풀이
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
06. 디바이스의 등록과 해제 김진홍
1. 지역변수와 전역변수 2. auto, register 3. static,extern 4. 도움말 사용법
 6장. SQL 쿼리.
Reversing 발표자 : 박현우.
CODE INJECTION 시스템B 김한슬.
Assembly 05 방호남 07 반지훈 09 박상욱.
7 생성자 함수.
Presentation transcript:

64bit 프로그래밍 정성태(kevin13@chol.net) MSDN Magazine 2006-05 x64 Primer – Everything You Need to Know To Start Programming 64-bit Windows Systems 2006.06.10 정성태(kevin13@chol.net) *** 이 문서는 PPT Template 만을 .NETXPERT 를 썼을 뿐, 회사의 공식 문서가 아닙니다.

Win64 IA64 와는 달리 x64 는 기존 x86 시스템과의 호환성을 유지. Win64 시스템은 x64 - AMD x64, Intel x64 모두 에서 동작하며, 이로 인해 응용 프로그램은 단일한 Win64 시스템을 목표로 제작하면 됨. 이 PPT 에서는 기존 Win32 응용 프로그램을 x64 로 변환하기 위해 필요한 Win64 기반 지식을 다룹니다.

목차 OS 세부 구현 x64 CPU 구조 VC++ 로 x64 프로그램 개발 .NET 으로 x64 프로그램 개발

1-1. 주소 공간 – 물리 메모리 한계 OS 세부 구현 이론상 가능한 주소 공간 : 2의 64승 – 16 exabytes Windows x64 운영 체제 : 2의 44승 – 16 terabytes 차이가 나는 이유? 현재의 x64 CPU 자체의 한계 : 2의 40승 까지만 지원 – 1 terabytes 아키텍쳐 차원에서 확보된 한계 : 2의 52승 까지 가능 – 4 petabytes 늘어난 메모리 만큼 관리되어져야 할 페이지 테이블도 따라서 증가 표 [1] 참조

표 1 Physical Memory and CPU Limits OS 세부 구현 표 1 Physical Memory and CPU Limits 물리 메모리 및 CPU 한계 32-Bit 모델 64-Bit 모델 Windows XP Professional 4GB (1-2 CPUs) 128GB (1-2 CPUs) Windows Server 2003, Standard Edition 4GB (1-4 CPUs) 32GB (1-4 CPUs) Windows Server 2003, Enterprise Edition 64GB (1-8 CPUs) 1TB (1-8 CPUs) Windows Server 2003, Datacenter Edition 64GB (8-32 CPUs) 1TB (8-64 CPUs)

1-2. 주소 공간 – Windows 시스템 OS 세부 구현 32-Bit Models 64-Bit Models 가상 주소 공간 4GB 16TB 32-bit 프로세스에 대한 가상 주소 공간 2GB (3GB if system is booted with /3GB switch) 4GB if compiled with /LARGEADDRESSAWARE (2GB otherwise) 64-bit 프로세스에 대한 가상 주소 공간 Not applicable 8TB Paged pool 470MB 128GB Non-paged pool 256MB System Page Table Entry (PTE) 660MB to 900MB

1-3. 주소 공간 – Win64 프로세스 공간 OS 세부 구현 0 ~ 8 TB : User mode 8 ~ 16 TB : Kernel mode Page size : 4KB 최초 64KB 영역은 매핑이 안됨. 따라서 실제 유효한 주소 는 0x10000 이상 System DLL 들은 4GB 이상의 영역에 위치. (보통 0x7FF00000000)

1-4. 주소 공간 – Win32 주소공간 예시 OS 세부 구현 x86 – Windows 2003 기준 : Internet Explorer 실행

1-5. 주소 공간 – Win64 주소공간 예시 OS 세부 구현 x64 – Windows 2003 기준 : Internet Explorer 실행

2. DEP ( Data Execution Protection ) OS 세부 구현 2. DEP ( Data Execution Protection ) 최근의 x64 프로세서들은 CPU No Execute bit 가 지원되어, Win64 윈도우즈는 하드웨어적으로 구현된 DEP 기능을 사용. 버퍼 오버런으로 인한 데이터 영역에서의 코드 실행을 금지 버퍼 오버런을 야기 시켰던 바이러스 및 프로그램 자체의 오류에 대한 보호 기능 향상 시스템 안정화

3. 타입 (Types) OS 세부 구현 int, long, DWORD : Win64 에서도 여전히 32bit 포인터, HANDLE, size_t : Win64 – 64bit 로 변경

OS 세부 구현 4. 파일 포맷 : PE32+ 기존 Win32 PE 파일과 비슷한 구조 유지. 필요 없는 필드의 삭제 및 32bit 크기의 필드들에 대한 64bit 의 확장 변경 IMAGE_LOAD_CONFIG, IMAGE_THUNK_DATA 같은 경우 역시 32bit 필드들이 64bit 로 확장 새롭게 PDATA 섹션이 추가 – Exception Handling 을 위한 함수 테이블 표 [3] 참조

표 3 Changes to PE File FIelds Header Field Change Magic Set to 0x20b instead of 0x10b BaseOfData Deleted ImageBase Widened to 64 bits SizeOfStackReserve Widened SizeOfStackCommit SizeOfHeapReserve SizeOfHeapCommit

5-1. 예외 처리 : Win32 – 스택 기반 OS 세부 구현 예외가 발생하면 OS 는 FS:[0] 을 시작으로 스택 상에 Linked List 로 연결되어 있는 예외 처리기를 실행. EXCEPTION_DISPOSITION __cdecl _except_handler( struct _EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, struct _CONTEXT *ContextRecord, void * DispatcherContext ) { return ExceptionContinueExecution; } { DWORD handler = (DWORD)_except_handler; __asm { push handler // Address of handler function push FS:[0] // Address of previous handler mov FS:[0],ESP // Install new EXECEPTION_REGISTRATION } __asm { mov eax,0 // Zero out EAX mov [eax], 1 // Write to EAX to deliberately cause a fault } __asm { mov eax,[ESP] // Get pointer to previous record mov FS:[0], EAX // Install previous record add esp, 8 // Clean our EXECEPTION_REGISTRATION off stack }

5-2. 예외 처리 : Win64 – 테이블 기반 OS 세부 구현 테이블 기반의 예외 처리. Win64 실행 모듈 자체에 runtime function table 을 포함. 함수 테이블에 있는 각각의 entry 는 해당 함수의 시작/끝 주소와 함께 부가 정보에 대한 위치를 포함. Win64 SDK WinNT.h 파일에 정의된 IMAGE_RUNTIME_FUNCTION_ENTRY 를 참조 동적 생성된 코드를 위해서 런타임 시에 추가 entry 를 넣고 싶다면, RtlAddFunctionTable API 를 사용 단점 : 스택 기반의 예외 처리에 비해서, 함수 테이블을 모두 검색해야 하기 때문에 상대적으로 느리다. 장점 : 함수가 실행될 때마다 try 데이터 블록을 설정해야 하는 오버헤드가 없다.

5-3. 예외 처리 : Win64 – 예외 처리 없는 코드 OS 세부 구현 int _tmain(int argc, _TCHAR* argv[]) { 0000000000402DF0 mov qword ptr [rsp+10h],rdx 0000000000402DF5 mov dword ptr [rsp+8],ecx 0000000000402DF9 push rdi 0000000000402DFA sub rsp,10h 0000000000402DFE mov rdi,rsp 0000000000402E01 mov rcx,4 0000000000402E0B mov eax,0CCCCCCCCh 0000000000402E10 rep stos dword ptr [rdi] 0000000000402E12 mov ecx,dword ptr [rsp+20h]  int boundary = 0; 0000000000402E16 mov dword ptr [rsp],0  boundary ++; 0000000000402E1D mov eax,dword ptr [rsp] 0000000000402E20 add eax,1 0000000000402E23 mov dword ptr [rsp],eax { int check = 0; 0000000000402E26 mov dword ptr [check],0 } return 0; 0000000000402E2E xor eax,eax } 0000000000402E30 add rsp,10h 0000000000402E34 pop rdi 0000000000402E35 ret

5-4. 예외 처리 : Win64 – 예외 처리 있는 코드 OS 세부 구현 int _tmain(int argc, _TCHAR* argv[]) { 0000000000402DF0 mov qword ptr [rsp+10h],rdx 0000000000402DF5 mov dword ptr [rsp+8],ecx 0000000000402DF9 push rdi 0000000000402DFA sub rsp,10h 0000000000402DFE mov rdi,rsp 0000000000402E01 mov rcx,4 0000000000402E0B mov eax,0CCCCCCCCh 0000000000402E10 rep stos dword ptr [rdi] 0000000000402E12 mov ecx,dword ptr [rsp+20h] 0000000000402E16 mov qword ptr [rsp+8],0FFFFFFFFFFFFFFFEh int boundary = 0; 0000000000402E1F mov dword ptr [rsp],0  boundary ++; 0000000000402E26 mov eax,dword ptr [rsp] 0000000000402E29 add eax,1 0000000000402E2C mov dword ptr [rsp],eax try { int check = 0; 0000000000402E2F mov dword ptr [check],0 } catch ( ... ) } return 0; 0000000000402E37 xor eax,eax 0000000000402E39 add rsp,10h 0000000000402E3D pop rdi 0000000000402E3E ret

OS 세부 구현 5-5. 예외 처리 : 참고 자료 x86 예외 처리 A Crash Course on the Depths of Win32™ Structured Exception Handling http://www.microsoft.com/msj/0197/Exception/Exception.aspx x64 예외 처리 X64 Unwind Information http://blogs.msdn.com/509372.aspx

OS 세부 구현 6. 새로 추가된 API IA64 버전과는 달리 x64 버전의 Windows 에서는 그다지 특기할 만한 새로운 API 가 없음. IsWow64Process – 현재 Win64 시스템에서 구동되고 있는지 검사. GetNativeSystemInfo – Win64 시스템의 환경 정보 그 외의 API 들은 [표 4]에 나열

표 4 New 64-Bit APIs Functionality API Exception Handling RtlAddFunctionTable RtlDeleteFunctionTable RtlRestoreContext RtlLookupFunctionEntry RtlInstallFunctionTableCallback Registry RegDeleteKeyEx RegGetValue RegQueryReflectionKey NUMA (Non-Uniform Memory Access) GetNumaAvailableMemoryNode GetNumaHighestNodeNumber GetNumaNodeProcessorMask GetNumaProcessorNode WOW64 Redirection Wow64DisableWow64FsRedirection Wow64RevertWow64FsRedirection RegDisableReflectionKey RegEnableReflectionKey Miscellaneous GetLogicalProcessorInformation QueryWorkingSetEx SetThreadStackGuarantee GetSystemFileCacheSize SetSystemFileCacheSize EnumSystemFirmwareTables GetSystemFirmwareTable

OS 세부 구현 7-1. WOW64 Subsystem Win32 코드를 Win64 환경에서 실행시켜 주는 서브시스템 환경. WOW64 에서 실행되고 있는 프로세스는 작업관리자에서 “*32” 로 확인 가능. - 16 bit 코드는 지원 종료

7-2. WOW64 Subsystem - 제한 OS 세부 구현 32bit 프로세스는 커널 모드로 진입시, 중간의 WOW64 코드가 해당 호출을 가로채서 처리. 32bit 프로세스 – 32bit DLL 만 로딩 가능 64bit 프로세스 – 64bit DLL 만 로딩 가능 프로세스 간 통신은 여전히 유효하며, 기존의 공유 메모리(shared memory), 명명 파이프(named pipe), 동기화 개체(named synchronization object)들은 그대로 사용 가능 To enable IIS 6.0 to run 32-bit applications on 64-bit Windows Open a command prompt and navigate to the %systemdrive%\Inetpub\AdminScripts directory. Type the following command: cscript.exe adsutil.vbs set W3SVC/AppPools/Enable32BitAppOnWin64 "true" Press ENTER. * 이로 인해, Internet Explorer 의 경우 32bit 용이 제공됨. 또한 IIS 웹 애플리케이션의 경우, 64bit 로 변환될 수 없는 32bit COM DLL 로 인해 WOW64 모드로 동작하는 상황도 발생됨.

7-2. WOW64 Subsystem – 시스템 디렉토리 관리 OS 세부 구현 7-2. WOW64 Subsystem – 시스템 디렉토리 관리 Kernel32.dll 과 같은 DLL 들이 동일한 디렉토리에서 동일한 이름으로 32bit 모듈과 64 모듈을 가지고 있을 수 없으므로, 이를 위해 WOW64 는 32bit 프로세스에 대해 시스템 디렉토리를 “SysWow64” 폴더로 우회 만약, 64bit 프로세스에서 명시적으로 “SysWow64” 폴더 경로를 구하고 싶다면, GetSystemWow64Directory API 를 사용. 32bit DLL : “C:\Windows\SysWow64” 64bit DLL : “C:\Windows\System32”

7-3. WOW64 Subsystem – 레지스트리 관리 OS 세부 구현 7-3. WOW64 Subsystem – 레지스트리 관리 32bit 와 64bit 로 제공되는 COM 개체가 등록될 때, 또는 32/64bit 프로세스가 해당 COM 개체를 생성할 때의 레지스트리 참조 문제를 해결하기 위해 별도 관리 명시적으로, 다른 환경의 레지스트를 구하기 위해서는 RegOpenKey API 등의 flag 값으로 다음과 같은 값들이 추가됨 KEY_WOW64_64KEY – 명시적으로 64 bit 레지스트리 경로를 반환 KEY_WOW64_32KEY – 명시적으로 32 bit 레지스트리 경로를 반환 Windows 시작시 자동 실행 프로그램에 대해서. 다음의 노드도 살펴봐야 합니다. HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run 64bit 프로세스 : HKEY_CLASSES_ROOT\CLSID 32bit 프로세스 : HKEY_CLASSES_ROOT\Wow6432Node\CLSID

8. 기타 OS 세부 구현 - 쓰레드 환경 블록을 나타내는 FS 레지스터는 Win64 에서는 GS 레지스터가 담당. - PatchGuard 적용 : syscall 테이블이나 IDT (interrupt dispatch table)같은 중요한 커널 데이터를 사용자 모드의 프로그램이나 드라이버가 명시적으로 지원되지 않는 방법으로 변경하는 것을 봉쇄. 중요한 커널 메모리 영역에 대한 변화를 별도의 커널 모드 쓰레드를 이용하여 감시.

x64 CPU 구조 1. 레지스터 IA64 와는 달리, 기존 x86 과의 호환성을 위해서 유사한 구조로 확장됨. RAX RBX RCX RDX RSI RDI RSP RBP R8 R9 R10 R11 R12 R13 R14 R15 IA64 와는 달리, 기존 x86 과의 호환성을 위해서 유사한 구조로 확장됨. 범용 레지스터의 이름이 64bit 로 확장되면서 새롭게 “R”로 시작. 이전의 EAX, AX, AL, AH 등의 접근 방식도 그대로 지원 R8 ~ R15 까지의 새로운 64bit 범용 레지스터 추가 16개의 128-bit 의 SSE2 레지스터 – XMM0 ~ XMM15 자세한 x64 레지스터 셋은 WinNT.h 파일의 #if defined(_AMD64_)안에 있는 _CONTEXT 구조체를 참고.

x64 CPU 구조 2. 64bit 주소 지정 아래와 같은 기존 32bit 명령어의 경우 5-byte 명령어 크기를 가짐 CALL DWORD PTR [XXXXXXXX] 64bit 에서도 64bit 주소 공간을 사용함에도 불구하고 위의 명령어는 그대로 5-byte 를 유지. 64-bit 모드에서는 32-bit 크기의 오퍼랜드 값은 현재 명령어를 기준으로 상대적인 위치를 나타내는 offset 값으로 동작. 즉, 실제로 다음과 같은 명령어는, 00401000: CALL DWORD PTR [00020000h] 00421000h 영역에 저장된 64-bit 포인터 값이 호출 주소가 됨. 이로 인해, 64-bit 포인터 값을 담고 있는 영역이 코드 실행 주소로부터 2GB 내에 위치하고 있어야 하는 제한이 생김. 따라서 개발자가 동적으로 코드를 생성하거나, 기존 코드를 변경하는 경우에는 이것에 주의해야 함. * 2006-08-12 추가 : Call Dword ptr 명령어 다음 주소부터 계산해서 변위값을 더하기 때문에 엄밀히 421000h 값은 아님.

3-1. 파라미터 전달 방식(calling convention) x64 CPU 구조 3-1. 파라미터 전달 방식(calling convention) - 단 하나의 calling convention 만을 지원. __cdecl 같은 지시자들은 컴파일러에 의해 무시됨. x64 호출 방식은 굳이 비교하자면, x86 fastcall 방식과 유사. - 처음 4개의 정수 값들은(우측에서 좌측 순으로) 64bit 레지스터들에 전달. RCX: 첫번재 인자 RDX: 두번재 인자 R8: 세번째 인자 R9: 네번째 인자 - 처음 4개의 부동 소수 값들은 XMM0 ~ XMM3 레지스터에 전달. - 각각 4개의 값들을 초과하는 인수에 대해서는 스택을 통해서 전달.

3-2. 파라미터 전달 방식(calling convention) - 예제 x64 CPU 구조 3-2. 파라미터 전달 방식(calling convention) - 예제   int test( int k, int j, int t, int o, int p, double dd ) { return 0; } test( 0, 1, 2, 3, 4, 0.06 ); 0000000000402E52 movsd xmm0,mmword ptr [__real@3faeb851eb851eb8 (405B88h)] 0000000000402E5A movsd mmword ptr [rsp+28h],xmm0 // XMM0 == 0.06 0000000000402E60 mov dword ptr [rsp+20h],4 // 스택 == 4 0000000000402E68 mov r9d,3 // R9 == 3 0000000000402E6E mov r8d,2 // R8 == 2 0000000000402E74 mov edx,1 // RDX == 1 0000000000402E79 xor ecx,ecx // RCX == 0 0000000000402E7B call test

3-3. 파라미터 전달 방식(calling convention) – 스택 관리(1) x64 CPU 구조 3-3. 파라미터 전달 방식(calling convention) – 스택 관리(1) 인자를 레지스터에 전달하는 것과 상관없이 스택 영역도 확보. 레지스터를 사용해야 할 경우가 생기면, 그 값을 해당하는 스택에 보관. 인자가 없더라도 최소 4개 영역 만큼은 확보. 이로 인해, 스택 위치로 복사하는 offset 값이 동일하게 유지됨. 인자가 5개 이상일 때부터 추가 스택 영역 확보. - 스택 정리 작업도 “호출자(caller)” 가 담당.

3-3. 파라미터 전달 방식(calling convention) – 스택 관리(2) x64 CPU 구조 3-3. 파라미터 전달 방식(calling convention) – 스택 관리(2) 함수의 진입(prologue)/탈출(epilogue) 코드 부분을 제외하고 RSP 값이 바뀌는 경우가 거의 발생하지 않음. x64 컴파일러는 함수 내에서 가장 큰 파라미터 수를 가진 호출 함수를 기준으로 충분한 스택 공간을 미리 예약. 그렇게 잡아둔 공간으로 이후의 함수 호출들에 대해서 스택 공간을 재사용. 함수 호출 시마다 발생했던 ESP 레지스터에 대한 작업이 사라짐 자세한 x64 호출 방식에 대해서는 다음의 토픽을 참조. The history of calling conventions, part 5: amd64 ; http://blogs.msdn.com/oldnewthing/archive/2004/01/14/58579.aspx

3-4. 파라미터 전달 방식(calling convention) – 반환 값 x64 CPU 구조 3-4. 파라미터 전달 방식(calling convention) – 반환 값 정수인 경우, RAX 로 전달. 부동 소수 값인 경우 XMM0 으로 전달 함수 호출 간에 보존되어야 할 레지스터 ; RBX, RBP, RDI, RSI, R12, R13, R14, R15 휘발성이고 값이 변경될 수 있는 레지스터 ; RAX, RCX, RDX, R8, R9, R10, R11

x64 CPU 구조 4. 기타 Integer parameters that are less than 64-bits are sign extended, then still passed via the appropriate register, if among the first four integer parameters. At no point should any parameter be in a stack location that's not a multiple of 8 bytes, thus preserving 64-bit alignment. Any argument that's not 1, 2, 4, or 8 bytes (including structs) is passed by reference. Structs and unions of 8, 16, 32, or 64-bits are passed as if they were integers of the same size.

1. 컴파일 환경 구성 – VS.NET 2005 VC++ 로 x64 프로그램 개발 “Build” / “Configuration Manager” 에서 “Active solution platform” / “<New...>” 를 선택. “x64” 환경을 위한 빌드 유형을 생성.

2. 권고 사항 – 소스 변환(1) VC++ 로 x64 프로그램 개발 포인터 변환 연산을 int, long, DWORD 값 등에 저장해서 한 것이 가장 큰 문제. 포인터는 x64 에서 8byte 로 바뀌어 4GB 이상의 영역을 지정할 수 있는 데 연산을 수행했던 int/long/DWORD 값은 여전히 4byte 로 심각한 문제 발생 포인터 연산을 수행한 int/long/DWORD 의 경우, DWORD_PTR, INT_PTR 등으로 변환하고, 크기를 명시해야 할 필요가 있는 경우에는 basetsd.h 에 정의된 INT32, INT64, INT16, UINT32, DWORD64 등을 사용 printf/sprintf 등의 포맷팅에서 문제 발생. 보통 포인터 값에 대한 출력으로 %X, %08X 를 사용했던 것들을 %p 로 수정. 크기 종속적인 출력인 경우 “I” 접두사를 사용. 예를 들어, UINT_PTR 변수에는 “%lu”, 플랫폼에 무관한 64bit 부호 있는 정수에 대해서는 “%l64d”를 사용

2. 권고 사항 – 소스 변환(2) VC++ 로 x64 프로그램 개발 포인터 문제를 명시적으로 끌어내기 위해 DLL/EXE 의 base address 를 4GB 이상의 영역으로 지정 Win32 와 Win64 에서의 컴파일 시 소스 코드를 지정하기 위해 다음의 매크로 상수를 사용. _M_IX86 : x86 프로세서 _M_AMD64 : AMD 64 프로세서 _WIN64 : IX86 과 AMD64 를 포함한 64bit 환경 #ifdef _M_AMD64 // My x64 code here #elif defined (_M_IX86) // My x86 code here #else #error !!! Need to write code for this architecture #endif #ifdef _M_AMD64 // My x64 code here #else // My x86 code here #endif

2. 권고 사항 – 소스 변환(3) VC++ 로 x64 프로그램 개발 - 인라인 어셈블리 : x64 빌드에서는 인라인 어셈블리 코드가 지원되지 않음. __asm 예약어 자체를 사용할 수 없음. 64bit MASM (ML64exe)를 사용해서 별도 컴파일.

1. 컴파일 환경 구성 – VS.NET 2005 .NET 으로 x64 프로그램 개발 - .NET 은 기본적으로 “Any CPU” 로 설정되어 있음. 원한다면, 특정 CPU 에서만 동작하도록 “x86”, “x64”, “Itanium”으로 설정 가능.

.NET 으로 x64 프로그램 개발 2. 권고 사항 – 소스 변환 - P/Invoke 관련 코드가 있는 경우, 반드시 검증.