Untuk apa register "FS" / "GS"?

103

Jadi saya tahu register berikut apa dan penggunaannya seharusnya:

  • CS = Code Segment (digunakan untuk IP)

  • DS = Segmen Data (digunakan untuk MOV)

  • ES = Segmen Tujuan (digunakan untuk MOVS, dll.)

  • SS = Stack Segment (digunakan untuk SP)

Tapi apa register berikut yang dimaksudkan untuk digunakan?

  • FS = "Segmen File"?

  • GS = ???

Catatan: Saya tidak bertanya tentang sistem operasi tertentu - Saya bertanya tentang apa yang dimaksudkan untuk digunakan oleh CPU, jika ada.

pengguna541686
sumber
24
Sejauh yang saya tahu, F dan G pada keduanya tidak berarti apa-apa. Hanya saja ada ruang pada CPU (dan dalam set instruksi) untuk enam register segmen yang dapat ditentukan pengguna, dan seseorang memperhatikan bahwa selain segmen tack "S", huruf "C" dan "D" (kode dan data) berada dalam urutan, jadi "E" adalah segmen "ekstra", lalu "F" dan "G" hanya diikuti.
torek
3
Bisa jadi, selalu sulit untuk mengetahui apa yang sedang terjadi di kepala orang lain kecuali Anda ada di sana pada saat itu (dan saya berada di pantai lain, tidak jauh dari tim desain Intel).
torek
20
Coba pikirkan betapa menyenangkannya kami dengan register BS: -}
Ira Baxter
5
Saya selalu menggunakan GS sebagai "Segmen Grafik". :-)
Brian Knoblauch
2
Bagaimana dengan "G" eneral "S"?
SS Anne

Jawaban:

110

Ada tujuan mereka, dan untuk apa mereka digunakan oleh Windows dan Linux.

Maksud asli di balik register segmen adalah untuk memungkinkan program mengakses banyak segmen memori yang berbeda (besar) yang dimaksudkan untuk menjadi independen dan bagian dari penyimpanan virtual yang persisten. Idenya diambil dari sistem operasi Multics 1966 , yang memperlakukan file sebagai segmen memori yang dapat dialamatkan. Tidak ada BS "Buka file, tulis catatan, tutup file", cukup "Simpan nilai ini ke dalam segmen data virtual" dengan pembilasan halaman kotor.

Sistem operasi 2010 kami saat ini merupakan langkah mundur raksasa, itulah sebabnya mereka disebut "Eunuchs". Anda hanya dapat menangani segmen tunggal ruang proses Anda , memberikan apa yang disebut "ruang alamat datar (IMHO tumpul)". Register segmen pada mesin x86-32 masih dapat digunakan untuk register segmen sebenarnya, tetapi tidak ada yang peduli (Andy Grove, mantan presiden Intel, memiliki kecocokan publik yang cukup terkenal abad lalu ketika dia mengetahui setelah semua insinyur Intel menghabiskan energi dan uangnya untuk mengimplementasikan fitur ini, sehingga tidak ada yang akan menggunakannya. Ayo, Andy!)

AMD dalam 64 bit memutuskan mereka tidak peduli jika mereka menghilangkan Multics sebagai pilihan (itulah interpretasi amal; yang tidak ramah adalah mereka tidak tahu apa-apa tentang Multics) dan karenanya menonaktifkan kemampuan umum register segmen dalam mode 64 bit. Masih ada kebutuhan utas untuk mengakses utas penyimpanan lokal, dan setiap utas membutuhkan penunjuk ... di suatu tempat dalam status utas yang segera dapat diakses (misalnya, di register) ... ke utas penyimpanan lokal. Karena Windows dan Linux sama-sama menggunakan FS dan GS (terima kasih Nick atas klarifikasinya) untuk tujuan ini dalam versi 32 bit, AMD memutuskan untuk membiarkan register segmen 64 bit (GS dan FS) digunakan pada dasarnya hanya untuk tujuan ini (saya pikir Anda bisa buat mereka menunjuk ke mana saja di ruang proses Anda; tidak tahu apakah kode aplikasi dapat memuatnya atau tidak).

Ini akan menjadi IMHO yang lebih cantik secara arsitektural untuk membuat setiap peta memori utas memiliki alamat virtual absolut (misalnya, 0-FFF katakanlah) yang merupakan penyimpanan lokal utasnya (tidak diperlukan penunjuk register [segmen]!); Saya melakukan ini di OS 8 bit pada tahun 1970-an dan itu sangat berguna, seperti memiliki setumpuk register besar lainnya untuk dikerjakan.

Jadi, register segmen sekarang seperti lampiran Anda. Mereka melayani tujuan vestigial. Untuk kerugian kolektif kita.

Mereka yang tidak tahu sejarah tidak ditakdirkan untuk mengulanginya; mereka ditakdirkan untuk melakukan sesuatu yang lebih bodoh.

