Mengapa program tidak ditulis di Majelis lebih sering? [Tutup]

216

Tampaknya menjadi pendapat umum bahwa pemrograman perakitan membutuhkan waktu lebih lama dan lebih sulit untuk diprogram daripada bahasa tingkat yang lebih tinggi seperti C. Oleh karena itu tampaknya direkomendasikan atau diasumsikan bahwa lebih baik menulis dalam bahasa tingkat yang lebih tinggi karena alasan ini dan untuk alasan portabilitas yang lebih baik.

Baru-baru ini saya telah menulis dalam perakitan x86 dan saya sadar bahwa mungkin alasan-alasan ini tidak benar, kecuali mungkin portabilitas. Mungkin itu lebih merupakan masalah keakraban dan mengetahui cara menulis majelis dengan baik. Saya juga memperhatikan bahwa pemrograman dalam perakitan sangat berbeda dari pemrograman dalam HLL. Mungkin programmer perakitan yang baik dan berpengalaman bisa menulis program dengan mudah dan secepat menulis programmer C yang berpengalaman dalam C.

Mungkin itu karena pemrograman perakitan sangat berbeda dari HLL, dan karenanya memerlukan pemikiran, metode dan cara yang berbeda, yang membuatnya tampak sangat canggung untuk memprogram untuk yang tidak terbiasa, dan karenanya memberikan nama buruknya untuk menulis program di.

Jika portabilitas bukan merupakan masalah, maka sungguh, apa yang akan dimiliki C terhadap assembler yang baik seperti NASM?

Sunting: Hanya untuk menunjukkan. Ketika Anda menulis dalam kumpulan, Anda tidak harus menulis hanya dalam kode instruksi. Anda dapat menggunakan makro dan prosedur dan konvensi Anda sendiri untuk membuat berbagai abstraksi untuk membuat program lebih modular, lebih mudah dikelola dan lebih mudah dibaca. Di sinilah terbiasa dengan cara menulis majelis yang baik masuk

mudge
sumber
71
Menulis ? Bagaimana dengan membaca kode? Anda (dan orang lain) akan membaca kode jauh lebih banyak daripada yang Anda tulis
nos
81
Mengapa saya harus belajar bahasa baru hanya karena program saya akan berjalan pada platform baru? Mengapa saya harus membuat program saya agar sesuai dengan ide CPU tentang berapa banyak register yang ada dan apa yang dapat Anda lakukan dengannya? Saya mencoba memecahkan masalah, tidak melakukan penawaran komputer.
Joachim Sauer
8
Ringkasan dari EDIT: Seseorang dapat menggunakan kompiler C.
Meinersbur
4
@Simon Mungkin tahun saya salah, tetapi saya terkejut bahwa kita memperdebatkan ASM vs "bahasa tingkat tinggi seperti C" pada 2010. Khususnya bagian di mana C adalah contoh bahasa tingkat tinggi
matt b
11
@ changelog: Bukan itu caranya mengeja pemrograman.reddit.com.
BoltClock

Jawaban:

331

ASM memiliki keterbacaan yang buruk dan tidak dapat dipertahankan dibandingkan dengan bahasa tingkat yang lebih tinggi.

Juga, ada lebih sedikit pengembang ASM daripada bahasa lain yang lebih populer, seperti C.

Selain itu, jika Anda menggunakan bahasa tingkat yang lebih tinggi dan instruksi ASM baru tersedia (misalnya SSE), Anda hanya perlu memperbarui kompiler Anda dan kode lama Anda dapat dengan mudah menggunakan instruksi baru.

Bagaimana jika CPU berikutnya memiliki register dua kali lebih banyak?

Kebalikan dari pertanyaan ini adalah: Fungsi apa yang disediakan kompiler?

Saya ragu Anda bisa / ingin / harus mengoptimalkan ASM Anda lebih baik daripada yang gcc -O3bisa.

Benoit
sumber
10
gcc tidak begitu hebat dalam pengoptimalan, jauh lebih baik daripada rata-rata manusia, tetapi ada banyak tempat di mana pengoptimal gagal melakukan pekerjaan dengan baik. Setuju dengan Anda meskipun sebaliknya.
old_timer
4
@dwelch Sangat jarang terjadi bahwa gcc (atau banyak kompiler lain) gagal mengoptimalkan C. yang dikompilasi dengan benar. Namun, dalam kasus-kasus tersebut, Anda selalu dapat menulis sejumlah prosedur dalam ASM dan menautkan hanya metode-metode tersebut pada saat membangun.
cortijon
@ Ben S: Saya awalnya diedit dalam "banyak" daripada "banyak" karena "banyak" digunakan untuk objek tunggal saja. Karena objek "banyak" adalah jamak (pengembang), "banyak" adalah opsi yang benar. Tetapi saya tidak akan mengedit jawaban Anda lagi jika "banyak" adalah yang Anda inginkan.
Billy ONeal
1
Ada banyak kasus di mana kompiler tidak dapat mengoptimalkan dengan baik, tetapi cukup sering pengembang yang menyadari keterbatasan pengoptimal dapat mengoptimalkan kode C-nya tanpa menggunakan perakitan.
Qwertie
1
FWIW dalam pekerjaan saya, saya mengkompilasi produk kami dengan gcc -g -O0, karena dapat melampirkan gdb pada sistem live dan tidak menjadi gila karena variabel dioptimalkan dari keberadaan, bernilai jauh lebih banyak ke perusahaan daripada meninggalkan 4 miliar siklus CPU menganggur setiap hari (dari total 3 triliun). Bilangan bulat crunching tidak sering menjadi hambatan.
Bernd Jendrissek
1930

Hellо, saya seorang kompiler.

