Difference between revisions of "Writing portable code regarding the processor architecture/id"

From Lazarus wiki
Jump to navigationJump to search
(New page: Ada beberapa isu utama saat menulis kode yang portabel sehubungan dengan arsitektur prosesor: endianness dan prosesor 32 vs. 64 bit. == Endianness == Endianness is the way...)
 
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 +
{{Editing Writing portable code regarding the processor architecture}}
 +
 
Ada beberapa isu utama saat menulis kode yang portabel sehubungan dengan arsitektur prosesor: endianness dan prosesor [[32 bit|32]] vs. [[64 bit]].
 
Ada beberapa isu utama saat menulis kode yang portabel sehubungan dengan arsitektur prosesor: endianness dan prosesor [[32 bit|32]] vs. [[64 bit]].
  
 
== Endianness ==
 
== Endianness ==
  
Endianness is the way how values larger than a [[Byte|byte]] (e.g. 16/32/64-bit
+
Endianness adalah cara bagaimana nilai lebih besar dari sebuah [[Byte|byte]] (misalnya 16/32/64-bit
[[Integer|integers]]) are stored by the processor.  
+
[[Integer|integers]]) disimpan oleh prosesor.  
  
Free Pascal supports processors with two types of endianness:
+
Free Pascal mendukung prosesor dengan dua jenis endianness:
  
# Store the lowest value on the lowest address;  longint(4) encoded as 04 00 00 00  (''[http://en.wikipedia.org/wiki/Little_endian little endian]'')
+
# Menyimpan nilai terendah pada alamat terendah;  longint(4) dienkode sebagai 04 00 00 00  (''[http://en.wikipedia.org/wiki/Little_endian little endian]'')
# Store the highest value on the lowest address;  longint(4) encoded as 00 00 00 04 (''[http://en.wikipedia.org/wiki/Big_endian big endian]'')
+
# Menyimpan nilai tertingi pada alamat terendah;  longint(4) dienkode sebagai 00 00 00 04 (''[http://en.wikipedia.org/wiki/Big_endian big endian]'')
  
side note:
+
catatan samping:
  