Ira Baxter
sumber
11
@supercat: Skema yang lebih sederhana dan lebih cemerlang yang akan memungkinkan mereka menangani 65536 kali lebih banyak penyimpanan, akan memperlakukan register segmen sebagai ekstensi 16 bit atas penuh dari 16 bit bawah, yang pada intinya adalah 286, 386 dan Multics melakukannya.
Ira Baxter
4
@IraBaxter: Masalah dengan pendekatan itu adalah bahwa segmen bergaya 80286 memiliki overhead yang cukup tinggi daripada yang harus disimpan banyak objek di setiap segmen, dan dengan demikian menyimpan kedua segmen dan offset pada setiap penunjuk. Sebaliknya, jika seseorang bersedia untuk membulatkan alokasi memori hingga kelipatan 16 byte, segmentasi gaya 8086 memungkinkan seseorang untuk menggunakan segmen itu sendiri sebagai cara untuk mengidentifikasi objek. Membulatkan alokasi hingga 16 byte mungkin sedikit menjengkelkan pada tahun 1980, tetapi akan mewakili kemenangan hari ini jika ukuran referensi objek dikurangi dari 8 menjadi empat.
supercat
3
Register tersebut digunakan dalam sistem operasi modern. Mereka sebagian besar didedikasikan untuk menunjukkan informasi tentang blok kontrol tugas, setidaknya di dua OS utama yang sekarang tersedia untuk chip x86. Dan, karena mereka bukan lagi "tujuan umum" bahkan untuk maksud awalnya, Anda tidak dapat menggunakannya untuk banyak hal. Lebih baik berpura-pura pada sistem x86-64 bahwa mereka tidak ada sampai Anda membutuhkan informasi yang mereka biarkan Anda akses di blok kontrol thread.
Ira Baxter
5
Analogi usus buntu sangat buruk berdasarkan sains yang ketinggalan zaman; itu terkait dengan sistem kekebalan, jadi jelas bukan "sisa". Ini mengurangi pos sebenarnya. Selain itu, ini adalah respon yang bagus.
code_dredd
5
Terima kasih atas perlakuan yang lucu, tanpa batas dari memori tersegmentasi vs memori datar :) Setelah juga menulis kode pada 6809 (dengan dan tanpa memori paged), 6502, z80, 68k dan 80 [123]? 86, perspektif saya adalah tersegmentasi memori adalah pertunjukan horor dan saya senang itu dimasukkan ke tong sampah sejarah. Penggunaan FS dan GS untuk akses yang efisien dari data thread_local adalah konsekuensi yang tidak diinginkan dari kesalahan historis.
Richard Hodges
44

Register FSdan GSregister segmen. Mereka tidak memiliki tujuan yang ditentukan prosesor, tetapi diberi tujuan oleh OS yang menjalankannya. Di Windows 64-bit GSregister digunakan untuk menunjuk ke struktur yang ditentukan sistem operasi. FSdan GSbiasanya digunakan oleh kernel OS untuk mengakses memori khusus thread. Di windows, GSregister digunakan untuk mengelola memori khusus utas. Kernel linux digunakan GSuntuk mengakses memori khusus cpu.

sitinus
sumber
1
Apakah mereka dimaksudkan untuk digunakan untuk tujuan yang ditentukan OS, atau untuk memfasilitasi kode yang perlu melakukan sesuatu seperti *dest++ = lookup[*src++];yang sebaliknya akan menjadi agak canggung jika dest, lookup, dan src berada di tiga lokasi yang tidak terkait.
supercat
8
Pada Windows FS memang untuk penyimpanan khusus utas. Lihat peta terdokumentasi dari blok yang ditunjukkan oleh FS di sini en.wikipedia.org/wiki/Win32_Thread_Information_Block
Nedko
2
Bukan hanya di Windows. GS juga digunakan untuk TLS di OS X. GS juga digunakan oleh kernel 64bit untuk melacak struktur sistem selama sakelar konteks. OS akan menggunakan SWAPGS untuk itu.
ET
13

FS digunakan untuk menunjuk ke blok informasi benang (TIB) pada proses windows.

salah satu contoh tipikal adalah ( SEH ) yang menyimpan pointer ke fungsi callback di FS:[0x00].

GS biasanya digunakan sebagai penunjuk ke thread local storage (TLS). dan satu contoh yang mungkin pernah Anda lihat sebelumnya adalah stack canary protection (stackguard), di gcc Anda mungkin melihat sesuatu seperti ini:

mov    eax,gs:0x14
mov    DWORD PTR [ebp-0xc],eax
zerocool
sumber
2
Ini sebenarnya tidak menjawab pertanyaan itu. Pertanyaannya menyatakan Catatan: Saya tidak bertanya tentang sistem operasi tertentu - saya bertanya tentang apa yang dimaksudkan untuk digunakan oleh CPU, jika ada.
Michael Petch
10
@MichaelPetch ya saya tahu saya hanya ingin menambahkan ini sebagai info yang bagus untuk mereka yang membaca q / s ini di SO
zerocool
3