Saya baru saja memindai ribuan baris kode saat Anda membaca kalimat ini. Saya melihat-lihat jutaan kemungkinan untuk mengoptimalkan satu baris Anda menggunakan ratusan teknik optimasi berbeda berdasarkan sejumlah besar penelitian akademis yang akan Anda habiskan bertahun-tahun. Saya tidak akan merasa malu, bahkan sedikit ick, ketika saya mengubah loop tiga baris ke ribuan instruksi hanya untuk membuatnya lebih cepat. Saya tidak malu untuk melakukan banyak optimasi atau melakukan trik paling kotor. Dan jika Anda tidak menginginkan saya, mungkin untuk satu atau dua hari, saya akan bersikap dan melakukannya sesuka Anda. Saya dapat mengubah metode yang saya gunakan kapan pun Anda inginkan, bahkan tanpa mengubah satu baris pun kode Anda. Saya bahkan dapat menunjukkan kepada Anda bagaimana kode Anda akan terlihat dalam perakitan, pada arsitektur prosesor yang berbeda dan sistem operasi yang berbeda dan dalam konvensi perakitan yang berbeda jika Anda mau. Ya, semua dalam hitungan detik. Karena, Anda tahu, saya bisa; dan kamu tahu, kamu tidak bisa.

PS Oh, omong-omong Anda tidak menggunakan setengah dari kode yang Anda tulis. Saya membantu Anda dan membuangnya.

ssg
sumber
99

Saya telah menulis shedload assembler untuk chip 6502, Z80, 6809 dan 8086. Saya berhenti melakukannya segera setelah kompiler C tersedia untuk platform yang saya tangani, dan segera menjadi setidaknya 10x lebih produktif. Kebanyakan pemrogram yang baik menggunakan alat yang mereka gunakan untuk alasan rasional.

segera
sumber
72

Saya suka pemrograman dalam bahasa assembly, tetapi dibutuhkan lebih banyak kode untuk melakukan hal yang sama seperti pada bahasa tingkat tinggi, dan ada korelasi langsung antara baris kode dan bug. (Ini dijelaskan beberapa dekade lalu di The Mythical Man-Month .)

Dimungkinkan untuk menganggap C sebagai 'perakitan tingkat tinggi', tetapi dapatkan beberapa langkah di atas itu dan Anda berada di dunia yang berbeda. Dalam C # Anda tidak berpikir dua kali untuk menulis ini:

foreach (string s in listOfStrings) { /* do stuff */ }

Ini akan menjadi lusinan, mungkin ratusan baris kode dalam perakitan, setiap programmer yang menerapkannya akan mengambil pendekatan yang berbeda, dan orang berikutnya yang datang harus mengetahuinya. Jadi, jika Anda percaya (seperti yang dilakukan banyak orang) bahwa program ditulis terutama untuk dibaca orang lain, perakitan kurang dapat dibaca dibandingkan dengan HLL pada umumnya.

Sunting: Saya mengumpulkan perpustakaan pribadi kode yang digunakan untuk tugas-tugas umum, dan makro untuk menerapkan struktur kontrol mirip-C. Tapi saya menabrak dinding di tahun 90-an, ketika GUI menjadi norma. Terlalu banyak waktu dihabiskan untuk hal-hal yang rutin.

Tugas terakhir yang saya miliki di mana ASM sangat penting adalah beberapa tahun yang lalu, menulis kode untuk memerangi malware. Tidak ada antarmuka pengguna, jadi itu semua bagian yang menyenangkan tanpa mengasapi.

egrunin
sumber
Apa kamu yakin akan hal itu? Saya ingat pernah membaca di Kode Lengkap bahwa ini tidak terjadi ...
jcolebrand
1
Saya yakin ada titik di mana keuntungan 'garis lebih sedikit' dikalahkan oleh kerugian 'optimasi prematur'. Tapi saya belum melihat Kode Lengkap di usia ...
egrunin
6
Agak ironis untuk menggunakan "optimasi prematur" sebagai argumen untuk perakitan ... (Saya mungkin salah menafsirkan Anda. Saya masih berpikir itu lucu.)
Bernd Jendrissek
Anda masih dapat memanggil fungsi dalam assembler, jadi saya ragu bahwa foreach-loop membutuhkan puluhan hingga ratusan baris. Atau apa yang saya lewatkan?
Sebastian Mach
@phrnelnel: foreachmelakukan jauh lebih banyak daripada for- itu instantiates dan menggunakan iterator tipe-spesifik.
egrunin
15

Selain jawaban orang lain tentang keterbacaan, pemeliharaan, kode lebih pendek dan karena itu lebih sedikit bug, dan menjadi lebih mudah, saya akan menambahkan alasan tambahan:

kecepatan program.

Ya, dalam perakitan Anda dapat mengatur kode Anda untuk memanfaatkan setiap siklus terakhir dan membuatnya secepat mungkin secara fisik. Namun siapa yang punya waktu? Jika Anda menulis program C yang tidak sepenuhnya bodoh, kompiler akan melakukan pekerjaan yang sangat baik untuk mengoptimalkan untuk Anda. Mungkin membuat setidaknya 95% dari optimasi yang akan Anda lakukan dengan tangan, tanpa Anda harus khawatir tentang melacak semua itu. Jelas ada 90/10 jenis aturan di sini, di mana 5% optimasi terakhir akan menghabiskan 95% waktu Anda. Jadi mengapa repot?

Brian Postow
sumber
4
+1. Menulis kode assembler dan menulis kode assembler cepat adalah dua hal yang berbeda. Jika Anda menggunakan kompiler yang baik, Anda mendapatkan kode assembler cepat secara gratis.
Niki
Anda mendapatkan kode assembler cepat secara gratis hanya jika Anda tahu cara menggunakan kompiler, kebanyakan tidak menggunakan optimisasi, kebanyakan orang mengkompilasi dengan opsi debug dan sebagai hasilnya berakhir dengan assembler lambat yang dilakukan dengan buruk. ya lebih dari 99% dari waktu Anda tidak boleh menyentuhnya, hanya menyentuh tombol-tombol kompiler dan tidak men-tweak output secara langsung.
old_timer
jika Anda peduli dengan optimasi, maka Anda harus melakukan itu dari kompiler ... JIKA Anda tidak peduli tentang optimasi, tetapi Anda masih menggunakan perakitan, maka Anda hanya bersikap konyol.
Brian Postow
@wwch: Saya kira mungkin ada beberapa skrip-kiddies yang tidak repot-repot mencari tahu bagaimana mereka digunakan. Tapi saya ragu orang seperti mereka akan pernah bisa menulis kode assembler cepat.
Niki
13

