Loading AI tools
uygulanan işlemlerle programlama dilinin birbirine çok yakın olduğu düşük seviye programlama dilleri Vikipedi'den, özgür ansiklopediden
Assembly dili (İngilizce: assembly language), bir işlemcinin komut kümesi üzerine tanımlanmış alt seviye bir dildir. Assembly dili kolay hatırlanabilir semboller (“İngilizce: mnemonics”) tanımlar ve böylece işlemcinin makina koduna karşılık gelen sayı dizilerinin bilinmesine gerek kalmaz. Assembly dili, platformdan bağımsız yüksek seviyeli programlama dillerinin aksine, işlemci mimarisine bağımlıdır. Tipik uygulamaları; cihaz sürücüleri, alt seviyeli dahili (embedded) ve gerçek zamanlı sistemlerdir. Bır assembly programı assembler kullanılarak makine koduna çevrilir.
Assembler komutları işlem kodlarına çevirerken hafıza mahalleri (memory locations) için sembolik isimler belirler ve “object code”unu oluşturur. Sembolik referansların kullanılması, program değişikliklerinden sonra elle yapılan adres güncelleştirmeleri ve hesaplamaları gerektirmemesi assembler'ın en önemli özelliğidir. Assembler metinsel ikameyi (yerine koymayı) yerine getirmek için – örneğin, bir alt rutin (subroutine) yerine “inline” olarak çalışacak komutların ortak kısa serilerini üretmek için- makro oluşturma imkânları içerir.
Assembler programları genellikle yüksek seviyeli dilleri yazma konusunda derleyicilerden daha az karmaşıktır ve 1950'li yıllardan beri kullanılmaktadır. (Bilgisayarların ilk günlerindeki ilk assembler programları o nesildeki programcılar için önemli bir keşifti.) Modern assembler programları, bilhassa MIPS, Sun SPARC ve HP PA-RISC gibi RISC'e dayalı mimariler CPU “pipeline” verimliliğini sağlamaya yönelik komutları (instruction) optimize eder.
Özelleştirilmiş üst seviye assembler programları aşağıda belirtilen soyutlamaları sağlar:
Assembly dilinde yazılan bir program pek çok yerine getirilebilir komutlara (emirlere) tekabül eden komut “mnemonic”lerin (sembollerin) bir serisinden oluşur ve bir assembler tarafından işlendiğinde hafızaya yüklenebilir.
Örneğin; bir x86/IA-32 işlemci makine dilinde ifade edilmiş olan aşağıdaki ikili (binary) komutu yerine getirebilir:
Assembly'dekı karşılığı çok daha kolay hatırlanır:
mov
sembolü (mnemonic) bir işlem kodu olup, “move” (taşı) sözcüğünü kısaltmak için komut kümesi tasarımcısı tarafından seçilmiştir. Virgülle ayrılmış argümanların veya parametrelerin bir listesi işlem kodunu izler. ;
ve sonrasi yorum satırıdır.
Assembly dilinin makine diline dönüştürülmesi bir çevirici tarafından gerçekleştirilir ve bunun tersi olan işlem bir disassembler tarafından yapılır. Yüksek seviyeli dillerin aksine basit assembly ifadeleri ile makine dili komutları arasında genellikle 1:1 ilişki bulunur. Ancak, bazı hallerde bir çevirici ortak ihtiyaç duyulan işlevselliği sağlayacak olan çeşitli makine dili komutlarına yayılan pseudoinstructions (yapma emirler) sağlayabilir. Örneğin, bir “büyük veya eşit ise dallandır” emrine sahip olmayan bir makine için bir çevirici makinenin “eğer küçük ise kur” (set if less than) ve “eğer sıfır ise dallandır (kurulan emrin neticesinde)” ifadelerine kadar uzanan bir “yapay emri” assembler tarafından üretilebilir. Bazı assembler programları pek çoğu ayrıca daha karmaşık kod ve veri dizisini üretmek amacıyla satıcılar ve programcılar tarafından kullanılan zengin bir makro dili de sağlar.
Her bilgisayar mimarisi kendine özgü makine diline sahiptir ve dolayısıyla kendisine ait bir çevirme dili vardır. Bilgisayarlar destekledikleri işlemlerin sayısına ve tipine göre birbirlerinden farklıdır. Bilgisayarlar aynı zamanda farklı ebat ve sayıda kayıt ünitelerine ve hafızada veri tiplerinin farklı örneklerine sahip olabilirler. Pek çok genel amaçlı bilgisayar esas itibarıyla aynı işlevselliği sürdürürken, bu işlevlerin yapılış tarzı farklıdır; çevirme dilleri bu farklılıkları yansıtır.
Makine dili ifadelerden (statements) veya komutlardan (instructions) oluşur. İşlemci mimarisine bağlı olarak, verilen bir komut:
belirleyebilir.
Daha karmaşık işlemler, sırasıyla yerine getirilen (bir Von Neumann makinesinde) veya başka bir şekilde kontrol akış komutlarıyla yönlendirilen bu basit komutların birleştirilmesiyle oluşturulur.
Pek çok komut kümesinden yer alan bazı işlemler:
• Taşıma
. bir sabit değere bir kayıt yerini ayarlayınız (CPU'nun kendisinde geçici bir “scratchpad” (bir bilgisayar sisteminde geçici sonuçları tutmak için kullanılan bir bellek) yeri)
. verileri bir bellek yerinden bir kayıt yerine veya kayıt yerinden bir bellek yerine taşıyınız. Bu işlem daha sonra bir hesaplama yapmak veya hesaplama sonucunun saklamak için verilerin temin edilmesi amacıyla yapılır.
. donanım cihazlarından verileri okuyunuz ve yazınız.
• Hesaplama
. sonuçları bir kayıt yerine yerleştirerek iki kayıt yerinin değerlerini toplayınız, çıkarınız, çarpınız veya bölünüz.
. bir çift kayıt yerindeki (pair of registers) ilgili bit'lerin birleşimini/ayrımını (ve/veya) alarak veya bir kayıt yerinde (register) her bir bit'i eksilterek bit'e yönelik işlemleri yapınız.
. Kayıt yerlerindeki iki değeri karşılaştırınız (örneğin, birinin diğerinden az olup olmadığını veya ikisinin de birbirlerine eşit olup olmadıklarını anlamak için)
• Program akışının etkilenmesi
. programda başka bir yere atlayınız ve orada komutları yerine getiriniz.
. belli bir koşulun oluşması halinde başka bir yere atlayınız.
. başka bir yere atlayınız, ancak (bir çağrıya) dönüş noktası olarak bir sonraki komutun yerini saklayınız.
Bazı bilgisayarlar içerdikleri komut grubunda karmaşık (complex) komutlara sahiptirler. Tek bir “complex” komut diğer bilgisayarlarda pek çok komutları alabileceği bir şeyi yapar. Bu tür komutlar çoklu adımlar atan, çoklu fonksiyonel birimleri kontrol eden veya başka bir şekilde belli bir işlemci tarafından uygulanan basit talimatların tümünden daha hacimli görünen komutlar olarak sınıflandırılırlar. “Complex” (Karmaşık) komutların bazı örnekleri aşağıda verilmiştir:
Son zamanlarda özellikle çok popüler hale gelen bir kompleks (karmaşık) komut türü SIMD işlemi veya aynı zamanda çoklu veri parçaları üzerinde aynı aritmetik işlemi yapan bir işlem olan vektör komutudur. SIMD komutları çoğunlukla ses, görüntü ve video işleminde bulunan algoritmaların kolayca paralelizasyonunu sağlar. MNX, 3DNow ve AltiVec gibi ticari markalarda muhtelif SIMD uygulamaları piyasaya sunulmuştur.
Komut takımlarının (grubu) tasarımı karmaşık bir husustur. Basit bir komut takımı küçültülmüş işlemci büyüklüğü ve düşük enerji tüketimiyle birlikte yüksek hızlar için potansiyel oluşturabilir; daha karmaşık olan genel işlemleri optimize edebilir, bellek/kaşe verimliliğini artırabilir veya programlamayı basitleştirebilir. Bu farklılık genellikle CISC’ye (Complex Instruction set Computer) (Kompleks Komut Kümesiyle çalışan Bilgisayar) karşı RISC (Reduced Instruction Set Computer) (Küçültülmüş Komut Kümesiyle çalışan Bilgisayar) açısından tartışılır, ancak bu bir aşırı basitleştirmedir. (Örneğin, RISC kavramı bir mikro programlanan mimariye açık – assembly dil programlanmasında direkt yoldan ziyade derleyici teknoloji tarafından işletilmeyi amaçlayan- olarak düşünülebilir. Programlama kolaylığı ve pek çok optimizasyon meseleleri tartışılacak bir konuyu teşkil eder). İlgili yorumlar için komut grubuna (instruction set) bakınız.
Assembly dilindeki komutlar (emirler) yüksek seviyeli bir dilin aksine genellikle oldukça basittir. Her bir komut tipik olarak bir işlem kodundan (veya, sadece, komut) artı sıfır veya daha fazla “operand” lardan (işlem faktörlerinden) ibarettir. Komutların pek çoğu tek bir değere veya değer çiftine atıfta bulunur. Dilde kodlanan bir komut genellikle doğrudan yerine getirilebilir makine dili komutuna tekabül eder.
Pek çok assembly dillerinde ortak olarak bulunan diğer elemanlar arasında aşağıdakiler yer alır:
Söz konusu özellikler yüksek seviyeli dil tasarımlarından ödünç alınır. Bunlar kodlamada alt seviyeli kodu sürdürme problemlerini büyük ölçüde basit hale getirebilir. Derleyiciler veya “disassembler”ler (derlenmiş makina kodunu assembly diline çeviren program, tersine çevirici) tarafından üretilmiş olan ham (işlenmemiş) assembly kaynak kodunun – yani, yorumsuz, anlamlı semboller, veya veri tanımları – okunması oldukça zordur.
Pek çok assembly dili yukarıda belirtilen temel karakteristikleri paylaşır. Ancak, bazı istisnalar bulunmaktadır:
Büyük ölçekli assembly dilinin gelişmesindeki gerilemeden bu yana daha sofistike çeviriciler için çok az görünür talep olmuştur.
Tarihsel olarak tamamen assembly dilinde olmak üzere çok sayıda programlar yazılmıştır. Çalışan sistemler 1970'li yıllarda ve 1980'li yılların başlangıcında C'nin yaygın bir şekilde kullanılmasının kabul edilmesine kadar hemen hemen münhasıran assembly dilinde yazılmışlardı. Büyük şirketler tarafından yazılan büyük miktarda IBM ana gövde (mainframe) yazılımı dahil pek çok ticari uygulamalar da assembly dilinde yazılmıştı. Birtakım büyük şirketlerin 80'li yıllarda assembly dil uygulaması altyapılarını muhafaza etmelerine karşın COBOL ve FORTRAN dolayısıyla bu işin çoğunu değiştirmiştir.
İlk mikrobilgisayarların pek çoğu, genellikle çalışan sistemler ve geniş uygulamalar dahil elle kodlamalı assembly diline bel bağlamıştı. Bunun nedeni adı geçen sistemlerin konulan özel (idiosyncratic) bellek ve display mimarileri ve sağlanan sınırlı “buggy” sistem servisleri yüzünden ciddi kaynak sıkıntıları içinde bulunmalarıydı. Belki de daha önemlisi mikrobilgisayar kullanımına uygun birinci sınıf yüksek seviyeli dil derleyicilerinin bulunmayışıydı. Bir psikolojik faktöründe bunda rolü olmuş olabilir: mikrobilgisayar programcılarının ilk nesli bir hobici (meraklı), “teller ve pense” davranışı içindeydi. Bu zamandan kalan tipik büyük assembly dil programlarının örnekleri CP/M ve MS-DOS işlem sistemleridir; ilk IBM PC “spreadsheet” (hesap tablosu) programı Lotus 123 ve hemen hemen tüm popüler oyunlar için Commodore 64. Hatta 1990'lı yıllarda Mega Drive/Genesis ve Super nintendo Entertainment System için pek çok oyunlar dahil, pek çok konsol video oyunları assembly dilinde yazılmıştı. Popüler pasaj (arcade) oyunu NBA Jam (1993) buna başka bir örnektir.
Günümüzde dikkatleri çok az çekse de assembly dilinin yüksek seviyeli dillere göre faydalılığı ve performansı üzerinde sürekli olarak tartışmalar yapılmaktadır. Assembly dili önemli olduğunda kullanılan spesifik uygun bir yere sahiptir: aşağıya bakınız. Ancak genel olarak modern işlemciler etkin elle yapılan optimizasyonu giderek zorlaştırmaktadır. Ayrıca ve verimliliği sevenlerin korkulu umutsuzluklarına karşın artış gösteren işlemci performansı pek çok CPU'ların zamanın çoğunda boş oturduklarını, I/O işlemleri ve çağrı (paging) gibi önceden tahmin edilen sıkıntıların neden olduğu gecikmelerin söz konusu olduğunu ifade etmektedir. Bu pek çok programcılar için ham kodun çalışma hızını bir mesele olmaktan çıkarmıştır. (Böylece âşikâr performans etkisi olmaksızın yorumlanan dillerin kullanımı artırılmıştır.)
Aslında günümüz uzman pratisyenlerin assembly dilini tercih edebileceği sadece çok az durum vardır: şöyle ki:
Günümüzde pek az programcı günlük bazda assembly dilini kullanma gereğini duymaktadır. Performans-kritik uygulamalar için C gibi alt seviyeli bir dil genellikle seçilebilecektir. Şimdi, bir assembly dilinde yazılan programdan daha az verimli olan bir C programını yazmak çok güçtür.
Ancak, assembly dili pek çok Bilgisayar Bilimi programlarında hâlâ öğretilmektedir. Bir araç olarak günümüzde az sayıda programcılar düzenli olarak assembly dili ile çalışmaktaysalar da kolayca görülmeyen ancak önemli olan kavramlar hâlâ önemini sürdürmektedir. İkili (binary) aritmetik, bellek tahsisi, “stack” işleme, karakter seti kodlaması, kesme işlemi ve derleyici tasarımı gibi ana konular üzerinde ayrıntılı olarak çalışmak bir bilgisayarın donanım seviyesinde nasıl çalıştığını tam olarak kavramadan çok zor olacaktı. Bir bilgisayarın davranışı esas itibarıyla kendi komut setiyle belirlendiğinden, bu kavramların öğrenilmesindeki mantıksal usul bir assembly dili üzerinde çalışma yapmaktır. Neyse ki, pek çok modern bilgisayarlar benzer komut setlerine sahiptir, böylece tek bir assembly dili üzerindeki çalışma temel kavramları (concepts) öğrenmek, assembly dili kullanımının uygun olabileceği durumları tanımak ve verimli icra edilebilir bir kodun yüksek seviyeli dillerden yaratılabileceğini anlamak için yeterlidir.
Elle kodlanmış assembly dili tipik olarak bir sistemin BIOS'unda kullanılır. Bu alt seviyeli kod diğerleriyle birlikte OS'yi tanıtmadan (booting) önce sistem donanımını çalıştırmak ve test etmek için kullanılır ve ROM içinde saklanır. Bir kez belli bir seviyedeki donanımın çalıştırılması yapılırsa, icraat diğer koda geçer, tipik olarak yüksek seviyeli dillerde yazılmıştır; fakat güç devreye alındıktan hemen sonra çalışan kod genellikle assembly dilinde yazılır. Aynı şey pek çok “boot” yükleyicileri içinde geçerlidir.
Pek çok derleyiciler tam derleme yapılmadan önce ilk iş olarak, assembly kodunun hatadan kurtarma (debugging) ve optimizasyon amacıyla görülmesine imkân vererek yüksek seviyeli dillerin assembly (çevirme) içine alınmasını sağlar.
Bu imkânları kullanan programlar, Linux kernel gibi, daha sonra herbir donanım platformu üzerinde farklı assembly dili kullanan soyutlamalarını inşa edebilir. Sistemin taşınabilir kodu daha sonra bu işlemciye özel elemanları tek bir arayüz vasıtasıyla kullanabilir.
Pek çok program sadece makine kodu formunda dağıtıldıklarından ve makine kodunun genellikle assembly diline çevrilmesi kolay olduğundan ve bu formda dikkatlice incelendiğinden, fakat bir yüksek seviyeli dile çevirmek çok zor olduğundan, assembly dili ters mühendislikte de kıymetlidir. Etkileşimli (interaktif) disassembler gibi araçlar bu amaca yönelik “disassembly”nin kapsamlı kullanımına imkân verir.
Not: Dil çeviricisi teriminin kullanılması şüphesiz potansiyel olarak karıştırılır ve müphemdir, çünkü bu terim aynı zamanda assembly dil komutlarını makine koduna çeviren faydalanma (utility) programının da adıdır. Bazıları bunun tam karşılığı olmadığını veya hata olduğunu düşünebilir. Ancak, bu kullanım profesyoneller arasında ve literatürde on yıldan beri yaygın bir kullanıma sahiptir. Aynı şekilde bazı ilk bilgisayarlar çeviricilerine assembly programı olarak adlandırmışlardır.
Hem geçmişte hem de günümüzde verilen herhangi bir kişisel bilgisayar, ana gövde, dahili sistem ve oyun konsolu için çeviricilerden (muhtemelen düzinelerce) en az biri yazılmıştır. Örnekler için çeviriciler listesine bakınız.
Unix sistemlerinde çevirici geleneksel olarak “as” olarak adlandırılır; kodun tek bir gövdesi olmasa da, her bir port için tipik olarak yeniden yazılır. Unix varyantlarının bir kısmı GAS kullanır.
İşlemci grupları içerisinde her bir çevirici kendine ait diyalekte sahiptir. Bazen, bazı çeviriciler başka bir çeviricinin diyalektini okuyabilir, örneğin, TASM eski MASM kodunu okuyabilir, fakat eski MASM kodu TASM'yi okuyamaz. FASM ve NASM aynı sentaksa sahiptirler, fakat her biri birbirlerine çevirmeyi güçleştiren farklı makroları destekler. Temel tamamıyla aynıdır, fakat ileri özellikler farklı olacaktır.
Ayrıca, assembly (çevirme) bazen aynı tip CPU üzerindeki farklı çalışan tüm sistemlerde taşınabilir. Çalışan sistemler arasında konvansiyonlar olarak çağrılması sıklıkla biraz farklıdır ve büyük dikkat ile assembly dilinde bir miktar portatifliğin elde edilmesi mümkündür, genellikle çalışan sistemler arasında değişmeyen bir C kütüphanesi ile bağlanarak. Ancak, arayanın çalışan sistemler arasında değişebilen ön işlemci makroları kullanmasını isteyen C kütüphanesi ile portatif olarak bağlanmak mümkün değildir.
Örneğin, derlemeden önce “libe”deki pek çok şey OS-specific, C-specific şeyleri programda yapmak için ön işlemciye bağlıdır. Aslında, bazı fonksiyonların ve sembollerin ön işlemcinin dışında varlıkları da garanti edilemez. En kötüsü, “structs” ın büyüklüğü ve alan sırası, aynı zamanda “off t” gibi belli “typedefs” büyüklüğü assembly dilinde hiç yoktur ve parametreler olarak sadece basit tam sayıları ve ibreleri alanların dışında “libe” deki fonksiyonları portatif olarak aramayı imkânsız hale getirerek Linux versiyonları arasında da farklıdırlar.
C gibi bazı yüksek seviyeli bilgisayar dilleri, assembly kodunun oldukça kısa bölümlerinin yüksek seviyeli dil kodunun içerisine yerleştirilebilindiği “Inline assembly”yi desteklerler. “Borland Pascal” de bir “asm” şifresiyle açılan bir çevirici derleyiciye sahip olmuştur. Bu başlıca Mouse (fare) ve COM-port sürücüleri oluşturmakta kullanılmıştı.
Assembly dil programlarını hatadan arındırmak (debug) için pek çok kişi bir benzetici (emulator) kullanır.
Aşağıda C, Visual Basic ve Assemblyde introduction programlarının farkı. Dil seviyesi yükseldikçe kod kısalmaktadır:
Assembly
title Hello World Program (hello.asm)
dosseg
.model small
.stack 100h
.data
hello_message db 'Hello World!',0dh,0ah,'$'
.code
main proc
mov ax,@data
mov ds,ax
mov ah,9
mov dx,offset hello_message
int 21h
mov ax,4C00h
int 21h
main endp
end main
C
#include<stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
Visual Basic
Sub Main()
MsgBox("Hello, World!") '
End Sub
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.