Middle endian, also called mixed endian, processors are rare nowadays. The best known, but now historic, middle endian processor is the [http://en.wikipedia.org/wiki/PDP-11 PDP-11] from DEC.
+
Endian tengah, juga disebut endian campuran, prosesor jarang sekarang. Yang terkenal, tapi sekarang menjadi historis, prosesor endian menengah adalah [http://en.wikipedia.org/wiki/PDP-11 PDP-11] dari DEC.
  
Endianness is generally a given choice per processor family, but some families of processors can be either big endian or little endian depending on the mainboard they are attached to (ARM, PPC).
+
Endianness adalah pilihan umum yang diberikan per keluarga prosesor, tapi beberapa keluar prosesor dapat berupa endian besar atau endian kecil pada mainboard yang disertakannya (ARM, PPC).
  
The best known little endian processor family is x86, the processor family used in PCs, and its brethren x86-64. Typical big endian processors are PPC (usually, see above note), and [http://en.wikipedia.org/wiki/68k m68k], many older systems such as the [http://en.wikipedia.org/wiki/HP3000 HP3000] minicomputers, and mainframes such as the [http://en.wikipedia.org/wiki/IBM_370 IBM 370] (Z series).
+
Prosesor endian kecil yang paling terkenal adalah keluarga x86, keluar prosesor yang digunakan dalam PC, dan yang terbarunya x86-64. Prosesor umum endian besar adalah PPC (biasanya, lihat catatan di atas), dan [http://en.wikipedia.org/wiki/68k m68k], banyak sistem lebih lama seperti misalnya [http://en.wikipedia.org/wiki/HP3000 HP3000] minikomputer, dan mainframes seperti [http://en.wikipedia.org/wiki/IBM_370 IBM 370] (seri Z).
  
Since TCP/IP specifies that all protocol header structures that go over the wire should be big endian, so this notation is sometimes also refered to as ''network order''.
+
Karena TCP/IP menetapkan bahwa semua struktur header protokol yag bejalan di atas kawat harus endian besar, maka notasi ini kadang-kadang dirujuk sebagai ''urutan jaringan''.
  
Endianness is important
+
Endianness adalah penting
# when exchanging data between different architectures
+
# ketika bertukar data antara arsitektur yang bebeda
# when accessing data sometimes as (an array of) a larger type, like integer, and sometimes as (an array of) a byte.
+
# ketika mengakses data kadang-kadang sebagai (sebuah array dari) tipe lebih besar, seperti integer, dan kadangkala sebagai (sebuah array dari) byte.
  
An example of the latter:
+
Contoh yang terakhir:
  
 
<TT>
 
<TT>
Line 56: Line 58:
  
 
</tt>
 
</tt>
On little endian machines (PCs), the above code will write 5 (since longint(5) is stored as 05 00 00 00 in memory), while on big endian machines (e.g. Powermacs) it will write 0 (since longint(5) is stored as 00 00 00 05 in memory).  (If you get the report your machine is indeterminate, please report on this wiki page what processor does this and what you get!)
+
Pada mesin endian kecil (PCs), kode di atas akan menulis 5 (karena longint(5) disimpan sebagai 05 00 00 00 dalam memori), sementara pada mesin endian besar (contohnya Powermacs) ia akan menulis 0 (karena longint(5) disimpan sebagai 00 00 00 05 dalam memori).  (Jika anda mendapatkan laporan mesin anda adalah menengah, silahkan laporkan pada halaman wiki ini apa yang tidak didapatkan dan didapatkan prosesor ini!)
  
To determine the endianness of the processor, use the ENDIAN_BIG or ENDIAN_LITTLE (or FPC_LITTLE_ENDIAN and FPC_BIG_ENDIAN starting from version 1.9) defines that are defined by freepascal automatically depending on the processor.
+
Untuk menentukan endianness dari sebuah prosesor, gunakan ENDIAN_BIG atau ENDIAN_LITTLE (atau FPC_LITTLE_ENDIAN dan FPC_BIG_ENDIAN mulai dari versi 1.9) mendefinisikan bahwa didefinisikan oleh freepascal secara otomatis tergantung pada prosesor.
  
 
== Penjajaran ==
 
== Penjajaran ==
  
Some processors will allow improperly aligned data but with reduced efficiency (IBM 370/zSeries).  Some processors generate hardware processor exceptions when data is badly aligned (e.g. Alpha or ARM).  Sometimes the hardware exceptions are caught and fixed using emulation by the OS, but this is very slow, and should be avoided. This can also cause records to have different sizes, so always use sizeof(recordtype); as size of a record. If you define a packed record, try to ensure that data is naturally aligned, if possible. Some processors only have alignment requirements for certain types of data, like floating point (e.g. older PowerPCs).  
+
Beberapa prosesor akan membolehkan penjajaran data yang tidak benar dengan mengurangi efisiensi (IBM 370/zSeries).  Beberapa prosesor membuat eksepsi prosesor hardware saat data dijajarkan dengan buruk (misalnya Alpha atau ARM).  Adakalanya eksepsi hardware ditangkap dan dibetulkan menggunakan emulasi oleh OS, tapi ini sangat lambat, dan harus dihindari. Ini juga bisa menyebabkan records harus mempunyai ukuran berbeda, maka selalu gunakan sizeof(recordtype); sebagai ukuran record. Jika anda mendefinisikan packed record, coba untuk memastikan bahwa data dijajarkan secara alami, bila memungkinkan. Beberapa prosesor hanya menjajarkan persyaratan untuk tipe data tertentu, seperti floating point (misalnya PowerPC lama).  
  
To check if the CPU requires proper alignment, check the FPC_REQUIRES_PROPER_ALIGNMENT (version 1.9 and higher) defineOn 32 Bit CPUs this usually means that data up to a size of 4 must be naturally aligned. If you want to access unaligned data, use the [[move]] procedure to move it to an aligned location before processing it. The move procedure takes care of unaligned data and handles it properly.
+
Untuk memeriksa apakah CPU memerlukan penjajaran yang benar, periksa definisi FPC_REQUIRES_PROPER_ALIGNMENT (versi 1.9 dan lebih tinggi).  Pada CPU 32 Bit ini biasanya berarti bahwa data sampai ukuran 4 harus dijajarkan secara alami. Jika anda ingin mengakses data unaligned, gunakan prosedur [[move]] untuk memindahkannya ke lokasi aligned sebelum memprosesnya. Prosedur move memelihara data unaligned dan menanganinya dengan benar.
  
There are multiple strategies for aligning:
+
Ada multipel strategi untuk penjajaran:
* align every field on a multiple of a certain value (typically a power of two, 1,2,4,8.  1 is equivalent to "packed")
+
* jajarkan setiap field pada multipel nilai tertentu (biasanya pangkat dua, 1,2,4,8.  1 sama dengan "packed")
* pad before every field such that it is aligned on a multiple of its size (so a longint on 4, an int64 on 8 bytes etc). This is typically done by C compiler, which is why FPC calls it {$packrecords C}.  
+
* padatkan sebelum setiap field yang dijajarkan pada multipel ukurannya (maka longint pada 4, int64 pada 8 bytes dll). Ini biasanya dikerjakan oleh kompilator C, yang mengapa FPC memanggilnya {$packrecords C}.  
  
(For [[array]]s or [[nested record]]s, the size of their largest sub unit is used)
+
(Untuk [[Array/id|array]] atau [[nested record/id|nested record]], ukuran sub unit terbesarnya yang digunakan)
  
Mac OS X {$packrecords C} seems to pad the entire record at the end to make it a certain size. This is still being investigated, and probably will be fixed in compiler.
+
Mac OS X {$packrecords C} nampaknya memadatkan seluruh record di akhir guna memastikan ukuran tertentu. Ini masih diinvestigasi, dan mungkin akan dibetulkan dalam kompilator.
  
 
== 32 Bit vs. 64 Bit ==
 
== 32 Bit vs. 64 Bit ==
  
To achive maximum compatiblity with older code, FPC doesn't change the size of predefined data types like <tt>[[Integer|integer]]</tt>, <tt>[[longint]]</tt> or <tt>[[word]]</tt> when changing from 32 to 64 Bit. However, the size of a pointer is 8 bytes on a 64 bit architecture so constructs like <tt>longint([[pointer]](p))</tt> are doomed to crash on 64 bit architectures. However, to allow you to write portable code, the FPC system unit introduces the types <tt>[[Ptrint|PtrInt]]</tt> and <tt>[[Ptruint|PtrUInt]]</tt> which are signed and unsigned integer data types with the same size as a pointer.
+
Untuk mencapai kompatibilitas maksimum dengan kode lebih lama, FPC tidak mengubah ukuran tipe data yang sudah didefinisikan seperti <tt>[[Integer|integer]]</tt>, <tt>[[longint]]</tt> atau <tt>[[Word|word]]</tt> ketika mengubah dari 32 ke 64 Bit. Akan tetapi, ukuran pointer adalah 8 byte pada arsitektur 64 bit maka membentuk seperti <tt>longint([[pointer]](p))</tt> pasti rusak pada arsitektur 64 bit. Untuk membolehkan anda menulis kode portabel, unit system FPC memperkenalkan tipe <tt>[[Ptrint|PtrInt]]</tt> dan <tt>[[Ptruint|PtrUInt]]</tt> yang adalah tipe data integer signed dan unsigned dengan ukuran yang sama sebagai sebuah pointer.
  
Keep in mind that the size change of the "pointer" type also affects record sizes. If you allocate records with fixed sizes, and not with [[new]] or with [[getmem]] (<x>,[[sizeof]](<x>)), this will have to be fixed.
+
Harap diingat bahwa perubahan ukuran dari tipe "pointer" juga mempengaruhi ukuran record. Jika anda mengalokasikan records dengan ukuran tetap, dan tidak dengan [[new]] atau dengan [[getmem]] (<x>,[[sizeof]](<x>)), ini harus dibetulkan.
  
This is in line with most open Unix platforms. In the commercial world, there are some exceptions like Tru64, with is ILP64
+
Ini adalah baris dengan platform Unix paling terbuka. Dalam dunia komersial, ada beberapa kekecualian seperti Tru64, yang adalah ILP64
  
 
== Konvensi pemanggilan ==
 
== Konvensi pemanggilan ==
  
* For IBM 370 and zSeries, see the [[ZSeries]] page for further discussion.
+
* Untuk IBM 370 dan zSeries, lihat halaman [[ZSeries]] untuk diskusi lebih jauh.
  
In general avoid relying on internal knowledge, like if a pass by const is on the stack or by value.
+
Secara umum, hindari ketergantungan pada pengetahuan internal, seperti jika dikirimkan oleh const pada stack atau dengan value.
  
 
=== x86 ===
 
=== x86 ===

Latest revision as of 00:39, 26 October 2015

English (en) Bahasa Indonesia (id) русский (ru)

Ada beberapa isu utama saat menulis kode yang portabel sehubungan dengan arsitektur prosesor: endianness dan prosesor 32 vs. 64 bit.

Endianness

Endianness adalah cara bagaimana nilai lebih besar dari sebuah byte (misalnya 16/32/64-bit integers) disimpan oleh prosesor.

Free Pascal mendukung prosesor dengan dua jenis endianness:

  1. Menyimpan nilai terendah pada alamat terendah; longint(4) dienkode sebagai 04 00 00 00 (little endian)
  2. Menyimpan nilai tertingi pada alamat terendah; longint(4) dienkode sebagai 00 00 00 04 (big endian)

catatan samping:

Endian tengah, juga disebut endian campuran, prosesor jarang sekarang. Yang terkenal, tapi sekarang menjadi historis, prosesor endian menengah adalah PDP-11 dari DEC.

Endianness adalah pilihan umum yang diberikan per keluarga prosesor, tapi beberapa keluar prosesor dapat berupa endian besar atau endian kecil pada mainboard yang disertakannya (ARM, PPC).

Prosesor endian kecil yang paling terkenal adalah keluarga x86, keluar prosesor yang digunakan dalam PC, dan yang terbarunya x86-64. Prosesor umum endian besar adalah PPC (biasanya, lihat catatan di atas), dan m68k, banyak sistem lebih lama seperti misalnya HP3000 minikomputer, dan mainframes seperti IBM 370 (seri Z).

Karena TCP/IP menetapkan bahwa semua struktur header protokol yag bejalan di atas kawat harus endian besar, maka notasi ini kadang-kadang dirujuk sebagai urutan jaringan.

Endianness adalah penting

  1. ketika bertukar data antara arsitektur yang bebeda
  2. ketika mengakses data kadang-kadang sebagai (sebuah array dari) tipe lebih besar, seperti integer, dan kadangkala sebagai (sebuah array dari) byte.

Contoh yang terakhir:

Type
     Q = RECORD
         case boolean of
             true: (i:integer);
             false: (p:array[1..4] of byte)
     END;
Var x:^Q ;
begin
     new(x);
     x^.i:=5;
     if x^.p[1]=5 then
         writeln(x^.p[1],' Your machine is Little Endian')
     else
         if x^.p[4]=5 then
             writeln(x^.p[1],' Your machine is Big Endian')
         else
             writeln(x^.p[1],' ',x^.p[2],' ',x^.p[3],' ',x^.p[4],' Your machine''s endianness is indeterminate; please report the results to the compiler development team');
     writeln;
    {Make it wait so we can see the results }
     write('Press enter when you finish reading this ');
     readln;
end.

Pada mesin endian kecil (PCs), kode di atas akan menulis 5 (karena longint(5) disimpan sebagai 05 00 00 00 dalam memori), sementara pada mesin endian besar (contohnya Powermacs) ia akan menulis 0 (karena longint(5) disimpan sebagai 00 00 00 05 dalam memori). (Jika anda mendapatkan laporan mesin anda adalah menengah, silahkan laporkan pada halaman wiki ini apa yang tidak didapatkan dan didapatkan prosesor ini!)

Untuk menentukan endianness dari sebuah prosesor, gunakan ENDIAN_BIG atau ENDIAN_LITTLE (atau FPC_LITTLE_ENDIAN dan FPC_BIG_ENDIAN mulai dari versi 1.9) mendefinisikan bahwa didefinisikan oleh freepascal secara otomatis tergantung pada prosesor.

Penjajaran

Beberapa prosesor akan membolehkan penjajaran data yang tidak benar dengan mengurangi efisiensi (IBM 370/zSeries). Beberapa prosesor membuat eksepsi prosesor hardware saat data dijajarkan dengan buruk (misalnya Alpha atau ARM). Adakalanya eksepsi hardware ditangkap dan dibetulkan menggunakan emulasi oleh OS, tapi ini sangat lambat, dan harus dihindari. Ini juga bisa menyebabkan records harus mempunyai ukuran berbeda, maka selalu gunakan sizeof(recordtype); sebagai ukuran record. Jika anda mendefinisikan packed record, coba untuk memastikan bahwa data dijajarkan secara alami, bila memungkinkan. Beberapa prosesor hanya menjajarkan persyaratan untuk tipe data tertentu, seperti floating point (misalnya PowerPC lama).

Untuk memeriksa apakah CPU memerlukan penjajaran yang benar, periksa definisi FPC_REQUIRES_PROPER_ALIGNMENT (versi 1.9 dan lebih tinggi). Pada CPU 32 Bit ini biasanya berarti bahwa data sampai ukuran 4 harus dijajarkan secara alami. Jika anda ingin mengakses data unaligned, gunakan prosedur move untuk memindahkannya ke lokasi aligned sebelum memprosesnya. Prosedur move memelihara data unaligned dan menanganinya dengan benar.

Ada multipel strategi untuk penjajaran:

  • jajarkan setiap field pada multipel nilai tertentu (biasanya pangkat dua, 1,2,4,8. 1 sama dengan "packed")
  • padatkan sebelum setiap field yang dijajarkan pada multipel ukurannya (maka longint pada 4, int64 pada 8 bytes dll). Ini biasanya dikerjakan oleh kompilator C, yang mengapa FPC memanggilnya {$packrecords C}.

(Untuk array atau nested record, ukuran sub unit terbesarnya yang digunakan)

Mac OS X {$packrecords C} nampaknya memadatkan seluruh record di akhir guna memastikan ukuran tertentu. Ini masih diinvestigasi, dan mungkin akan dibetulkan dalam kompilator.

32 Bit vs. 64 Bit

Untuk mencapai kompatibilitas maksimum dengan kode lebih lama, FPC tidak mengubah ukuran tipe data yang sudah didefinisikan seperti integer, longint atau word ketika mengubah dari 32 ke 64 Bit. Akan tetapi, ukuran pointer adalah 8 byte pada arsitektur 64 bit maka membentuk seperti longint(pointer(p)) pasti rusak pada arsitektur 64 bit. Untuk membolehkan anda menulis kode portabel, unit system FPC memperkenalkan tipe PtrInt dan PtrUInt yang adalah tipe data integer signed dan unsigned dengan ukuran yang sama sebagai sebuah pointer.

Harap diingat bahwa perubahan ukuran dari tipe "pointer" juga mempengaruhi ukuran record. Jika anda mengalokasikan records dengan ukuran tetap, dan tidak dengan new atau dengan getmem (<x>,sizeof(<x>)), ini harus dibetulkan.

Ini adalah baris dengan platform Unix paling terbuka. Dalam dunia komersial, ada beberapa kekecualian seperti Tru64, yang adalah ILP64

Konvensi pemanggilan

  • Untuk IBM 370 dan zSeries, lihat halaman ZSeries untuk diskusi lebih jauh.

Secara umum, hindari ketergantungan pada pengetahuan internal, seperti jika dikirimkan oleh const pada stack atau dengan value.

x86

ARM

68K


navigation bar: data types
simple data types

boolean byte cardinal char currency double dword extended int8 int16 int32 int64 integer longint real shortint single smallint pointer qword word

complex data types

array class object record set string shortstring