Jika sebuah program produksi rata-rata mengatakan 100 ribu baris kode, dan setiap baris sekitar 8-12 instruksi assembler, itu akan menjadi 1 juta instruksi assembler.

Bahkan jika Anda dapat menulis semua ini dengan tangan pada kecepatan yang layak (ingat, 8 kali lebih banyak kode yang harus Anda tulis), apa yang terjadi jika Anda ingin mengubah beberapa fungsi? Memahami sesuatu yang Anda tulis beberapa minggu lalu dari 1 juta instruksi itu adalah mimpi buruk! Tidak ada modul, tidak ada kelas, tidak ada desain berorientasi objek, tidak ada kerangka kerja, tidak ada apa-apa. Dan jumlah kode yang mirip dengan yang Anda harus tulis untuk hal-hal yang paling sederhana adalah yang paling menakutkan.

Selain itu, Anda tidak dapat mengoptimalkan kode Anda sebaik bahasa tingkat tinggi. Di mana C misalnya melakukan sejumlah optimasi gila karena Anda menggambarkan maksud Anda, bukan hanya kode Anda, di assembler Anda hanya menulis kode, assembler tidak dapat benar-benar melakukan optimasi catatan-layak pada kode Anda. Apa yang Anda tulis adalah apa yang Anda dapatkan, dan percayalah, Anda tidak dapat secara optimal mengoptimalkan 1 juta instruksi yang Anda tempel dan tempel saat Anda menulisnya.

Buta
sumber
8

Yah saya telah menulis banyak pertemuan "di masa lalu", dan saya dapat meyakinkan Anda bahwa saya jauh lebih produktif ketika saya menulis program dalam bahasa tingkat tinggi.

Maurice Perry
sumber
8
"Majelis adalah bahasa Latin".
Adriano Varoli Piazza
4
@ Adriano: kecuali ada banyak, banyak dialek yang berbeda dan tidak ada dua yang mirip.
Joachim Sauer
1
Tentu, tetapi saya maksudkan bahwa belajar memprogram di antara mereka memberi Anda wawasan tentang arsitektur mesin yang membantu Anda di level yang lebih tinggi. Kecuali jika Anda berurusan dengan memori halaman, dalam kasus itu Anda akhirnya terluka. Seperti membaca Carmen 16 dari Catullus.
Adriano Varoli Piazza
5
@Adriano "Assembly is Latin", Tidak ada asm yang menggerutu manusia gua. Satu mendengus untuk batu 2 mendengus untuk rusa, 3 mendengus untuk api - bagus untuk hal-hal sederhana tetapi sulit untuk menjalankan kerajaan.
Martin Beckett
1
@ Martin: Pernahkah Anda mencoba melakukan aritmatika kompleks dengan angka Romawi?
Adriano Varoli Piazza
6

Tingkat kompetensi assembler yang wajar adalah keterampilan yang berguna, terutama jika Anda bekerja di semua level sistem atau pemrograman yang disematkan, bukan karena Anda harus menulis assembler sebanyak itu, tetapi karena kadang-kadang penting untuk memahami apa yang sebenarnya dilakukan oleh kotak. . Jika Anda tidak memiliki pemahaman tingkat rendah tentang konsep dan masalah assembler, ini bisa sangat sulit.

Namun, untuk benar-benar menulis banyak kode di assembler, ada beberapa alasan mengapa hal itu tidak banyak dilakukan.

  • Tidak ada kebutuhan (hampir). Kecuali untuk sesuatu seperti inisialisasi sistem yang sangat awal dan mungkin beberapa fragmen assembler yang tersembunyi dalam fungsi C atau makro, semua kode tingkat sangat rendah yang mungkin pernah ditulis dalam assembler dapat ditulis dalam C atau C ++ tanpa kesulitan.

  • Kode dalam bahasa tingkat yang lebih tinggi (bahkan C dan C ++) mengembun fungsi menjadi baris yang jauh lebih sedikit, dan ada penelitian yang menunjukkan bahwa jumlah bug berkorelasi dengan jumlah baris kode sumber. Yaitu, masalah yang sama, diselesaikan di assembler dan C, akan memiliki lebih banyak bug di assembler hanya karena lebih lama. Argumen yang sama memotivasi perpindahan ke bahasa tingkat yang lebih tinggi seperti Perl, Python, dll.

  • Menulis dalam assembler, Anda harus berurusan dengan setiap aspek masalah, dari tata letak memori terperinci, pemilihan instruksi, pilihan algoritma, manajemen tumpukan, dll. Bahasa tingkat yang lebih tinggi mengambil semua ini dari Anda, yang mengapa begitu jauh lebih padat dalam ketentuan LOC.

Pada dasarnya, semua hal di atas terkait dengan tingkat abstraksi yang tersedia untuk Anda dalam assembler versus C atau bahasa lain. Assembler memaksa Anda untuk membuat semua abstraksi Anda sendiri, dan memeliharanya melalui disiplin diri Anda sendiri, di mana bahasa tingkat menengah seperti C, dan terutama bahasa tingkat yang lebih tinggi, memberi Anda abstraksi di luar kotak, serta kemampuan membuat yang baru dengan relatif mudah.

Dale Hagglund
sumber
6

Sebagai pengembang yang menghabiskan sebagian besar waktunya di dunia pemrograman tertanam, saya berpendapat bahwa perakitan jauh dari bahasa mati / usang. Ada tingkat pengkodean dekat-ke-logam tertentu (misalnya, dalam driver) yang terkadang tidak dapat dinyatakan secara akurat atau efisien dalam bahasa tingkat yang lebih tinggi. Kami menulis hampir semua rutinitas antarmuka perangkat keras kami di assembler.