Menurut Manual Intel, dalam mode 64-bit register ini dimaksudkan untuk digunakan sebagai register basis tambahan dalam beberapa kalkulasi alamat linier. Saya menarik ini dari bagian 3.7.4.1 (hal 86 di set volume 4). Biasanya ketika CPU berada dalam mode ini, alamat linier sama dengan alamat efektif, karena segmentasi sering tidak digunakan dalam mode ini.

Jadi di ruang alamat datar ini, FS & GS berperan dalam menangani tidak hanya data lokal tetapi struktur data sistem operasi tertentu (hal 2793, bagian 3.2.4) sehingga register ini dimaksudkan untuk digunakan oleh sistem operasi, namun para perancang khusus tersebut menentukan.

Ada beberapa tipuan menarik saat menggunakan penggantian dalam mode 32 & 64-bit, tetapi ini melibatkan perangkat lunak dengan hak istimewa.

Dari perspektif "niat asli", itu sulit untuk dikatakan selain itu hanya register tambahan. Ketika CPU dalam mode alamat nyata , ini seperti prosesor berjalan dengan kecepatan tinggi 8086 dan register ini harus diakses secara eksplisit oleh program. Demi emulasi 8086 sejati, Anda akan menjalankan CPU dalam mode virtual-8086 dan register ini tidak akan digunakan.

Robert Houghton
sumber
2

TL; DR;

Untuk apa register "FS" / "GS"?

Cukup untuk mengakses data di luar segmen data default (DS). Persis seperti ES.


Baca Panjang:

Jadi saya tahu register berikut apa dan penggunaannya seharusnya:

[...]

Yah, hampir tetapi DS bukanlah 'beberapa' Segmen Data, tetapi yang default. Apakah semua operasi berlangsung secara default (* 1). Ini adalah semua variabel default berada - pada dasarnya datadan bss. Ini dalam beberapa hal merupakan alasan mengapa kode x86 agak kompak. Semua data penting, yang paling sering diakses, (plus kode dan tumpukan) berada dalam jarak singkat 16 bit.

ES digunakan untuk mengakses segala sesuatu yang lain (* 2), segala sesuatu di luar 64 KiB DS. Seperti teks dari pengolah kata, sel dari lembar kerja, atau data gambar dari program grafik dan seterusnya. Tidak seperti yang sering diasumsikan, data ini tidak banyak diakses, jadi membutuhkan prefiks tidak terlalu menyakitkan daripada menggunakan bidang alamat yang lebih panjang.

Serupa, itu hanya gangguan kecil bahwa DS dan ES mungkin harus dimuat (dan dimuat ulang) saat melakukan operasi string - ini setidaknya diimbangi oleh salah satu set instruksi penanganan karakter terbaik pada masanya.

Yang benar-benar menyakitkan adalah ketika data pengguna melebihi 64 KiB dan operasi harus dimulai. Sementara beberapa operasi hanya dilakukan pada satu item data pada satu waktu (pikirkan A=A*2), kebanyakan memerlukan dua ( A=A*B) atau tiga item data ( A=B*C). Jika item ini berada di segmen yang berbeda, ES akan dimuat ulang beberapa kali per operasi, menambahkan beberapa overhead.

Pada awalnya, dengan program kecil dari dunia 8 bit (* 3) dan set data yang sama kecilnya, itu bukan masalah besar, tetapi segera menjadi leher botol kinerja utama - dan lebih dari itu rasa sakit yang sebenarnya di pantat untuk programmer (dan kompiler). Dengan 386 Intel akhirnya memberikan bantuan dengan menambahkan dua segmen lagi, jadi setiap seri unary , binary atau ternary , dengan elemen yang tersebar di memori, dapat berlangsung tanpa memuat ulang ES sepanjang waktu.

Untuk pemrograman (setidaknya dalam perakitan) dan desain kompiler, ini cukup menguntungkan. Tentu saja, mungkin ada lebih banyak lagi, tetapi dengan tiga leher botol pada dasarnya sudah hilang, jadi tidak perlu berlebihan.

Penamaan bijaksana huruf F / G hanyalah lanjutan alfabet setelah E. Setidaknya dari sudut desain CPU tidak ada yang terkait.


* 1 - Penggunaan ES untuk tujuan string merupakan pengecualian, karena hanya diperlukan dua register segmen. Tanpa mereka tidak akan banyak berguna - atau selalu membutuhkan awalan segmen. Yang dapat mematikan salah satu fitur yang mengejutkan, penggunaan instruksi string (tidak berulang) yang menghasilkan kinerja ekstrim karena pengkodean byte tunggal mereka.

* 2 - Jadi kalau dipikir-pikir, 'Segmen Lain-Lain' akan menjadi penamaan yang jauh lebih baik daripada 'Segmen Tambahan'.

* 3 - Selalu penting untuk diingat bahwa 8086 hanya dimaksudkan sebagai pengukur celah berhenti sampai 8800 diselesaikan dan terutama ditujukan untuk dunia tertanam untuk mempertahankan 8080/85 pelanggan.

Raffzahn
sumber
1
Wow, terima kasih telah menjelaskan semua ini! Ini menjelaskan banyak hal dan sangat masuk akal! +1
pengguna541686