Mengenal dan memakai instruksi SIMD

Instruksi SIMD (Single Instruction Multiple Data) adalah jenis instruksi pada prosesor modern yang bisa melakukan operasi terhadap banyak data sekaligus (biasanya bentuknya adalah array/vector). Instruksi assembly dalam sebuah ISA biasanya hanya melakukan hal dasar berikut:

  • Menyalin data dari memori/register ke memori/register
  • Melakukan operasi terhadap satu atau lebih register dan menyimpan hasilnya di memori atau register (contoh: penjumlahan, perkalian, operasi bit, dsb). Beberapa operasi akan mempengaruhi flag pada CPU.
  • Memindahkan alur eksekusi ke alamat tertentu dalam kondisi tertentu (biasanya berdasarkan flag)
  • Melakukan manipulasi hardware spesifik (misalnya mengakses I/O, enable interrupt, enable paging, dsb)

Instruksi SIMD bisa melakukan load/save register dari/ke memori, melakukan manipulasi pada register, tapi satu instruksi bisa memproses banyak data sekaligus. Jika dilakukan dengan benar, ini bisa mempercepat program cukup signifikan. Instruksi SIMD tidak bisa melakukan branching ke banyak alamat sekaligus.

Sejarah SIMD ini cukup panjang: singkatnya tahun 1970an sudah dipikirkan ide ini dan sudah diimplementasikan di berbagai komputer besar, tapi baru masuk ke CPU untuk consumer di akhir abad lalu. Data yang diproses semuanya perlu berurutan (seperti array) dan biasanya disebut sebagai vector (tidak berhubungan dengan istilah vektor di matematika).

Lanjutkan membaca Mengenal dan memakai instruksi SIMD

Calling convention pada AMD64, ARM64, dan RISCV64

Artikel ini merupakan lanjutan dari artikel Hello, World! sebelumnya yang akan memperkenalkan calling convention pada arsitektur AMD64, ARM64 dan RISCV64. Program assembly pada artikel sebelumnya sangat sederhana: tidak ada percabangan, tidak ada pemanggilan fungsi, hanya memakai syscall. Kali ini saya ingin membahas mengenai: pembuatan fungsi, percabangan, dan pemanggilan fungsi.

Calling Convention

Jika kita membuat seluruh program sendiri, tidak memanggil fungsi apapun yang lain, maka kita punya kebebasan memakai register manapun juga untuk kebutuhkan apapun. Misalnya kita ingin memanggil fungsi, parameter pertama bisa di register r0, parameter kedua di r1, dst. Atau terserah kalau mau mulai dari r5 juga boleh.

Tapi ketika kita ingin memakai library atau kode orang lain, maka kita perlu memiliki semacam standard/konvensi agar berbagai program bisa berinteroperasi. Istilah untuk ini adalah calling convention, sebuah calling convention biasanya menyatakan:

  • Bagaimana passing parameter, register mana yang dipakai (atau apakah langsung dipassing menggunakan stack)
  • Di register mana hasil kembalian fungsinya
  • Register-register mana saja yang boleh diubah di dalam subrutin/fungsi (scratch registers), atau disebut juga caller saved registers
  • Register-register mana saja yang harus disimpan (must be preserved) dalam subrutin/fungsi, atau callee saved registers

Untuk register yang harus disimpan, maksudnya: ketika keluar dari subrutin, maka nilai register tersebut harus sama dengan ketika masuk. Artinya kita boleh saja mengubah register tersebut di dalam fungsi, asalkan kita simpan dulu, entah di stack atau di tempat lain, dan sebelum kembali (return), nilai registernya dikembalikan lagi.

Lanjutkan membaca Calling convention pada AMD64, ARM64, dan RISCV64

Hello, World! di Linux dalam Assembly AMD64, ARM64, dan RISCV64

Tadinya saya ingin menulis tentang arsitektur RISC-V, dan memulai dengan membuat Hello, World!, tapi setelah diingat lagi, saya belum pernah membahas assembly di berbagai arsitektur lain. Jadi di tulisan ini saya ingin membuat program Hello World di Linux untuk arsitektur 64 bit: x86/64 disebut juga AMD64, ARM64 dan RISCV64.

Dulu waktu mulai mengenal assembly, saya menganggap ini susah. Tapi setelah diingat lagi, semuanya karena keterbatasan teknologi yang saya pakai saat itu:

  • Saya memakai DOS, jika salah memprogram assembly maka komputer bisa restart atau hang dengan mudah, bahkan ketika masuk ke Windows 95/98, masih sangat mudah membuat crash dengan program DOS sederhana
  • Tool yang ada juga terbatas, misalnya saya membuat program assembly mode grafik di DOS, maka debugger tidak bisa jalan ketika program berjalan
  • Arsitektur x86 memang lebih rumit dibandingkan arsitektur lain, karena masalah sejarah (arsitektur ini berusaha kompatibel dengan versi sebelumnya)

Dengan sistem operasi modern seperti Linux dan tools yang ada saat ini, belajar assembly berbagai arsitektur sudah semakin mudah:

  • Hardware dan sistem operasi mendukung memory protection, tidak mudah membuat crash
  • Sistem multi window memudahkan memprogram grafik dan menjalankan debugger di Window lain. Selain itu jika ingin memprogram grafik fullscreen juga bisa dilakukan via remote SSH
  • Ternyata berbagai arsitektur lain lebih sederhana daripada x86

Saya memakai HoneyComb LX untuk target ARM dan Nezha SBC untuk target RISCV64.

Lanjutkan membaca Hello, World! di Linux dalam Assembly AMD64, ARM64, dan RISCV64