Yang sedang berkata, kode perakitan ini dibungkus sedemikian rupa sehingga dapat dipanggil dari kode C dan diperlakukan seperti perpustakaan. Kami tidak menulis seluruh program dalam pertemuan karena berbagai alasan. Pertama dan terpenting adalah portabilitas; basis kode kami digunakan pada beberapa produk yang menggunakan arsitektur berbeda dan kami ingin memaksimalkan jumlah kode yang dapat dibagi di antara mereka. Kedua adalah keakraban pengembang. Sederhananya, sekolah tidak mengajarkan perakitan seperti dulu, dan pengembang kami jauh lebih produktif di C daripada di perakitan. Selain itu, kami memiliki berbagai macam "ekstra" (hal-hal seperti perpustakaan, debugger, alat analisis statis, dll) yang tersedia untuk kode C kami yang tidak tersedia untuk kode bahasa assembly. Bahkan jika kita ingin menulis program perakitan murni, kita tidak akan bisa karena beberapa pustaka perangkat keras yang kritis hanya tersedia sebagai C libs. Di satu sisi, ini masalah ayam / telur. Orang-orang diusir dari perakitan karena tidak ada banyak perpustakaan dan alat pengembangan / debug yang tersedia untuk itu, tetapi lib / alat tidak ada karena tidak cukup banyak orang menggunakan perakitan untuk menjamin upaya pembuatannya.

Pada akhirnya, ada waktu dan tempat untuk hampir semua bahasa. Orang-orang menggunakan apa yang paling mereka kenal dan produktif. Mungkin akan selalu ada tempat dalam repertoar programmer untuk berkumpul, tetapi kebanyakan programmer akan menemukan bahwa mereka dapat menulis kode dalam bahasa tingkat yang lebih tinggi yang hampir sama efisiennya dalam waktu yang jauh lebih sedikit.

bta
sumber
6

Ketika Anda menulis dalam kumpulan, Anda tidak harus menulis hanya dalam kode instruksi. Anda dapat menggunakan makro dan prosedur dan konvensi Anda sendiri untuk membuat berbagai abstraksi untuk membuat program lebih modular, lebih mudah dikelola dan lebih mudah dibaca.

Jadi apa yang Anda katakan pada dasarnya adalah, bahwa dengan penggunaan assembler canggih yang terampil, Anda dapat membuat kode ASM Anda lebih dekat dan lebih dekat ke C (atau lagi pula bahasa tingkat rendah penemuan Anda sendiri), sampai akhirnya Anda hanya seproduktif seorang programmer C.

Apakah itu menjawab pertanyaan Anda? ;-)

Saya tidak mengatakan ini dengan santai: Saya telah memprogram menggunakan assembler dan sistem yang persis seperti itu. Bahkan lebih baik, assembler dapat menargetkan prosesor virtual, dan penerjemah terpisah menyusun output assembler untuk platform target. Banyak yang terjadi dengan IF LLVM, tetapi dalam bentuk awalnya pra-kencan sekitar 10 tahun. Jadi ada portabilitas, ditambah kemampuan untuk menulis rutin untuk target asssembler tertentu di mana diperlukan untuk efisiensi.

Menulis menggunakan assembler itu hampir sama produktifnya dengan C, dan dengan perbandingan dengan GCC-3 (yang sekitar saat saya terlibat) assembler / penerjemah menghasilkan kode yang kira-kira sama cepat dan biasanya lebih kecil. Ukuran sangat penting, dan perusahaan memiliki sedikit programmer dan bersedia untuk mengajar karyawan baru bahasa baru sebelum mereka dapat melakukan sesuatu yang bermanfaat. Dan kami memiliki cadangan yang orang-orang yang tidak tahu assembler (misalnya pelanggan) dapat menulis C dan mengompilasinya untuk prosesor virtual yang sama, menggunakan konvensi pemanggilan yang sama dan seterusnya, sehingga interfacing rapi. Jadi rasanya seperti kemenangan kecil.

Itu dengan beberapa tahun kerja di tas mengembangkan teknologi assembler, perpustakaan, dan sebagainya. Diakui banyak yang membuatnya menjadi portabel, jika itu hanya menargetkan satu arsitektur maka assembler semua-menari semua-bernyanyi akan jauh lebih mudah.

Singkatnya: Anda mungkin tidak menyukai C, tetapi itu tidak berarti bahwa upaya menggunakan C lebih besar daripada upaya untuk menghasilkan sesuatu yang lebih baik.

Steve Jessop
sumber
5

Perakitan tidak portabel antara mikroprosesor yang berbeda.

semaj
sumber
Itu tidak sepenuhnya benar dengan prosesor modern dan program assembler, Anda dapat menargetkan prosesor yang berbeda seperti yang Anda bisa dalam C. Tentu Anda tidak akan dapat menggunakan set lengkap instruksi dalam kasus ini, tetapi Anda juga tidak akan melakukannya jika Anda menulisnya dalam C. Portabilitas bukan perhatian utama.
Blindy
6
Mungkin maksud Anda arsitektur .
Ben S
2
@ Blindy - Anda dapat menargetkan prosesor yang berbeda dalam keluarga x86 tetapi jelas tidak ada kesamaan dalam instruksi perakitan antara varian x86 dan prosesor ARM atau Z80 atau 8051.
semaj
Benar, tetapi kemudian Anda tidak dapat memprogram z80 dalam c. Saya pikir kita semua berbicara tentang prosesor x86 / x64 normal di sini.
Blindy
1
Seluruh dunia bukan x86. Tidak ada tentang "mikroprosesor yang berbeda" menunjukkan bahwa mereka semua menjalankan set instruksi yang sama.
Bernd Jendrissek
5

Alasan yang sama kita tidak pergi ke kamar mandi di luar lagi, atau mengapa kita tidak berbicara bahasa Latin atau Aram.

Teknologi hadir dan membuat segalanya lebih mudah dan lebih mudah diakses.

EDIT - untuk berhenti menyinggung orang, saya telah menghapus kata-kata tertentu.

