Saya telah pemrograman dalam bahasa tingkat yang lebih tinggi (Python, C #, VBA, VB.NET) selama sekitar 10 tahun dan saya benar-benar tidak memahami apa yang terjadi, "di bawah tenda."
Saya bertanya-tanya apa manfaat dari belajar perakitan, dan bagaimana ini akan membantu saya sebagai seorang programmer? Bisakah Anda memberi saya sumber daya yang akan menunjukkan kepada saya persis hubungan antara apa yang saya tulis dalam kode tingkat yang lebih tinggi dengan apa yang terjadi dalam perakitan?
for
lingkaran dengan mendeklarasikan variabel di luarnya. contohJawaban:
Karena Anda akan memahami cara benar-benar bekerja.
Apa intinya adalah bahwa semua hal yang kita tulis dalam C # atau Python perlu diterjemahkan ke dalam urutan tindakan dasar yang dapat dieksekusi komputer. Sangat mudah untuk memikirkan komputer dalam hal kelas, generik dan daftar pemahaman tetapi ini hanya ada dalam bahasa pemrograman tingkat tinggi kami.
Kita dapat memikirkan konstruksi bahasa yang terlihat sangat bagus tetapi itu tidak diterjemahkan dengan sangat baik ke cara tingkat rendah dalam melakukan sesuatu. Dengan mengetahui cara kerjanya, Anda akan lebih memahami mengapa segala sesuatunya berjalan sebagaimana mestinya.
sumber
Ini akan memberi Anda pemahaman yang lebih baik tentang apa yang "terjadi di bawah tenda" dan bagaimana pointer bekerja dan makna variabel register dan arsitektur (alokasi dan manajemen memori, melewati parameter (berdasarkan nilai / dengan referensi), dll) secara umum.
Untuk mengintip cepat dengan C bagaimana ini?
kompilasi dengan
gcc -S so.c
dan lihat output assembly diso.s
:sumber
so.c
file standar untuk pertanyaan stackoverflow (seperti yang saya milikiso.py
,so.awk
dll) untuk menguji hal-hal dengan cepat. So.S .. :)gcc -O -c -g -Wa,-ahl=so.s so.c
Anda dapat melihat output perakitan untuk setiap baris kode C. Ini membuatnya sedikit lebih mudah untuk memahami apa yang sedang terjadi.5:so.c
menemukan kode untuk baris 5 dariso.c
.Saya pikir jawaban yang Anda cari ada di sini: http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language
Kutipan dari artikel:
Selain itu, saya akan merekomendasikan buku ini karena memiliki versi sederhana dari arsitektur komputer: Pengantar Sistem Komputasi: Dari Bits dan Gates ke C and Beyond, 2 / e Yale N. Patt, Universitas Texas di Austin Sanjay J. Patel, Universitas Illinois di Urbana / Champaign
sumber
Menurut pendapat saya yang sederhana, itu tidak banyak membantu.
Saya dulu tahu perakitan x86 dengan sangat baik. Itu sedikit membantu ketika perakitan muncul di kursus saya, muncul sekali selama wawancara, dan itu membantu saya membuktikan bahwa kompiler (Metrowerks) menghasilkan kode yang buruk. Sangat menarik bagaimana komputer sebenarnya bekerja, dan saya merasa secara intelektual lebih kaya karena telah mempelajarinya. Itu juga sangat menyenangkan untuk dimainkan saat itu.
Namun, kompiler hari ini lebih baik dalam menghasilkan perakitan daripada hampir semua orang di hampir semua bagian kode. Kecuali Anda menulis kompiler atau memeriksa apakah kompiler Anda melakukan hal yang benar, Anda mungkin membuang-buang waktu dengan mempelajarinya.
Saya akui bahwa banyak pertanyaan yang masih berguna diajukan oleh programmer C ++ diinformasikan dengan mengetahui assembly. Sebagai contoh: haruskah saya menggunakan variabel stack atau heap? saya harus melewati nilai atau referensi const? Namun, dalam hampir semua kasus, saya berpikir bahwa pilihan ini harus dibuat berdasarkan keterbacaan kode daripada penghematan waktu komputasi. (Misalnya, gunakan variabel tumpukan setiap kali Anda ingin membatasi variabel ke ruang lingkup.)
Saran saya yang sederhana adalah fokus pada keterampilan yang benar-benar penting: desain perangkat lunak, analisis algoritma, dan pemecahan masalah. Dengan pengalaman mengembangkan proyek-proyek besar, intuisi Anda akan meningkat, yang meningkatkan nilai Anda lebih dari sekadar mengetahui perakitan (menurut saya).
sumber
Anda harus terbiasa dengan satu level 'lebih dalam' dalam sistem yang sedang Anda kerjakan. Melewati terlalu jauh dalam sekali jalan tidak buruk, tetapi mungkin tidak membantu seperti yang diinginkan seseorang.
Seorang programmer dalam bahasa tingkat tinggi harus belajar bahasa tingkat yang lebih rendah (C adalah pilihan yang sangat baik). Anda tidak perlu pergi jauh-jauh ke perakitan untuk memiliki apresiasi terhadap apa yang terjadi di bawah selimut ketika Anda memberi tahu komputer untuk membuat instance objek, atau membuat tabel hash, atau set - tetapi Anda harus dapat membuat kode mereka.
Untuk seorang programmer java, mempelajari beberapa C akan membantu Anda dengan manajemen memori, melewati argumen. Menulis beberapa perpustakaan java yang luas di C akan pergi cara untuk memahami kapan harus menggunakan implementasi Set apa (Anda ingin hash? Atau tree?). Berurusan dengan char * di lingkungan berulir akan membantu memahami mengapa String tidak dapat diubah.
Dibawa ke tingkat berikutnya ... AC programmer harus memiliki pengetahuan tentang perakitan, dan jenis perakitan (sering ditemukan di toko-toko sistem tertanam) kemungkinan akan lebih baik dengan memahami hal-hal di tingkat gerbang. Mereka yang bekerja dengan gerbang harus mengetahui beberapa fisika kuantum. Dan para fisikawan kuantum itu, mereka masih berusaha mencari tahu apa abstraksi selanjutnya.
sumber
Karena Anda tidak menyebutkan C atau C ++ dalam bahasa yang Anda tahu daftar. Saya SANGAT merekomendasikan untuk mempelajarinya dengan baik bahkan sebelum berpikir tentang berkumpul. C atau C ++ akan memberikan semua konsep dasar yang benar-benar transparan dalam bahasa yang dikelola dan Anda akan memahami sebagian besar konsep yang disebutkan di halaman ini dengan salah satu bahasa paling penting yang dapat Anda gunakan dalam proyek dunia nyata. Ini adalah nilai tambah nyata untuk keterampilan pemrograman Anda. Perlu diketahui bahwa rakitan digunakan di area yang sangat spesifik dan hampir tidak berguna seperti C atau C ++.
Saya bahkan akan melangkah lebih jauh dengan mengatakan bahwa Anda tidak harus terjun ke kebaktian sebelum memahami cara kerja bahasa yang tidak dikelola. Ini hampir merupakan bacaan wajib.
Anda harus belajar perakitan jika Anda ingin melangkah lebih jauh ke bawah. Anda ingin tahu bagaimana tepatnya setiap konstruksi bahasa dibuat. Ini informatif tetapi tingkat kerumitannya sangat berbeda.
sumber
Jika Anda tahu bahasa dengan baik, Anda harus memiliki setidaknya pengetahuan dasar tentang teknologi satu tingkat abstraksi yang lebih rendah.
Mengapa? Ketika terjadi kesalahan, pengetahuan tentang mekanisme yang mendasari membuatnya jauh lebih mudah untuk men-debug masalah aneh, dan secara alami menulis kode yang lebih efisien
Menggunakan Python (/ CPython) sebagai contoh, jika Anda mulai mendapatkan crash aneh atau kinerja buruk, pengetahuan tentang cara men-debug kode C bisa sangat berguna, sama seperti pengetahuan tentang penghitungan ulang metode manajemen memori. Ini juga akan membantu Anda mengetahui kapan / jika menulis sesuatu sebagai ekstensi C, dan seterusnya ...
Untuk menjawab pertanyaan Anda dalam hal ini, pengetahuan tentang perakitan benar-benar tidak akan membantu pengembang Python yang berpengalaman (terlalu banyak langkah dalam abstraksi - apa pun yang dilakukan dengan Python akan menghasilkan banyak instruksi perakitan)
..tapi, jika Anda berpengalaman dengan C, maka mengetahui "level selanjutnya turun" (perakitan) memang akan berguna.
Demikian pula, jika Anda menggunakan CoffeScript maka (sangat) berguna untuk mengetahui Javascript. Jika Anda menggunakan Clojure, pengetahuan tentang Java / JVM berguna.
Ide ini juga berfungsi di luar bahasa pemrograman - jika Anda menggunakan Assembly, ide yang bagus untuk membiasakan diri dengan bagaimana fungsi perangkat keras yang mendasarinya. Jika Anda seorang perancang web, ide yang baik untuk mengetahui bagaimana aplikasi web diimplementasikan. Jika Anda seorang mekanik mobil, sebaiknya memiliki pengetahuan tentang beberapa fisika
sumber
Tuliskan program c kecil, dan bongkar hasilnya. Itu saja. Namun, bersiaplah untuk kode "housekeeping" yang lebih besar atau lebih kecil yang ditambahkan untuk kepentingan Sistem Operasi.
Majelis membantu Anda memahami apa yang terjadi di bawah kap karena berhubungan langsung dengan memori, register prosesor dan sejenisnya.
Jika Anda benar-benar ingin menggunakan bare-metal tanpa semua kerumitan sistem operasi yang menyulitkan, coba pemrograman Arduino dalam bahasa assembly.
sumber
Tidak ada jawaban pasti, karena programmer tidak semuanya tipe. Apakah Anda PERLU untuk tahu apa yang mengintai di bawahnya? Jika demikian, maka pelajari. apakah Anda hanya ingin mempelajarinya, karena penasaran? Jika demikian, maka pelajari. Jika itu tidak memiliki manfaat praktis bagi Anda, lalu mengapa repot-repot? Apakah seseorang membutuhkan tingkat pengetahuan mekanik hanya untuk mengendarai mobil? Apakah montir membutuhkan tingkat pengetahuan insinyur, hanya untuk bekerja di mobil? Ini analogi yang serius. Seorang mekanik dapat menjadi mekanik yang sangat baik, produktif tanpa menyelam untuk merekayasa kedalaman pemahaman tentang kendaraan yang dipeliharanya. Sama untuk musik. Apakah Anda benar-benar menyelami kompleksitas melodi, harmoni dan ritme untuk menjadi penyanyi atau pemain yang baik? Tidak. Beberapa musisi yang sangat berbakat tidak dapat membaca sedikitpun musik, apalagi memberi tahu Anda perbedaan antara mode Dorian dan Lydian. Jika Anda ingin, baik-baik saja, tetapi tidak, Anda tidak perlu melakukannya. Jika Anda seorang pengembang web, majelis tidak memiliki penggunaan praktis yang dapat saya pikirkan. Jika Anda berada di sistem tertanam atau sesuatu yang sangat khusus, maka mungkin diperlukan, tetapi jika ya, Anda akan mengetahuinya.
Inilah pendapat Joel tentang nilai bersandar pada bahasa tingkat tinggi: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html
sumber
Sebenarnya, apa yang mungkin terbaik untuk Anda adalah kelas yang tidak (sepengetahuan saya) ada di mana saja: Ini akan menjadi kelas yang menggabungkan tinjauan singkat tentang bahasa mesin / assembler dan konsep penyimpanan yang menangani dengan tur melalui konstruksi kompiler , pembuatan kode, dan lingkungan runtime.
Masalahnya adalah bahwa dengan bahasa tingkat tinggi, jauh dari perangkat keras seperti C # atau Python Anda tidak benar-benar menghargai kenyataan bahwa setiap gerakan yang Anda lakukan berubah menjadi ratusan jika tidak ribuan instruksi mesin, dan Anda tidak cenderung memahami bagaimana beberapa baris bahasa tingkat tinggi dapat menyebabkan sejumlah besar penyimpanan diakses dan dimodifikasi. Anda tidak perlu tahu persis apa yang sedang terjadi "di balik selimut", tetapi Anda perlu memiliki apresiasi untuk ruang lingkup apa yang terjadi, dan konsep umum tentang jenis hal yang terjadi.
sumber
Jawaban saya untuk pertanyaan ini telah berkembang relatif baru-baru ini. Jawaban yang ada mencakup apa yang akan saya katakan di masa lalu. Sebenarnya, ini masih dicakup oleh jawaban atas - titik "menghargai konstruk dalam pemrograman tingkat tinggi", tapi ini adalah kasus khusus yang menurut saya layak disebutkan ...
Menurut posting blog Jeff Atwood ini , yang merujuk pada penelitian, memahami tugas adalah masalah utama dalam memahami pemrograman. Pemrogram pelajar memahami bahwa notasi hanya mewakili langkah-langkah yang diikuti oleh komputer, dan alasan demi langkah, atau kalau tidak terus menerus menjadi bingung dengan analogi yang menyesatkan dengan persamaan matematika dll.
Nah, jika Anda memahami yang berikut dari 6502 assembler ...
Itu benar-benar hanya langkah-langkahnya. Kemudian ketika Anda belajar menerjemahkannya ke pernyataan tugas ...
Anda tidak perlu analogi yang menyesatkan dengan persamaan matematika - Anda sudah memiliki model mental yang tepat untuk memetakannya.
EDIT - tentu saja jika penjelasan yang Anda dapatkan
LDA variable
pada dasarnyaACCUMULATOR = variable
, yang persis seperti yang Anda dapatkan dari beberapa tutorial dan referensi, Anda akhirnya kembali ke tempat Anda memulai dan sama sekali tidak membantu.Saya belajar 6502 assembler sebagai bahasa kedua saya, yang pertama adalah Commodore Basic, dan saya belum benar-benar belajar banyak tentang itu pada saat itu - sebagian karena ada begitu sedikit yang harus dipelajari, tetapi juga karena assembler hanya tampak jauh lebih menarik saat itu . Sebagian waktu, sebagian karena saya adalah seorang geek berusia 14 tahun.
Saya tidak merekomendasikan melakukan apa yang saya lakukan, tetapi saya ingin tahu apakah mempelajari beberapa contoh yang sangat sederhana dalam bahasa assembler yang sangat sederhana mungkin merupakan awal yang bermanfaat untuk belajar bahasa tingkat yang lebih tinggi.
sumber
Kecuali jika Anda seorang penulis kompiler, atau membutuhkan sesuatu yang sangat dioptimalkan (seperti algoritma pemrosesan data), mempelajari kode perakitan tidak akan memberikan manfaat apa pun.
Menulis dan memelihara kode yang ditulis dalam kumpulan sangat sulit, oleh karena itu bahkan jika Anda tahu bahasa assembler dengan sangat baik, Anda tidak boleh menggunakannya, kecuali tidak ada cara lain.
Artikel " Mengoptimalkan untuk SSE: Studi Kasus " menunjukkan apa yang mungkin dilakukan jika Anda pergi ke pertemuan. Penulis berhasil mengoptimalkan algoritma dari 100 siklus / vektor menjadi 17 siklus / vektor.
sumber
Menulis dalam kumpulan tidak akan memberi Anda peningkatan kecepatan ajaib karena jumlah detail (alokasi register dll.) Anda mungkin akan menulis algoritma paling sepele yang pernah ada.
Selain itu dengan perakitan prosesor modern (baca - dirancang setelah 70-80-an) tidak akan memberikan Anda jumlah detail yang cukup untuk mengetahui apa yang sedang terjadi (yaitu - pada sebagian besar prosesor). PU modern (CPU dan GPU) cukup kompleks sejauh instruksi penjadwalan pergi. Mengetahui dasar-dasar perakitan (atau pseudoassembly) akan memungkinkan untuk memahami buku / kursus arsitektur komputer yang akan memberikan pengetahuan lebih lanjut (cache, eksekusi out-of-order, MMU dll). Biasanya Anda tidak perlu tahu ISA yang rumit untuk memahaminya (MIPS 5 adalah IIRC yang cukup populer).
Mengapa mengerti prosesor? Mungkin memberi Anda lebih banyak pemahaman tentang apa yang terjadi. Katakanlah Anda menulis perkalian matriks dengan cara naif:
Ini mungkin 'cukup baik' untuk tujuan Anda (jika matriksnya 4x4 mungkin akan dikompilasi dengan instruksi vektor). Namun ada beberapa program yang cukup penting ketika Anda mengkompilasi array besar - bagaimana cara mengoptimalkannya? Jika Anda menulis kode dalam perakitan, Anda mungkin memiliki beberapa% peningkatan (kecuali jika Anda akan melakukan seperti yang dilakukan kebanyakan orang - juga dengan cara naif, register yang kurang dimanfaatkan, memuat / menyimpan ke memori secara terus-menerus dan akibatnya memiliki program yang lebih lambat daripada dalam bahasa HL) .
Namun Anda dapat membalikkan baris dan secara ajaib mendapatkan kinerja (mengapa? Saya meninggalkannya sebagai 'pekerjaan rumah') - IIRC tergantung pada berbagai faktor untuk matriks besar bahkan bisa 10x.
Yang mengatakan - ada yang bekerja pada kompiler yang mampu melakukannya ( grafit untuk gcc dan Polly untuk apa pun yang menggunakan LLVM). Mereka bahkan mampu mengubahnya menjadi (maaf - saya menulis pemblokiran dari memori):
Untuk meringkas - mengetahui dasar-dasar perakitan memungkinkan Anda untuk menggali berbagai 'detail' dari desain prosesor yang akan memungkinkan Anda untuk menulis program lebih cepat. Mungkin baik untuk mengetahui perbedaan antara arsitektur RISC / CISC atau VLIW / vektor prosesor / SIMD / .... Namun saya tidak akan mulai dengan x86 karena mereka cenderung cukup rumit (mungkin ARM juga) - mengetahui apa itu register dll adalah IMHO cukup untuk memulai.
sumber
Biasanya itu SANGAT penting untuk keperluan debugging. Apa yang Anda lakukan ketika sistem rusak di tengah instruksi dan kesalahan itu tidak masuk akal? Ini jauh dari masalah dengan bahasa .NET selama Anda hanya menggunakan kode aman - sistem hampir selalu akan melindungi Anda dari apa yang terjadi di bawah tenda.
sumber
Singkatnya saya pikir jawabannya adalah karena Anda dapat melakukan lebih banyak jika Anda belajar berkumpul. Unit pembelajaran memberikan akses ke bidang pemrograman perangkat tertanam, penetrasi dan pencegahan keamanan, rekayasa balik, dan pemrograman sistem yang sangat sulit untuk dikerjakan jika Anda tidak tahu assembler.
Sedangkan untuk mempelajarinya untuk meningkatkan kinerja program, ini diragukan dalam pemrograman aplikasi. Sebagian besar waktu ada begitu banyak hal yang harus difokuskan terlebih dahulu sebelum mencapai tingkat optimasi ini seperti mengoptimalkan akses i / o Anda pada disk dan jaringan, mengoptimalkan cara Anda membangun GUI, memilih algoritma yang tepat, memaksimalkan semua inti Anda , menjalankan uang perangkat keras terbaik dapat membeli dan beralih dari ditafsirkan ke bahasa yang dikompilasi. Kecuali jika Anda membuat perangkat lunak untuk pengguna akhir lainnya, perangkat keras lebih murah dibandingkan dengan upah per jam programmer, terutama dengan ketersediaan cloud.
Juga, Anda harus mempertimbangkan peningkatan kecepatan eksekusi program dengan keterbacaan kode Anda setelah Anda ditabrak bus, berhenti atau kembali ke basis kode untuk mengubahnya setahun setelah Anda menulis versi terakhir.
sumber
Saya akan merekomendasikan algoritma pembelajaran: pengurutan, daftar tertaut, pohon biner, hashing, dll.
Pelajari juga lisp, lihat Struktur dan Interpretasi Program Komputer beberapa perintah primitif, satu primitif cadel dan beberapa assembler provokatif).
Akhirnya jika Anda harus belajar assembler, pelajari yang mudah seperti ARM (juga digunakan di sekitar 4 kali lebih banyak perangkat daripada x86).
sumber
Yah, jawabannya adalah hanya karena bahasa yang Anda gunakan harus ditafsirkan atau dikompilasi menjadi assembler pada akhirnya. Tidak masalah bahasa atau mesin.
Desain bahasa berasal dari cara CPU bekerja. Lebih banyak pada program tingkat rendah, lebih sedikit pada program tingkat tinggi.
Saya akan mengakhiri dengan mengatakan bahwa Anda tidak hanya perlu mengetahui assembler kecil tetapi juga arsitektur CPU, yang Anda pelajari dengan mempelajari assembler.
Beberapa contoh: Ada banyak programmer java yang tidak mengerti mengapa ini tidak berhasil, dan bahkan kurang tahu apa yang terjadi ketika Anda menjalankannya.
Jika Anda tahu assembler kecil, Anda akan selalu tahu bahwa itu tidak sama dengan isi dari lokasi memori vs angka dalam variabel pointer yang "menunjuk" ke lokasi itu.
Lebih buruk lagi, bahkan dalam buku yang diterbitkan Anda akan membaca sesuatu seperti di JAWA primitif dilewatkan oleh nilai dan objek dengan referensi, yang sama sekali tidak benar. Semua argumen di Java diteruskan oleh nilai, dan Java TIDAK bisa meneruskan objek ke fungsi, hanya pointer, yang diteruskan oleh nilai.
Jika Anda sekarang memahami apa yang sedang terjadi, jika tidak begitu rumit untuk menjelaskan bahwa sebagian besar penulis hanya memberikan Anda kebohongan yang saleh.
Tentu saja, konsekuensi dari ini tidak kentara tetapi dapat membuat Anda dalam masalah nyata di kemudian hari. Jika Anda tahu assembler itu bukan masalah, jika tidak, Anda berada dalam proses debugging yang panjang.
sumber
String a = "X"; String b = "X"; if( a==b) return true;
yang sebenarnya== true
karena sesuatu yang disebutString interning
kompiler tidak. Semua pernyataan Java lainnya juga salah. Java tidak memiliki pointer, ia memiliki referensi yang bukan hal yang sama. Dan tidak ada satupun yang ada hubungannya dengan assembler dengan cara apa pun. Java melewati primitif berdasarkan nilai dan juga referensi berdasarkan nilai. Java tidak memiliki pointer sehingga tidak dapat melewati mereka dengan apa pun. Sekali lagi semua tidak relevan untuk mengetahui ASM.