2010-04-22 30 views
23

Tôi vừa thử một cái gì đó trong MSVC 2010 trên máy 32-bit của tôi ở đây và phát hiện ra rằng tôi có thể sử dụng __int64 trong các chương trình của tôi - mà thực sự làm việc!__int64 trên máy 32 bit?

  • Làm cách nào có thể?
+2

Bạn thậm chí có thể sử dụng tiêu chuẩn int64_t! –

+0

@ el.pescado: 'int64_t' chỉ là tiêu chuẩn trong C99; nó không phải là một phần của tiêu chuẩn C++, nhưng sẽ được thêm vào trong C++ 0x sắp tới. –

+0

Trong thực tế, máy 32 bit của bạn (tức là> Pentium) có một số hỗ trợ 64bit bản địa, nó cũng có 36bit không gian địa chỉ. Chỉ là các cửa sổ chọn giới hạn bạn đến 32bit –

Trả lời

34

Cùng một cách số học 32 bit hoạt động trên hệ thống 16 bit.

Trong trường hợp này, nó sử dụng 2 địa chỉ bộ nhớ 32 bit để tạo thành số 64 bit cùng nhau. Ngoài ra/chất nền là dễ dàng, bạn làm điều đó bởi các bộ phận, chỉ gotcha là lấy carry-over từ phần dưới lên phần cao hơn. Đối với phép nhân/chia, khó hơn (tức là thêm hướng dẫn).

Rõ ràng là chậm, chậm hơn một chút so với số học 32 bit cho phép nhân, nhưng nếu bạn cần nó, nó có sẵn cho bạn. Và khi bạn nâng cấp lên bộ xử lý 64 bit , nó sẽ tự động được tối ưu hóa thành một lệnh có kích thước chữ lớn hơn.

Visual Studio 2010 thực hiện chuyên nghiệp của chút nhân 64 trên một bộ xử lý 32-bit, biên soạn trong chế độ phát hành, là:

_allmul PROC NEAR 

A  EQU  [esp + 4]  ; stack address of a 
B  EQU  [esp + 12]  ; stack address of b 

     mov  eax,HIWORD(A) 
     mov  ecx,HIWORD(B) 
     or  ecx,eax   ;test for both hiwords zero. 
     mov  ecx,LOWORD(B) 
     jnz  short hard  ;both are zero, just mult ALO and BLO 

     mov  eax,LOWORD(A) 
     mul  ecx 

     ret  16    ; callee restores the stack 

hard: 
     push ebx 

A2  EQU  [esp + 8]  ; stack address of a 
B2  EQU  [esp + 16]  ; stack address of b 

     mul  ecx    ;eax has AHI, ecx has BLO, so AHI * BLO 
     mov  ebx,eax   ;save result 

     mov  eax,LOWORD(A2) 
     mul  dword ptr HIWORD(B2) ;ALO * BHI 
     add  ebx,eax   ;ebx = ((ALO * BHI) + (AHI * BLO)) 

     mov  eax,LOWORD(A2) ;ecx = BLO 
     mul  ecx    ;so edx:eax = ALO*BLO 
     add  edx,ebx   ;now edx has all the LO*HI stuff 

     pop  ebx 

     ret  16    ; callee restores the stack 

Như bạn có thể thấy, đó là một LOT chậm hơn so với nhân bình thường.

+1

Nó sẽ không được tối ưu hóa trừ khi bạn biên dịch cho x64, bất kể bạn có bộ xử lý nào. –

+0

Er, yea, đó là những gì tôi muốn nói. Đêm dài .. – Blindy

+0

Có thể đã đúng trong C# mặc dù! – Blindy

5

Tại sao bạn thấy nó đáng ngạc nhiên? Không có gì để ngăn trình biên dịch hỗ trợ các kiểu số nguyên 64, 128 hoặc nhiều bit trên máy 32 bit. Trình biên dịch thậm chí có thể hỗ trợ các loại 57 và 91 bit, nếu nó cảm thấy thích nó. Trong thực tế hỗ trợ số học số nguyên 2N-bit trên một máy N-bit là một nhiệm vụ tương đối dễ dàng, vì tập lệnh của một máy điển hình thường được thiết kế với kiểu chức năng này trong tâm trí.

3

32 bit chỉ đơn thuần là kích thước gốc của từ máy, có nghĩa là chúng có thể được xử lý trong một lần, không có nghĩa là các mục lớn hơn không thể xử lý được, chúng chỉ cần được xử lý riêng biệt 32- đơn vị bit theo nhiều bước, giống như cách chúng có thể nhỏ hơn từ máy, trong trường hợp đó chỉ là một phần của từ máy đầy đủ sẽ được xử lý.

0

Nó hoạt động vì loại dữ liệu số nguyên 64 bit là một phần của đặc tả ngôn ngữ.

Trình biên dịch cho ngôn ngữ PHẢI cho phép bạn làm việc với các số nguyên 64 bit (và nhận được kết quả chính xác, tất nhiên).

Chương trình của bạn phải hoạt động (và hoạt động chính xác), cho dù bạn nhắm mục tiêu máy 64 bit, 32 bit, 16 bit hoặc 8 bit (bất kể trình biên dịch nào cho phép).

Ai đã viết trình biên dịch buộc phải làm cho nó làm bất cứ điều gì là cần thiết để làm chomỗi hỗ trợ công việc kiểu dữ liệu trên mỗi nhắm mục tiêu loại xử lý.

Hỗ trợ các loại dữ liệu "cao hơn" có khả năng hỗ trợ đã được chăm sóc, để bạn không phải tự mình làm.

Làm cách nào?Rõ ràng, chấp nhận mã lệnh điều khiển số học 16 bit và dịch nó thành mã máy chạy trên bộ vi xử lý 16 bit (hoặc cao hơn) là công việc "dễ dàng" cho trình biên dịch, gần như là bản dịch trực tiếp. Z = X + Y có thể dịch thành mov a,(X); add a,(Y); mov (Z),a;.

Ngược lại, chấp nhận mã lệnh điều khiển số học 64 bit và dịch nó thành mã máy chạy trên bộ xử lý 32 bit (hoặc thấp hơn) phức tạp hơn. Trình biên dịch có nhiều việc phải làm, hoạt động trên các phần 32 bit của mỗi toán hạng tại một thời điểm. Có nhiều cách để làm điều đó.

Mã máy kết quả có thể sử dụng nhiều hướng dẫn nội tuyến (mã lớn hơn, thực thi nhanh hơn). Z = X + Y có thể dịch thành mov a,(X); adc a,(Y); mov (Z),a; mov a,CARRY; adc a,(X+1); adc a,(Y+1); mov (Z+1),a;.

Mã máy kết quả có thể gọi các chương trình con số học mở rộng (mã nhỏ hơn, thực thi chậm hơn). Z = X + Y có thể dịch thành mov a,X; call GET64; mov a,Y; call ADD64; mov a,Z; call STORE64;.

Các vấn đề liên quan