Jack Marchetti
sumber
4
Anda masih menyinggung orang Luddite dengan kataTechnology
SeanJA
1
"Kami" tidak berbicara bahasa Latin?
dank
Baik bahasa Latin maupun bahasa Aram tidak menghilang karena digantikan oleh teknologi yang lebih baik (yaitu bahasa yang lebih mudah dipelajari / dipelajari). Faktanya, bahasa Latin masih ada bersama kita di mana-mana di Eropa. Semua bahasa Romawi didasarkan pada bahasa Latin. Bahasa Aram modern (neo) dituturkan oleh hampir setengah juta orang saat ini. Alasan mengapa bahasa-bahasa ini tidak lazim lagi adalah historis (geopolitik, lebih tepatnya), bukan teknologi. Alasan yang sama bahasa Inggris adalah lingua franca dari kelas sains dan penguasa zaman kita - orang-orang dari kekaisaran terakhir, Inggris (dan sekarang Amerika AS) berbicara itu.
Ritz
4

Mengapa? Sederhana.

Bandingkan ini:

        for (var i = 1; i <= 100; i++)
        {
            if (i % 3 == 0)
                Console.Write("Fizz");
            if (i % 5 == 0)
                Console.Write("Buzz");
            if (i % 3 != 0 && i % 5 != 0)
                Console.Write(i);
            Console.WriteLine();
        }

dengan

.locals init (
    [0] int32 i)
L_0000: ldc.i4.1 
L_0001: stloc.0 
L_0002: br.s L_003b
L_0004: ldloc.0 
L_0005: ldc.i4.3 
L_0006: rem 
L_0007: brtrue.s L_0013
L_0009: ldstr "Fizz"
L_000e: call void [mscorlib]System.Console::Write(string)
L_0013: ldloc.0 
L_0014: ldc.i4.5 
L_0015: rem 
L_0016: brtrue.s L_0022
L_0018: ldstr "Buzz"
L_001d: call void [mscorlib]System.Console::Write(string)
L_0022: ldloc.0 
L_0023: ldc.i4.3 
L_0024: rem 
L_0025: brfalse.s L_0032
L_0027: ldloc.0 
L_0028: ldc.i4.5 
L_0029: rem 
L_002a: brfalse.s L_0032
L_002c: ldloc.0 
L_002d: call void [mscorlib]System.Console::Write(int32)
L_0032: call void [mscorlib]System.Console::WriteLine()
L_0037: ldloc.0 
L_0038: ldc.i4.1 
L_0039: add 
L_003a: stloc.0 
L_003b: ldloc.0 
L_003c: ldc.i4.s 100
L_003e: ble.s L_0004
L_0040: ret 

Mereka identik fitur-bijaksana. Yang kedua bahkan bukan assembler tetapi .NET IL (Bahasa Perantara, mirip dengan bytecode Java). Kompilasi kedua mengubah IL menjadi kode asli (yaitu hampir assembler), menjadikannya lebih samar.

Andrei Rînea
sumber
3

Saya kira ASM bahkan pada x86 (_64) masuk akal dalam kasus di mana Anda mendapatkan banyak dengan menggunakan instruksi yang sulit untuk dioptimalkan oleh kompiler. x264 misalnya menggunakan banyak asm untuk penyandiannya, dan peningkatan kecepatan sangat besar.

Tuan
sumber
2

Saya yakin ada banyak alasan, tetapi dua alasan cepat yang dapat saya pikirkan adalah

  1. Kode assembly jelas lebih sulit untuk dibaca (saya yakin lebih memakan waktu untuk menulis juga)
  2. Ketika Anda memiliki tim pengembang besar yang mengerjakan suatu produk, akan sangat membantu jika kode Anda dibagi menjadi blok-blok logis dan dilindungi oleh antarmuka.
Martin Konecny
sumber
1
Perhatikan bahwa Anda dapat memisahkan rakitan menjadi blok logis juga.
Paul Williams
2

Salah satu penemuan awal (Anda akan menemukannya di Brooks ' Mythical Man-Month , yang berasal dari pengalaman di tahun 1960-an) adalah bahwa orang-orang kurang lebih sama produktifnya dalam satu bahasa dengan yang lain, dalam baris kode yang di-debug setiap hari. Ini jelas tidak secara universal benar, dan dapat pecah ketika didorong terlalu jauh, tetapi umumnya berlaku untuk bahasa tingkat tinggi pada masa Brooks.

Oleh karena itu, cara tercepat untuk mendapatkan produktivitas adalah dengan menggunakan bahasa di mana satu baris kode individu melakukan lebih banyak, dan memang ini berfungsi, setidaknya untuk bahasa kompleksitas seperti FORTRAN dan COBOL, atau untuk memberikan contoh yang lebih modern C.

David Thornley
sumber
2

Portabilitas selalu menjadi masalah - jika tidak sekarang, setidaknya pada akhirnya. Industri pemrograman menghabiskan miliaran setiap tahun untuk port software lama yang, pada saat itu ditulis, "jelas" tidak ada masalah portabilitas sama sekali.

Thomas Pornin
sumber
2
"Itu tidak harus port ke arsitektur lain" terdengar jauh ke telinga saya seperti "Itu tidak akan membutuhkan lebih dari dua digit untuk tahun ini."
David Thornley
Atau kita tidak bisa menggunakan C # karena Windows mungkin tidak ada tahun depan?
Martin Beckett
Misalnya komputer Apple MacIntosh yang didasarkan pada prosesor seri Motorola MC68000, PowerPC (IBM et all), dan sekarang prosesor Intel x86 (IA-32 (e)). Jadi ya, portabilitas adalah masalah untuk sistem yang digunakan cukup lama, dan setiap programmer yang belum digigit oleh kode mereka bertahan lebih lama dari yang diharapkan belum berpengalaman.
mctylr
@ Martin: Dua puluh tahun dari sekarang, akan ada banyak program C # yang ingin dijalankan orang, jadi ada cara untuk mengkompilasi dan menjalankan program C #. Tidak ada yang secara inheren diperbaiki tentang C #, meskipun dalam dua puluh tahun saya akan terkejut jika itu masih sepopuler sekarang. Namun, dalam dua puluh tahun CPU kami akan sangat berbeda. Sebuah program assembler yang ditulis pada tahun 1990 mungkin berjalan saat ini, tetapi itu pasti tidak akan optimal, dan akan berjalan lebih lambat dari yang dikompilasi C.
David Thornley
Itulah yang saya maksud - Saya memiliki lebih banyak masalah porting karena kerangka kerja tingkat tinggi berubah dari 6 bulan yang lalu daripada yang saya lakukan karena instruksi dalam x86 berubah - terutama karena asm kode tangan cenderung untuk tetap menggunakan metode yang paling sederhana.
Martin Beckett
2

Ada lingkaran setan ketika perakitan menjadi kurang umum: ketika bahasa tingkat yang lebih tinggi matang, set instruksi bahasa perakitan dibangun lebih sedikit untuk kenyamanan programmer dan lebih untuk kenyamanan kompiler.

Jadi sekarang, secara realistis, mungkin sangat sulit untuk membuat keputusan yang tepat, misalnya, register mana yang harus Anda gunakan atau instruksi mana yang sedikit lebih efisien. Compiler dapat menggunakan heuristik untuk mencari tahu tradeoffs mana yang memiliki hasil terbaik. Kita mungkin dapat memikirkan masalah yang lebih kecil dan menemukan optimisasi lokal yang mungkin mengalahkan kompiler kami yang cukup canggih, tetapi kemungkinannya adalah bahwa dalam kasus rata-rata, kompiler yang baik akan melakukan pekerjaan yang lebih baik pada percobaan pertama daripada yang mungkin dilakukan oleh programmer yang baik. Akhirnya, seperti John Henry, kita mungkin mengalahkan mesin itu, tetapi kita mungkin benar-benar membakar diri untuk sampai ke sana.

Masalah kita sekarang juga sangat berbeda. Pada tahun 1986 saya mencoba mencari cara untuk mendapatkan sedikit lebih cepat dari program kecil yang melibatkan meletakkan beberapa ratus piksel di layar; Saya ingin animasi menjadi kurang tersentak-sentak. Kasus yang wajar untuk bahasa majelis. Sekarang saya mencoba mencari cara untuk mewakili abstraksi di sekitar bahasa kontrak dan kebijakan penyedia layanan untuk hipotek, dan saya lebih suka membaca sesuatu yang mirip dengan bahasa yang digunakan para pelaku bisnis. Tidak seperti makro LISP, makro Majelis tidak menegakkan banyak di jalan aturan, jadi meskipun Anda mungkin bisa mendapatkan sesuatu yang cukup dekat dengan DSL di assembler yang baik, itu akan rentan terhadap segala macam kebiasaan yang menang ' t menyebabkan masalah bagi saya jika saya menulis kode yang sama di Ruby, Boo, Lisp, C # atau bahkan F #.

Namun, jika masalah Anda mudah diekspresikan dalam bahasa assembly yang efisien, lebih banyak kekuatan untuk Anda.

JasonTrue
sumber
2

Begitu juga sebagian besar dari apa yang dikatakan orang lain.

Di masa lalu yang indah sebelum C ditemukan, ketika satu-satunya bahasa tingkat tinggi adalah hal-hal seperti COBOL dan FORTRAN, ada banyak hal yang tidak mungkin dilakukan tanpa menggunakan assembler. Itu adalah satu-satunya cara untuk mendapatkan keluasan penuh fleksibilitas, untuk dapat mengakses semua perangkat, dll. Tapi kemudian C ditemukan, dan hampir semua hal yang mungkin dalam perakitan dimungkinkan dalam C. Saya telah menulis sangat sedikit perakitan sejak kemudian.

Yang mengatakan, saya pikir ini adalah latihan yang sangat berguna bagi programmer baru untuk belajar menulis di assembler. Bukan karena mereka benar-benar akan menggunakannya, tetapi karena Anda mengerti apa yang sebenarnya terjadi di dalam komputer. Saya telah melihat banyak kesalahan pemrograman dan kode tidak efisien dari programmer yang jelas tidak tahu apa yang sebenarnya terjadi dengan bit dan byte dan register.

Jay
sumber
Ya, tepat. Fortran Disk dan Tape I / O pada mainframe IBM bertahun-tahun lalu hampir tidak berguna, jadi kami menulis rutin I / O kami sendiri di 370 / Assembler dan memanggil mereka dari kode Fortan IV. Dan menulis kode perakitan membuat saya sangat memahami arsitektur yang mendasarinya. Saya belum menulis kode perakitan apa pun sekarang selama beberapa tahun dan semua orang muda yang bekerja dengan saya tidak pernah menulis apa pun - tetapi saya berharap mereka melakukannya, itu sangat mendidik.
Simon Knights
2

Saya sudah pemrograman dalam perakitan sekarang selama sekitar satu bulan. Saya sering menulis sepotong kode dalam C dan kemudian mengkompilasinya ke perakitan untuk membantu saya. Mungkin saya tidak menggunakan kekuatan optimisasi penuh dari kompiler C tetapi tampaknya sumber asm C saya termasuk operasi yang tidak perlu. Jadi saya mulai melihat bahwa pembicaraan tentang compiler C yang baik mengungguli assembly coder yang baik tidak selalu benar.

Bagaimanapun, program perakitan saya sangat cepat. Dan semakin banyak saya menggunakan perakitan semakin sedikit waktu yang dibutuhkan untuk menulis kode saya karena itu benar-benar tidak sulit. Juga komentar tentang majelis yang memiliki keterbacaan yang buruk tidak benar. Jika Anda memberi label pada program Anda dengan benar dan memberikan komentar ketika ada elaborasi tambahan yang diperlukan, Anda harus siap. Sebenarnya cara perakitan lebih jelas bagi programmer karena mereka melihat apa yang terjadi di tingkat prosesor. Saya tidak tahu tentang programmer lain tetapi bagi saya saya suka mengetahui apa yang terjadi, daripada hal-hal yang berada di semacam kotak hitam.

Dengan mengatakan bahwa keuntungan sebenarnya dari kompiler adalah bahwa kompiler dapat memahami pola dan hubungan dan kemudian secara otomatis kode mereka di lokasi yang sesuai di sumber. Salah satu contoh populer adalah fungsi virtual di C ++ yang mengharuskan kompiler untuk memetakan pointer fungsi secara optimal. Namun kompiler terbatas untuk melakukan apa yang pembuat kompiler memungkinkan kompiler lakukan. Hal ini menyebabkan programmer kadang-kadang terpaksa melakukan hal-hal aneh dengan kode mereka, menambah waktu pengkodean, ketika mereka bisa dilakukan sepele dengan perakitan.

Secara pribadi saya pikir pasar sangat mendukung bahasa tingkat tinggi. Jika bahasa assembly adalah satu-satunya bahasa yang ada saat ini maka mereka akan sekitar 70% lebih sedikit orang pemrograman dan siapa yang tahu di mana dunia kita akan berada, mungkin kembali di tahun 90-an. Bahasa tingkat yang lebih tinggi menarik bagi orang yang lebih luas. Ini memungkinkan pasokan programmer yang lebih tinggi untuk membangun infrastruktur yang dibutuhkan dunia kita. Negara-negara berkembang seperti Cina dan India mendapat banyak manfaat dari bahasa seperti Jawa. Negara-negara ini akan cepat mengembangkan infrastruktur TI mereka dan orang-orang akan menjadi lebih saling terhubung. Jadi poin saya adalah bahwa bahasa tingkat tinggi populer bukan karena mereka menghasilkan kode unggul tetapi karena mereka membantu memenuhi permintaan di pasar dunia.

pengguna922475
sumber
+1 untuk kotak hitam. Yap, kami menggunakan kotak hitam, dan tidak ada cara untuk mengintip ke dalamnya (terlalu mudah). Bagaimana cara kerja C # foreach ? Siapa tahu. Microsoft berkata, ini sempurna. Maka harus begitu.
ern0
Juga, jangan lupa bahwa dengan 'bahasa tingkat tinggi' datang banyak hal lain yang penting di dunia nyata. C datang dengan perpustakaan standar (matematika, pemrosesan string, I / O dll), dan kemudian beban berat seperti Java datang dengan banyak paket dan perpustakaan lainnya untuk konektivitas, pemrosesan gambar, pemrosesan data, web dev dll. Ini pertanyaan menggunakan waktu Anda untuk fokus pada mendapatkan 1 tugas terperinci yang sangat berkinerja tinggi pada satu platform (dengan demikian menggunakan perakitan) dibandingkan menghabiskan waktu yang sama untuk mendapatkan tugas yang jauh lebih besar berjalan di berbagai platform dengan bug minimal.
jbx
1

Saya sedang belajar assembly di comp org sekarang, dan meskipun menarik, juga sangat tidak efisien untuk menulis. Anda harus menyimpan banyak detail di kepala Anda untuk membuat semuanya berfungsi, dan lebih lambat untuk menulis hal yang sama . Misalnya, 6 baris sederhana untuk loop di C ++ dapat sama dengan 18 baris atau lebih dari rakitan.

Secara pribadi, banyak kesenangan belajar bagaimana hal-hal bekerja pada level perangkat keras, dan itu memberi saya apresiasi yang lebih besar untuk bagaimana komputasi bekerja.

Jason
sumber
1

Apa yang dimiliki C dari assembler makro yang baik adalah bahasa C. Pengecekan tipe. Konstruksi lingkaran. Manajemen tumpukan otomatis. (Hampir) manajemen variabel otomatis. Teknik memori dinamis dalam assembler adalah rasa sakit yang hebat di pantat. Melakukan daftar yang ditautkan dengan benar benar menakutkan dibandingkan dengan C atau lebih baik lagi daftar foo.insert (). Dan debugging - yah, tidak ada kontes tentang apa yang lebih mudah untuk di-debug. HLL menang telak di sana.

Saya telah mengkodekan hampir setengah karir saya di assembler yang membuatnya sangat mudah bagi saya untuk berpikir di assmebler. ini membantu saya untuk melihat apa yang dilakukan oleh kompiler C yang lagi membantu saya menulis kode yang dapat ditangani oleh kompiler C secara efisien. Rutin yang dipikirkan dengan matang ditulis dalam C dapat ditulis untuk menghasilkan apa yang Anda inginkan dalam assembler dengan sedikit kerja - dan ini portabel! Saya sudah harus menulis ulang beberapa rutinitas asm yang lebih lama kembali ke C untuk alasan lintas platform dan itu tidak menyenangkan.

Tidak, saya akan tetap menggunakan C dan menangani sedikit penurunan kinerja sesekali terhadap waktu produktivitas yang saya dapatkan dengan HLL.

Michael Dorgan
sumber
1

Saya hanya bisa menjawab mengapa saya secara pribadi tidak menulis program dalam pertemuan lebih sering, dan alasan utamanya adalah lebih membosankan untuk dilakukan. Juga, saya pikir lebih mudah untuk membuat kesalahan secara halus tanpa menyadarinya. Misalnya, Anda mungkin mengubah cara Anda menggunakan register dalam satu rutin tetapi lupa untuk mengubahnya di satu tempat. Ini akan berkumpul dengan baik dan Anda mungkin tidak melihat sampai nanti.

Yang mengatakan, saya pikir masih ada kegunaan yang valid untuk perakitan. Sebagai contoh, saya memiliki sejumlah rutin perakitan yang cukup optimal untuk memproses data dalam jumlah besar, menggunakan SIMD dan mengikuti pendekatan paranoid "setiap bit adalah sakral" [kutipan V.Stob]. (Tetapi perhatikan bahwa implementasi perakitan naif sering jauh lebih buruk daripada apa yang dihasilkan kompiler untuk Anda.)

Phi
sumber
1

C adalah assembler makro! Dan itu yang terbaik!

Itu dapat melakukan hampir semua perakitan dapat, itu bisa portabel dan dalam sebagian besar kasus langka di mana ia tidak dapat melakukan sesuatu Anda masih dapat menggunakan kode perakitan tertanam. Ini hanya menyisakan sebagian kecil dari program yang Anda benar-benar perlu tulis dalam perakitan dan tidak lain dari perakitan.

Dan abstraksi tingkat yang lebih tinggi dan portabilitas membuatnya lebih bermanfaat bagi kebanyakan orang untuk menulis perangkat lunak sistem dalam C. Dan meskipun Anda mungkin tidak memerlukan portabilitas sekarang jika Anda menginvestasikan banyak waktu dan uang dalam menulis beberapa program, Anda mungkin tidak ingin membatasi diri dalam apa Anda akan dapat menggunakannya untuk di masa depan.

ahe
sumber
1

Orang sepertinya lupa bahwa ada juga arah yang lain.

Mengapa Anda menulis di Assembler di tempat pertama? Mengapa tidak menulis program dalam bahasa tingkat rendah?

Dari pada

mov eax, 0x123
add eax, 0x456
push eax
call printInt

Anda bisa menulis

B823010000
0556040000
50 
FF15.....

Itu memiliki banyak keuntungan, Anda tahu ukuran persis program Anda, Anda dapat menggunakan kembali nilai instruksi sebagai input untuk instruksi lain dan Anda bahkan tidak memerlukan assembler untuk menulisnya, Anda dapat menggunakan editor teks ...

Dan alasan Anda masih lebih suka Assembler tentang ini, adalah alasan orang lain lebih suka ...

BeniBela
sumber
0

Karena selalu seperti itu: waktu berlalu dan hal-hal baik berlalu juga :(

Tetapi ketika Anda menulis kode asm, rasanya benar-benar berbeda dari ketika Anda membuat kode tingkat tinggi, meskipun Anda tahu itu jauh lebih tidak produktif. Ini seperti Anda seorang pelukis: Anda bebas menggambar apa pun yang Anda suka sesuka Anda tanpa batasan (yah, hanya dengan fitur-fitur CPU) ... Itulah sebabnya saya menyukainya. Sayang sekali bahasa ini hilang. Tetapi sementara seseorang masih mengingatnya dan mengkodekannya, itu tidak akan pernah mati!

edk
sumber
Benar. Di sisi lain, ada penghinaan yang Anda alami ketika kasir dan supermarket menolak untuk mencairkan cek Anda, dengan jijik mengatakan, "Oh, Anda memprogram dalam bahasa LOW-LEVEL."
Jay
0

$$$

Perusahaan menyewa pengembang untuk membantu mengubah kode menjadi $$$. Semakin cepat kode berguna dapat diproduksi, semakin cepat perusahaan dapat mengubah kode tersebut menjadi $$$.

Bahasa tingkat yang lebih tinggi umumnya lebih baik dalam menghasilkan volume kode bermanfaat yang lebih besar. Ini bukan untuk mengatakan bahwa majelis tidak memiliki tempatnya, karena ada waktu dan tempat di mana tidak ada lagi yang akan dilakukan.

Sparky
sumber
0

Keuntungan dari HLL bahkan lebih besar ketika Anda membandingkan rakitan dengan bahasa tingkat yang lebih tinggi dari C, misalnya Java atau Python atau Ruby. Misalnya, bahasa-bahasa ini memiliki pengumpulan sampah: tidak perlu khawatir kapan harus membebaskan sepotong memori, dan tidak ada kebocoran memori atau bug karena membebaskan terlalu dini.

pengguna4660402
sumber
0

Seperti yang disebutkan sebelumnya, alasan keberadaan alat adalah seberapa efisiennya alat itu bekerja. Karena HLL dapat menyelesaikan pekerjaan yang sama dengan banyak baris kode asm, saya rasa wajar jika perakitan digantikan oleh bahasa lain. Dan untuk mengutak-atik perangkat keras - ada perakitan inline dalam C dan varian lainnya sesuai bahasa. Paul Carter dalam mengatakan dalam Bahasa Majelis PC

"... pemahaman yang lebih baik tentang bagaimana komputer benar-benar bekerja pada tingkat yang lebih rendah daripada dalam bahasa pemrograman seperti Pascal. Dengan mendapatkan pemahaman yang lebih dalam tentang bagaimana komputer bekerja, pembaca sering kali bisa jauh lebih produktif mengembangkan perangkat lunak dalam bahasa tingkat yang lebih tinggi seperti C dan C ++. Belajar memprogram dalam bahasa assembly adalah cara terbaik untuk mencapai tujuan ini. "

Kami punya perkenalan tentang perakitan di kursus kuliah saya. Ini akan membantu membersihkan konsep. Namun saya ragu salah satu dari kita akan menulis 90% dari kode di assembly Seberapa relevan pengetahuan majelis mendalam saat ini?

AruniRC
sumber
-2

Membalik-balik jawaban ini, saya yakin 9/10 dari responden tidak pernah bekerja dengan perakitan.

Ini adalah pertanyaan lama yang sering muncul dan Anda mendapatkan jawaban yang sama, kebanyakan salah informasi. Jika bukan karena portabilitas, saya masih akan melakukan semuanya sendiri. Meski begitu, saya kode dalam C hampir seperti yang saya lakukan di perakitan.

rampok
sumber
1
+1 menyebutkan orang tanpa pengalaman asm, dan +1 lainnya harus untuk "pengkodean dalam C seperti asm". Ketika saya menulis aplikasi C ++ (ya, CPP, bukan C) untuk disematkan, saya mengkode seperti asm, misalnya tidak menggunakan baru / malloc () sama sekali.
ern0
Jadi Anda menggunakan banyak hal seperti char buf [MAX_PATH] yang kemudian jatuh ketika seseorang memiliki data ukuran MAX_PATH + n? ;)
paulm
1
@ paulm - Maksud Anda seperti C?
Rob
1
Saya yakin penulis assembler tidak menghindari penggunaan malloc (). Ya, pada embedded Anda dibatasi oleh memori. Tetapi lakukan itu di Unix atau desktop lain (atau bahkan sebagian besar OS seluler) dan Anda hanya perlu membatasi diri dan pengguna Anda. Juga: Semakin sedikit LOC yang Anda tulis, semakin sedikit kemungkinan kesalahan, yang berarti kode tingkat yang lebih tinggi cenderung memiliki lebih sedikit kesalahan daripada lebih rendah.
uliwitness
1
Hanya tampak karena aku curiga dan, ya, aku yakin bisa memberi tahu redditor dan HNers ada di sini.
Rob