Assembly

bilgipedi.com.tr sitesinden
Assembly dili
Motorola 6800 Assembly Language.png
Motorola MC6800 için orijinal montaj dilini (sağda) ve birleştirilmiş formu gösteren bir assembler'dan tipik ikincil çıktı
ParadigmaZorunlu, yapılandırılmamış
İlk ortaya çıktı1949; 74 yıl önce
Yazma disipliniHiçbiri

Bilgisayar programlamada, assembly dili (veya assembler dili veya sembolik makine kodu), dildeki talimatlar ile mimarinin makine kodu talimatları arasında çok güçlü bir yazışma olan herhangi bir düşük seviyeli programlama dilidir. Assembly dilinde genellikle makine komutu başına bir ifade bulunur (1:1), ancak sabitler, yorumlar, assembler direktifleri, örneğin bellek konumlarının sembolik etiketleri, kayıtlar ve makrolar da genellikle desteklenir.

Assembly kodu, assembler olarak adlandırılan bir yardımcı program tarafından çalıştırılabilir makine koduna dönüştürülür. "Assembler" terimi genellikle Wilkes, Wheeler ve Gill'in 1951 tarihli The Preparation of Programs for an Electronic Digital Computer adlı kitaplarına atfedilir, ancak onlar bu terimi "birkaç bölümden oluşan başka bir programı tek bir programa monte eden bir program" anlamında kullanmışlardır. Dönüştürme işlemi, kaynak kodun birleştirilmesinde olduğu gibi montaj olarak adlandırılır. Bir assembler bir programı işlerken hesaplama adımına montaj zamanı denir.

Montaj makine kodu talimatlarına bağlı olduğundan, her montaj dili belirli bir bilgisayar mimarisine özgüdür.

Bazen aynı mimari için birden fazla assembler vardır ve bazen bir assembler bir işletim sistemine veya belirli işletim sistemlerine özgüdür. Çoğu assembly dili işletim sistemi çağrıları için özel bir sözdizimi sağlamaz ve çoğu assembly dili herhangi bir işletim sistemi ile evrensel olarak kullanılabilir, çünkü dil, tüm sistem çağrı mekanizmalarının nihayetinde dayandığı işlemcinin tüm gerçek yeteneklerine erişim sağlar. Assembly dillerinin aksine, çoğu yüksek seviyeli programlama dili genellikle birden fazla mimaride taşınabilir ancak yorumlama ya da derleme gerektirir ki bunlar assembling'den çok daha karmaşık görevlerdir.

Bilgi işlemin ilk on yıllarında, hem sistem programlama hem de uygulama programlamanın tamamen assembly dilinde gerçekleştirilmesi yaygındı. Bazı amaçlar için hala vazgeçilmez olsa da, programlamanın büyük çoğunluğu artık daha yüksek seviyeli yorumlanmış ve derlenmiş dillerde yürütülmektedir. Fred Brooks, "No Silver Bullet" (Gümüş Kurşun Yok) adlı kitabında assembly diliyle programlamadan uzaklaşmanın etkilerini özetlemiştir: "Şüphesiz yazılım üretkenliği, güvenilirliği ve basitliği için en güçlü darbe, programlama için yüksek seviyeli dillerin aşamalı olarak kullanılması olmuştur. Çoğu gözlemci bu gelişmenin üretkenlikte en az beş kat artış sağladığını ve güvenilirlik, basitlik ve anlaşılabilirlikte de eş zamanlı kazanımlar sağladığını belirtmektedir."

Günümüzde, performans nedenleriyle veya üst düzey dil tarafından desteklenmeyen şekillerde donanımla doğrudan etkileşim kurmak için daha üst düzey bir dilde uygulanan daha büyük sistemler içinde az miktarda assembly dili kodu kullanmak tipiktir. Örneğin, Linux çekirdeği kaynak kodunun 4.9 sürümünün %2'sinden biraz azı assembly dilinde yazılmıştır; %97'sinden fazlası ise C dilinde yazılmıştır.

Motorola 6800 Assembly Language.png

Çevirme dili ya da assembly dili (İngilizce İngilizceassembly language), bir bilgisayarda tüm işlemleri işlemci gerçekleştirir ve işlemcinin de, makine dili denen kendine has bir dili vardır. İşlemci yalnızca bu dili anlar ve bu dili kullanarak anlaşırsınız. Fakat bu dili öğrenmek ve kullanmak çok zordur. Bu nedenle insanların anlayabileceğimiz bir dilde konuşup ardından işlemcinin diline çeviren yazılımlar geliştirilmiştir. Bunlara derleyici denir. Derleyiciler de bir dile sahiptir fakat işlemcinin diline göre çok daha kolaydır. İşte bu derleyici dillerinden biri de Assemblydir. Çevirici dil, bilgisayar programlarının yazılmasında kullanılan alt seviyeli bir dildir. Assembly dili programlarının yazılımında insan dostu sembollerin (İngilizceİngilizcemnemonics”) kullanılması, daha fazla hataya yatkın ve zaman alıcı ilk bilgisayarlarda kullanılmış olan bir hedef bilgisayarının sayısal makine kodunda doğrudan programlama çalışmasının yerine geçmiştir. Bir assembly dil programı çevirici (İngilizceİngilizceassembler”) olarak adlandırılan faydalı bir program tarafından hedef bilgisayarın makine koduna çevrilir. (Bir çevirici bir derleyiciden (İngilizcecompiler) farklıdır ve genellikle “İngilizcemnemonic” ifadelerden makine komutlarına teke tek (izomorfik) çeviriler yapar.)

Assembly dil programları, genellikle platformdan bağımsız olan yüksek seviyeli programlama dillerinin aksine bir hedef bilgisayar mimarisine sıkı sıkıya bağlıdır ( ve bu bilgisayara özeldir). Çok fazla sofistike olan çeviriciler programın gelişmesini kolaylaştırmak, çeviri işlemini kontrol etmek ve hataların düzeltilmesine yardımcı olmak amacıyla mekanizmalar kullanarak program komutlarının temel çevirisini genişletir.

Assembly dili bir zamanlar programlamada çok fazla kullanılmaktaydı, ancak günümüzde daha az kullanılma eğilimindedir, öncelikle doğrudan donanım manipülasyonunun veya anormal performans hususları söz konusu olduğu zaman bu dil kullanılmaktadır. Tipik uygulamaları cihaz sürücüleri, alt seviyeli dahili (embedded) sistemleri ve gerçek zaman uygulamalarıdır.

Assembly(çeviri) ve assembler (çevirici) terimlerinin çelişkili kullanımlarına ilişkin olarak aşağıdaki terminoloji bölümüne bakınız.

Assembly dili sözdizimi

Assembly dili, örneğin her düşük seviyeli makine komutunu veya işlem kodunu, her yönergeyi, tipik olarak her mimari kaydı, bayrağı vb. temsil etmek için bir anımsatıcı kullanır. Bazı anımsatıcılar yerleşik olabilir ve bazıları kullanıcı tarafından tanımlanabilir. Birçok işlem tam bir komut oluşturmak için bir veya daha fazla operand gerektirir. Çoğu assembler, program ve bellek konumları için adlandırılmış sabitlere, kayıtlara ve etiketlere izin verir ve operandlar için ifadeleri hesaplayabilir. Böylece, programcılar sıkıcı tekrarlayan hesaplamalardan kurtulur ve assembler programları makine kodundan çok daha okunabilirdir. Mimariye bağlı olarak, bu öğeler sabit adreslerin yanı sıra ofsetler veya diğer veriler kullanılarak belirli talimatlar veya adresleme modları için de birleştirilebilir. Birçok assembler program geliştirmeyi kolaylaştırmak, assembly sürecini kontrol etmek ve hata ayıklamaya yardımcı olmak için ek mekanizmalar sunar.

Bazıları sütun odaklıdır, belirli sütunlarda belirli alanlar bulunur; bu 1950'lerde ve 1960'ların başında delikli kart kullanan makineler için çok yaygındı. Bazı birleştiriciler, noktalama işaretleri, beyaz boşluk gibi sınırlayıcılarla ayrılmış alanlarla serbest biçimli sözdizimine sahiptir. Bazı assembler'lar melezdir, örneğin etiketler belirli bir sütunda ve diğer alanlar sınırlayıcılarla ayrılmıştır; bu 1960'larda sütun odaklı sözdiziminden daha yaygın hale gelmiştir.

IBM Sistem/360

System/360 için tüm IBM assembler'larında varsayılan olarak 1. sütunda bir etiket, 2-71. sütunlarda sınırlayıcılarla ayrılmış alanlar, 72. sütunda bir devam göstergesi ve 73-80. sütunlarda bir sıra numarası bulunur. Etiket, işlem kodu, işlenenler ve yorumlar için sınırlayıcı boşluktur, tek tek işlenenler ise virgül ve parantezlerle ayrılır.

Terminoloji

  • Bir makro assembler, (parametrelendirilmiş) assembly dili metninin bir adla temsil edilebilmesi ve bu adın genişletilmiş metni diğer koda eklemek için kullanılabilmesi için bir makro talimat tesisi içeren bir assembler'dır.
    • Açık kod, bir makro tanımı dışındaki herhangi bir assembler girdisini ifade eder.
  • Çapraz assembler (ayrıca bkz. çapraz derleyici), ortaya çıkan kodun çalışacağı sistemden (hedef sistem) farklı türde bir bilgisayar veya işletim sistemi (ana sistem) üzerinde çalıştırılan bir assembler'dır. Çapraz birleştirme, gömülü sistem veya mikrodenetleyici gibi yazılım geliştirmeyi destekleyecek kaynaklara sahip olmayan sistemler için program geliştirmeyi kolaylaştırır. Böyle bir durumda, ortaya çıkan nesne kodunun hedef sisteme, salt okunur bellek (ROM, EPROM, vb.), bir programlayıcı (salt okunur bellek mikrodenetleyicilerde olduğu gibi cihaza entegre edildiğinde) ya da nesne kodunun tam bit bit kopyası veya bu kodun metin tabanlı bir gösterimi (Intel hex veya Motorola S-record gibi) kullanılarak bir veri bağlantısı yoluyla aktarılması gerekir.
  • Yüksek seviyeli assembler, gelişmiş kontrol yapıları (IF/THEN/ELSE, DO CASE, vb.) ve yapılar/kayıtlar, birlikler, sınıflar ve kümeler dahil olmak üzere yüksek seviyeli soyut veri türleri gibi daha çok yüksek seviyeli dillerle ilişkili dil soyutlamaları sağlayan bir programdır.
  • Bir mikro birleştirici, bir bilgisayarın düşük seviyeli çalışmasını kontrol etmek için bellenim adı verilen bir mikro programın hazırlanmasına yardımcı olan bir programdır.
  • Bir meta assembler, "bir assembly dilinin sözdizimsel ve anlamsal tanımını kabul eden ve bu dil için bir assembler üreten bir programdır" veya böyle bir tanımla birlikte bir assembler kaynak dosyasını kabul eden ve kaynak dosyasını bu tanıma uygun olarak birleştiren bir programdır. SDS 9 Serisi ve SDS Sigma serisi bilgisayarlar için "Meta-Symbol" assembler'lar meta assembler'lardır. Sperry Univac ayrıca UNIVAC 1100/2200 serisi için bir Meta-Assembler sağlamıştır.
  • satır içi assembler (veya gömülü assembler) yüksek seviyeli bir dil programı içinde bulunan assembler kodudur. Bu genellikle donanıma doğrudan erişime ihtiyaç duyan sistem programlarında kullanılır.

Anahtar kavramlar

Montajcı

Bir assembler programı, işlemler ve adresleme modları için mnemonik ve sözdizimi kombinasyonlarını sayısal eşdeğerlerine çevirerek nesne kodu oluşturur. Bu gösterim tipik olarak bir işlem kodunun ("opcode") yanı sıra diğer kontrol bitlerini ve verileri içerir. Birleştirici ayrıca sabit ifadeleri hesaplar ve bellek konumları ve diğer varlıklar için sembolik isimleri çözümler. Sembolik referansların kullanımı, program değişikliklerinden sonra sıkıcı hesaplamalardan ve manuel adres güncellemelerinden tasarruf sağlayan assembler'ların önemli bir özelliğidir. Çoğu assembler ayrıca metinsel ikame yapmak için makro olanakları da içerir - örneğin, alt program adı yerine satır içi olarak yaygın kısa talimat dizileri oluşturmak için.

Bazı assembler'lar komut setine özgü bazı basit optimizasyon türlerini de gerçekleştirebilir. Bunun somut bir örneği, çeşitli satıcıların her yerde bulunan x86 assembler'ları olabilir. Atlama boyutlandırma olarak adlandırılan bu işlemcilerin çoğu, istek üzerine herhangi bir sayıda geçişte atlama komutu değiştirmeleri (uzun atlamaların kısa veya göreceli atlamalarla değiştirilmesi) gerçekleştirebilir. Diğerleri, CPU boru hattından mümkün olduğunca verimli bir şekilde yararlanmak için mantıklı bir komut zamanlamasını optimize etmeye yardımcı olabilen RISC mimarileri için bazı birleştiriciler gibi talimatların basit bir şekilde yeniden düzenlenmesi veya eklenmesi bile yapabilir.

Assembler'lar 1950'lerden beri, makine dilinin üzerindeki ilk adım olarak ve Fortran, Algol, COBOL ve Lisp gibi yüksek seviyeli programlama dillerinden önce mevcuttur. Ayrıca, belki de en iyi bilinen örneklerden biri olan Speedcode ile hem assembly hem de yüksek seviyeli dillere benzer özelliklere sahip birkaç çevirmen ve yarı otomatik kod üreteci sınıfı da olmuştur.

Belirli bir CPU veya komut seti mimarisi için farklı sözdizimine sahip birkaç assembler olabilir. Örneğin, x86 ailesinden bir işlemcide bir yazmaca bellek verisi eklemek için kullanılan bir komut orijinal Intel sözdiziminde add eax,[ebx] şeklindeyken, GNU Assembler tarafından kullanılan AT&T sözdiziminde addl (%ebx),%eax şeklinde yazılır. Farklı görünümlere rağmen, farklı sözdizimsel formlar genellikle aynı sayısal makine kodunu üretir. Tek bir assembler, sözdizimsel biçimlerdeki varyasyonları ve bunların tam anlamsal yorumlarını desteklemek için farklı modlara da sahip olabilir (x86 assembly programlamanın özel durumunda FASM-syntax, TASM-syntax, ideal mod vb. gibi).

Geçiş sayısı

Nesne dosyasını üretmek için kaynaktan kaç geçiş gerektiğine (assembler'ın kaynağı kaç kez okuduğuna) bağlı olarak iki tür assembler vardır.

  • Tek geçişli birleştiriciler kaynak kodu bir kez gözden geçirir. Tanımlanmadan önce kullanılan herhangi bir sembol, nesne kodunun sonunda (veya en azından sembolün tanımlandığı noktadan daha erken olmamak kaydıyla) bağlayıcıya veya yükleyiciye "geri dönmesini" ve henüz tanımlanmamış sembolün kullanıldığı yerde bırakılan bir yer tutucunun üzerine yazmasını söyleyen "hatalar" gerektirecektir.
  • Çok geçişli birleştiriciler ilk geçişlerde tüm sembolleri ve değerlerini içeren bir tablo oluşturur, daha sonra kod oluşturmak için sonraki geçişlerde bu tabloyu kullanır.

Her iki durumda da, assembler sonraki sembollerin adreslerini hesaplamak için ilk geçişlerde her komutun boyutunu belirleyebilmelidir. Bu, daha sonra tanımlanan bir işlenene atıfta bulunan bir işlemin boyutu işlenenin türüne veya uzaklığına bağlıysa, assembler'ın işlemle ilk karşılaştığında kötümser bir tahmin yapacağı ve gerekirse bir veya daha fazla "işlem yok" talimatları daha sonraki bir geçişte veya hatalarda. Gözetleme deliği optimizasyonuna sahip bir assembler'da, adresler geçişler arasında yeniden hesaplanarak kötümser kodun hedefe olan tam mesafeye göre uyarlanmış kodla değiştirilmesine izin verilebilir.

Tek geçişli assembler kullanımının ilk nedeni bellek boyutu ve montaj hızıydı - genellikle ikinci bir geçiş sembol tablosunun bellekte saklanmasını (ileri referansları işlemek için), kasetteki program kaynağının geri sarılmasını ve yeniden okunmasını veya bir deste kartın veya delikli kağıt kasetin yeniden okunmasını gerektirirdi. Çok daha büyük belleklere (özellikle disk depolama) sahip daha sonraki bilgisayarlar, bu tür yeniden okumalar olmadan gerekli tüm işlemleri gerçekleştirecek alana sahipti. Çok geçişli assembler'ın avantajı, hataların bulunmamasının bağlama işlemini (ya da assembler doğrudan çalıştırılabilir kod üretiyorsa program yüklemesini) daha hızlı hale getirmesidir.

Örnek: aşağıdaki kod parçasında, tek geçişli bir assembler geriye doğru referansın adresini belirleyebilecektir BKWD ifadeyi birleştirirken S2ancak ileri referansın adresini belirleyemeyecektir. FWD dallanma ifadesini birleştirirken S1Gerçekten de, FWD tanımlanmamış olabilir. İki geçişli bir assembler her iki adresi de geçiş 1'de belirler, böylece geçiş 2'de kod oluşturulurken bilinirler.

S1   B    FWD
  ...
FWD   EQU *
  ...
BKWD  EQU *
  ...
S2    B   BKWD 

Yüksek seviye birleştiriciler

Daha sofistike yüksek seviyeli birleştiriciler aşağıdaki gibi dil soyutlamaları sağlar:

  • Üst düzey yordam/fonksiyon bildirimleri ve çağrıları
  • Gelişmiş kontrol yapıları (IF/THEN/ELSE, SWITCH)
  • Yapılar/kayıtlar, birlikler, sınıflar ve kümeler dahil olmak üzere üst düzey soyut veri türleri
  • Sofistike makro işleme (1950'lerin sonlarından beri örneğin IBM 700 serisi ve IBM 7000 serisi ve 1960'lardan beri IBM System/360 (S/360) ve diğer makineler için sıradan birleştiricilerde mevcut olmasına rağmen)
  • Sınıflar, nesneler, soyutlama, çok biçimlilik ve kalıtım gibi nesne yönelimli programlama özellikleri

Daha fazla ayrıntı için aşağıdaki Dil tasarımı bölümüne bakınız.

Assembly dili

Assembly dilinde yazılmış bir program, bir dizi anımsatıcı işlemci talimatları ve meta ifadeler (çeşitli şekillerde bildirimsel işlemler, yönergeler, sözde talimatlar, sözde işlemler ve sözde işlemler olarak bilinir), yorumlar ve verilerden oluşur. Assembly dili talimatları genellikle bir işlem kodu anımsatıcısından ve ardından bir veri, argüman veya parametre listesi olabilen bir işlenenden oluşur. Bazı talimatlar "zımni" olabilir, bu da talimatın üzerinde çalıştığı verilerin talimatın kendisi tarafından zımnen tanımlandığı anlamına gelir - böyle bir talimat bir işlenen almaz. Ortaya çıkan ifade bir assembler tarafından belleğe yüklenebilen ve çalıştırılabilen makine dili talimatlarına çevrilir.

Örneğin, aşağıdaki komut bir x86/IA-32 işlemcisine 8 bitlik bir değeri bir yazmaca taşımasını söyler. Bu komutun ikili kodu 10110'dur ve ardından hangi yazmacın kullanılacağını belirten 3 bitlik bir tanımlayıcı gelir. AL yazmacının tanımlayıcısı 000'dır, bu nedenle aşağıdaki makine kodu AL yazmacını 01100001 verisiyle yükler.

10110000 01100001

Bu ikili bilgisayar kodu, onaltılık olarak aşağıdaki gibi ifade edilerek daha okunabilir hale getirilebilir.

B0 61

Burada, B0 'Aşağıdaki değerin bir kopyasını AL'ye taşı' anlamına gelir ve 61, ondalık olarak 97 olan 01100001 değerinin onaltılık gösterimidir. 8086 ailesi için assembly dili, bu gibi talimatlar için MOV (move'un kısaltması) anımsatıcısını sağlar, bu nedenle yukarıdaki makine kodu, noktalı virgülden sonra gerekirse açıklayıcı bir yorumla birlikte assembly dilinde aşağıdaki gibi yazılabilir. Bu şekilde okumak ve hatırlamak çok daha kolaydır.

MOV AL, 61h ; AL'ye 97 desimal (61 hex) yükleyin <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Assembly language&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Assembly_language#Assembly_language <span style="color:#dddddd">ⓘ</span>]</span>

Bazı assembly dillerinde (bu dil de dahil olmak üzere) MOV gibi aynı anımsatıcı, ister anlık değerler, ister yazmaçlardaki değerler, ister yazmaçlardaki değerlerin işaret ettiği bellek konumları ya da anlık (diğer bir deyişle doğrudan) adresler olsun, veri yükleme, kopyalama ve taşıma için ilgili komutlar ailesi için kullanılabilir. Diğer assembler'lar "belleği yazmaca taşı" için L, "yazmacı belleğe taşı" için ST, "yazmacı yazmaca taşı" için LR, "anlık işleneni belleğe taşı" için MVI, vb. gibi ayrı işlem kodu anımsatıcıları kullanabilir.

Aynı anımsatıcı farklı komutlar için kullanılıyorsa, bu, anımsatıcıyı takip eden işlenenlere bağlı olarak, veri hariç (örneğin bu örnekteki 61h), anımsatıcının birkaç farklı ikili komut koduna karşılık geldiği anlamına gelir. Örneğin, x86/IA-32 CPU'lar için Intel assembly dili sözdizimi MOV AL, AH, AH kaydının içeriğini AL kaydına taşıyan bir talimatı temsil eder. Bu komutun onaltılık biçimi şöyledir:

88 E0

İlk bayt, 88h, bayt boyutlu bir yazmaç ile başka bir yazmaç veya bellek arasında bir hareketi tanımlar ve ikinci bayt, E0h, her iki işlenenin de yazmaç olduğunu, kaynağın AH olduğunu ve hedefin AL olduğunu belirtmek için kodlanır (üç bit alanıyla).

Aynı anımsatıcının birden fazla ikili komutu temsil edebildiği bu gibi durumlarda, assembler işlenenleri inceleyerek hangi komutun üretileceğini belirler. İlk örnekte, 61h işleneni geçerli bir onaltılık sayısal sabittir ve geçerli bir kayıt adı değildir, bu nedenle yalnızca B0 komutu uygulanabilir. İkinci örnekte, AH işleneni geçerli bir kayıt adıdır ve geçerli bir sayısal sabit (onaltılık, ondalık, sekizlik veya ikili) değildir, bu nedenle yalnızca 88 komutu uygulanabilir.

Assembly dilleri her zaman bu tür bir açıklık sözdizimleri tarafından evrensel olarak zorlanacak şekilde tasarlanmıştır. Örneğin, Intel x86 assembly dilinde, onaltılık bir sabit bir rakamla başlamalıdır, böylece onaltılık 'A' sayısı (ondalık ona eşittir) AH olarak değil, 0Ah veya 0AH olarak yazılır, böylece özellikle AH yazmacının adı olarak görünemez. (Aynı kural, BH, CH ve DH kayıtlarının adlarının yanı sıra, H harfiyle biten ve "BEACH" kelimesi gibi yalnızca onaltılık basamaklı karakterler içeren kullanıcı tanımlı herhangi bir sembolle ilgili belirsizliği de önler).

Orijinal örneğe dönersek, x86 işlem kodu 10110000 (B0) 8 bitlik bir değeri AL kaydına kopyalarken, 10110001 (B1) bunu CL'ye taşır ve 10110010 (B2) bunu DL'ye yapar. Bunlar için Assembly dili örnekleri aşağıda verilmiştir.

MOV AL, 1h ; AL'yi anlık değer 1 ile yükler
MOV CL, 2h ; CL'yi anlık değer 2 ile yükleyin
MOV DL, 3h ; DL'yi anlık değer 3 ile yükleyin

MOV sözdizimi, aşağıdaki örneklerde gösterildiği gibi daha karmaşık da olabilir.

MOV EAX, [EBX] ; EBX adresinde bulunan bellekteki 4 baytı EAX içine taşı
MOV [ESI+EAX], CL ; CL'nin içeriğini ESI+EAX adresindeki bayta taşı
MOV DS, DX ; DX'in içeriğini DS segment kaydına taşır

Her durumda, MOV anımsatıcısı bir assembler tarafından doğrudan 88-8C, 8E, A0-A3, B0-BF, C6 veya C7 işlem kodlarından birine çevrilir ve programcının normalde hangisinin olduğunu bilmesi veya hatırlaması gerekmez.

Assembly dilini makine koduna dönüştürmek bir assembler'ın işidir ve tersi de en azından kısmen bir disassembler tarafından gerçekleştirilebilir. Yüksek seviyeli dillerin aksine, birçok basit assembly deyimi ile makine dili talimatları arasında bire bir örtüşme vardır. Bununla birlikte, bazı durumlarda, bir assembler yaygın olarak ihtiyaç duyulan işlevselliği sağlamak için birkaç makine dili talimatına genişleyen sözde talimatlar (esasen makrolar) sağlayabilir. Örneğin, "büyükse veya eşitse dallan" komutu olmayan bir makine için, bir assembler makinenin "küçükse ayarla" ve "sıfırsa dallan (ayar komutunun sonucuna göre)" komutlarına genişleyen bir sözde komut sağlayabilir. Çoğu tam özellikli assembler ayrıca satıcılar ve programcılar tarafından daha karmaşık kod ve veri dizileri oluşturmak için kullanılan zengin bir makro dili (aşağıda tartışılmıştır) sağlar. Assembler ortamında tanımlanan sözde talimatlar ve makrolar hakkındaki bilgiler nesne programında bulunmadığından, bir disassembler makro ve sözde talimat çağrılarını yeniden yapılandıramaz, ancak assembler'ın bu soyut assembly dili varlıklarından ürettiği gerçek makine talimatlarını disassemble edebilir. Aynı şekilde, assembly dili kaynak dosyasındaki yorumlar assembler tarafından göz ardı edildiğinden ve ürettiği nesne kodu üzerinde hiçbir etkisi olmadığından, bir disassembler kaynak yorumlarını her zaman tamamen kurtaramaz.

Her bilgisayar mimarisinin kendi makine dili vardır. Bilgisayarlar, destekledikleri işlem sayısı ve türü, farklı boyut ve sayıdaki yazmaçlar ve depolama alanındaki veri temsilleri bakımından farklılık gösterir. Genel amaçlı bilgisayarların çoğu temelde aynı işlevselliği yerine getirebilse de, bunu yapma yolları farklıdır; ilgili montaj dilleri bu farklılıkları yansıtır.

Tek bir komut kümesi için, tipik olarak farklı assembler programlarında örneklenen birden fazla anımsatıcı seti veya assembly dili sözdizimi mevcut olabilir. Bu durumlarda, en popüler olanı genellikle CPU üreticisi tarafından sağlanan ve belgelerinde kullanılandır.

İki farklı anımsatıcı setine sahip iki CPU örneği Intel 8080 ailesi ve Intel 8086/8088'dir. Intel, assembly dili anımsatıcıları üzerinde telif hakkı talep ettiğinden (en azından 1970'lerde ve 1980'lerin başında yayınlanan belgelerinin her sayfasında), Intel komut setleriyle uyumlu CPU'ları bağımsız olarak üreten bazı şirketler kendi anımsatıcılarını icat etti. Intel 8080A'nın bir geliştirmesi olan Zilog Z80 CPU, tüm 8080A talimatlarını ve daha fazlasını destekler; Zilog, yalnızca yeni talimatlar için değil, aynı zamanda tüm 8080A talimatları için tamamen yeni bir montaj dili icat etti. Örneğin, Intel'in çeşitli veri aktarım talimatları için MOV, MVI, LDA, STA, LXI, LDAX, STAX, LHLD ve SHLD anımsatıcılarını kullandığı yerde, Z80 assembly dili hepsi için LD anımsatıcısını kullanır. Benzer bir durum, sırasıyla Intel 8086 ve 8088'in geliştirilmiş kopyaları olan NEC V20 ve V30 CPU'lardır. Zilog'un Z80'de yaptığı gibi NEC de Intel'in telif haklarını ihlal ettiği suçlamalarından kaçınmak için 8086 ve 8088 komutlarının tümü için yeni anımsatıcılar icat etmiştir. (Bu tür telif haklarının geçerli olup olmadığı tartışmalıdır ve AMD ve Cyrix gibi daha sonraki CPU şirketleri Intel'in x86/IA-32 komut anımsatıcılarını ne izin ne de yasal ceza olmaksızın aynen yeniden yayınladılar). Pratikte V20 ve V30'u programlayan birçok kişinin aslında Intel'inkinden ziyade NEC'in assembly dilinde yazıp yazmadığı şüphelidir; aynı komut seti mimarisi için herhangi iki assembly dili izomorfik olduğundan (bir şekilde İngilizce ve Domuz Latincesi gibi), bir üreticinin kendi yayınladığı assembly dilini o üreticinin ürünleriyle kullanma zorunluluğu yoktur.

Dil tasarımı

Temel unsurlar

Birleştiricilerin yazarlarının ifadeleri kategorize etme biçimlerinde ve kullandıkları isimlendirmede büyük ölçüde çeşitlilik vardır. Özellikle, bazıları makine anımsatıcısı veya genişletilmiş anımsatıcı dışındaki her şeyi sözde işlem (pseudo-op) olarak tanımlar. Tipik bir assembly dili, program işlemlerini tanımlamak için kullanılan 3 tür komut ifadesinden oluşur:

  • Opcode anımsatıcıları
  • Veri tanımları
  • Montaj direktifleri

Opcode anımsatıcıları ve genişletilmiş anımsatıcılar

Assembly dilindeki talimatlar (deyimler), yüksek seviyeli dillerdekilerin aksine genellikle çok basittir. Genel olarak, bir anımsatıcı tek bir çalıştırılabilir makine dili komutu (bir işlem kodu) için sembolik bir isimdir ve her makine dili komutu için tanımlanmış en az bir işlem kodu anımsatıcısı vardır. Her komut tipik olarak bir işlem veya işlem kodu artı sıfır veya daha fazla işlenenden oluşur. Çoğu komut tek bir değere veya bir çift değere atıfta bulunur. İşlenenler anlık (komutun kendisinde kodlanan değer), komutta belirtilen veya ima edilen yazmaçlar veya depolama alanında başka bir yerde bulunan verilerin adresleri olabilir. Bu, altta yatan işlemci mimarisi tarafından belirlenir: assembler sadece bu mimarinin nasıl çalıştığını yansıtır. Genişletilmiş anımsatıcılar genellikle bir opcode ile belirli bir operandın kombinasyonunu belirtmek için kullanılır, örneğin System/360 assembler'ları B için genişletilmiş bir anımsatıcı olarak M.Ö. 15'lik bir maske ile ve NOP ("NO OPeration" - bir adım için hiçbir şey yapmayın) için M.Ö. 0'lık bir maske ile.

Genişletilmiş anımsatıcılar genellikle talimatların özel kullanımlarını desteklemek için kullanılır, genellikle talimat adından anlaşılmayan amaçlar için. Örneğin, birçok CPU'nun açık bir NOP talimatı yoktur, ancak bu amaç için kullanılabilecek talimatları vardır. 8086 CPU'larda talimat xchg ax,ax için kullanılır nopile nop talimatı kodlamak için bir sözde-opcode olmak xchg ax,ax. Bazı sökücüler bunu tanır ve xchg ax,ax olarak talimat nop. Benzer şekilde, System/360 ve System/370 için IBM assembler'ları genişletilmiş mnemonikleri kullanır NOP ve NOPR için M.Ö. ve BCR sıfır maskeli. SPARC mimarisi için bunlar sentetik komutlar olarak bilinir.

Bazı assembler'lar iki veya daha fazla makine komutu üreten basit yerleşik makro komutları da destekler. Örneğin, bazı Z80 assembler'larda komut ld hl,bc üretmek için kabul edilir ld l,c ardından ld h,b. Bunlar bazen sözde-opkodlar olarak da bilinir.

Anımsatıcılar keyfi sembollerdir; 1985 yılında IEEE, tüm assembler'lar tarafından kullanılacak tek tip bir anımsatıcı seti için Standart 694'ü yayınladı. Standart o zamandan beri geri çekilmiştir.

Veri direktifleri

Veri ve değişkenleri tutmak için veri öğelerini tanımlamak için kullanılan talimatlar vardır. Bunlar verinin türünü, uzunluğunu ve hizalanmasını tanımlar. Bu talimatlar ayrıca verilerin dış programlar (ayrı olarak birleştirilen programlar) tarafından mı yoksa yalnızca veri bölümünün tanımlandığı program tarafından mı kullanılabileceğini tanımlayabilir. Bazı assembler'lar bunları pseudo-ops olarak sınıflandırır.

Montaj direktifleri

Pseudo-opcodes, pseudo-operations veya pseudo-ops olarak da adlandırılan assembly direktifleri, bir assembler'a "assembling talimatları dışında işlemler yapması için verilen" komutlardır. Yönergeler assembler'ın nasıl çalıştığını etkiler ve "nesne kodunu, sembol tablosunu, listeleme dosyasını ve dahili assembler parametrelerinin değerlerini etkileyebilir". Bazen pseudo-opcode terimi, veri üretenler gibi nesne kodu üreten yönergeler için ayrılmıştır.

Pseudo-op'ların isimleri genellikle makine talimatlarından ayırt etmek için bir nokta ile başlar. Pseudo-op'lar programın montajını programcı tarafından girilen parametrelere bağımlı hale getirebilir, böylece bir program belki de farklı uygulamalar için farklı şekillerde monte edilebilir. Ya da bir pseudo-op, okunması ve bakımı daha kolay hale getirmek için bir programın sunumunu değiştirmek için kullanılabilir. Pseudo-op'ların bir başka yaygın kullanımı da çalışma zamanı verileri için depolama alanları ayırmak ve isteğe bağlı olarak içeriklerini bilinen değerlere başlatmaktır.

Sembolik assembler'lar programcıların bellek konumları ve çeşitli sabitlerle keyfi isimler (etiketler veya semboller) ilişkilendirmesine izin verir. Genellikle, her sabit ve değişkene bir isim verilir, böylece komutlar bu konumlara isimle referans verebilir, böylece kendi kendini belgeleyen kodu teşvik eder. Çalıştırılabilir kodda, her alt rutinin adı giriş noktasıyla ilişkilendirilir, böylece bir alt rutine yapılan tüm çağrılar onun adını kullanabilir. Alt programların içinde, GOTO hedeflerine etiketler verilir. Bazı assembler'lar genellikle normal sembollerden sözlüksel olarak farklı olan yerel sembolleri destekler (örneğin, GOTO hedefi olarak "10$" kullanımı).

NASM gibi bazı assembler'lar esnek sembol yönetimi sağlayarak programcıların farklı isim alanlarını yönetmesine, veri yapıları içindeki ofsetleri otomatik olarak hesaplamasına ve gerçek değerlere ya da assembler tarafından gerçekleştirilen basit hesaplamaların sonuçlarına atıfta bulunan etiketler atamasına izin verir. Etiketler ayrıca sabitleri ve değişkenleri yeniden konumlandırılabilir adreslerle başlatmak için de kullanılabilir.

Assembly dilleri, diğer bilgisayar dillerinin çoğunda olduğu gibi, program kaynak koduna montaj sırasında göz ardı edilecek yorumlar eklenmesine izin verir. Bir dizi ikili makine talimatının anlamını ve amacını belirlemek zor olabileceğinden, assembly dili programlarında akıllıca yorum yapmak çok önemlidir. Derleyiciler veya sökücüler tarafından oluşturulan "ham" (yorumlanmamış) assembly dilinin, değişiklik yapılması gerektiğinde okunması oldukça zordur.

Makrolar

Birçok assembler önceden tanımlanmış makroları destekler ve diğerleri değişkenlerin ve sabitlerin gömülü olduğu metin satırları dizilerini içeren programcı tanımlı (ve tekrar tekrar tanımlanabilir) makroları destekler. Makro tanımı genellikle assembler ifadelerinin, örneğin direktiflerin, sembolik makine talimatlarının ve assembler ifadeleri için şablonların bir karışımıdır. Bu metin satırları dizisi işlem kodları veya yönergeler içerebilir. Bir makro tanımlandıktan sonra adı bir anımsatıcı yerine kullanılabilir. Birleştirici böyle bir deyimi işlediğinde, deyimi bu makro ile ilişkili metin satırları ile değiştirir, ardından bunları kaynak kod dosyasında varmış gibi işler (bazı birleştiricilerde, değiştirme metninde mevcut olan herhangi bir makronun genişletilmesi dahil). Bu anlamda makrolar 1950'lerin IBM otomatik kodlayıcılarına kadar uzanır.

Makro birleştiriciler tipik olarak makroları tanımlamak, değişkenleri tanımlamak, değişkenleri bir aritmetik, mantıksal veya dize ifadesinin sonucuna ayarlamak, yinelemek, koşullu olarak kod oluşturmak gibi direktiflere sahiptir. Bu direktiflerden bazıları bir makro tanımı içinde kullanılmak üzere kısıtlanmış olabilir, örneğin HLASM'de MEXIT, diğerlerine ise açık kod içinde (makro tanımları dışında) izin verilebilir, örneğin HLASM'de AIF ve COPY.

Assembly dilinde "makro" terimi, #define yönergesinin tipik olarak kısa tek satırlık makrolar oluşturmak için kullanıldığı C programlama dilindeki ön işlemci gibi diğer bazı bağlamlarda olduğundan daha kapsamlı bir kavramı temsil eder. Assembler makro talimatları, PL/I ve diğer bazı dillerdeki makrolar gibi, montaj sırasında assembler tarafından yorumlanarak çalıştırılan kendi başlarına uzun "programlar" olabilir.

Makrolar 'kısa' isimlere sahip olabildiklerinden ancak birkaç veya hatta birçok kod satırına genişleyebildiklerinden, assembly dili programlarının çok daha kısa görünmesini sağlamak için kullanılabilir ve daha yüksek seviyeli dillerde olduğu gibi daha az kaynak kodu satırı gerektirir. Ayrıca assembly programlarına daha yüksek yapı seviyeleri eklemek, isteğe bağlı olarak parametreler ve diğer benzer özellikler aracılığıyla gömülü hata ayıklama kodu eklemek için de kullanılabilirler.

Makro birleştiriciler genellikle makroların parametre almasına izin verir. Bazı birleştiriciler, isteğe bağlı parametreler, sembolik değişkenler, koşullular, dize manipülasyonu ve aritmetik işlemler gibi üst düzey dil öğelerini içeren, tümü belirli bir makronun yürütülmesi sırasında kullanılabilen ve makroların bağlamı kaydetmesine veya bilgi alışverişine izin veren oldukça karmaşık makro dilleri içerir. Böylece bir makro, makro argümanlarına dayalı olarak çok sayıda assembly dili talimatı veya veri tanımı üretebilir. Bu, örneğin kayıt tarzı veri yapıları veya "unrolled" döngüler oluşturmak için kullanılabilir veya karmaşık parametrelere dayalı tüm algoritmaları oluşturabilir. Örneğin, bir "sort" makrosu karmaşık bir sıralama anahtarının belirtimini kabul edebilir ve belirtimi yorumlayan genel bir prosedür için gerekli olacak çalışma zamanı testlerine ihtiyaç duymadan bu belirli anahtar için hazırlanmış kod üretebilir. Böyle bir makro paketi kullanılarak yoğun bir şekilde genişletilmiş assembly dilini kullanan bir kuruluşun daha üst düzey bir dilde çalıştığı düşünülebilir çünkü bu tür programcılar bilgisayarın en alt düzey kavramsal öğeleriyle çalışmamaktadır. Bu noktanın altını çizmek gerekirse, makrolar SNOBOL4'te (1967) sanal bir makine için bir assembly dili olan SNOBOL Implementation Language (SIL) ile yazılmış erken bir sanal makineyi uygulamak için kullanılmıştır. Hedef makine bunu bir makro birleştirici kullanarak kendi yerel koduna çeviriyordu. Bu, o zaman için yüksek derecede taşınabilirlik sağladı.

Makrolar, anabilgisayar döneminde belirli müşteriler için büyük ölçekli yazılım sistemlerini özelleştirmek için kullanıldı ve ayrıca müşteri personeli tarafından üretici işletim sistemlerinin belirli sürümlerini yaparak işverenlerinin ihtiyaçlarını karşılamak için kullanıldı. Bu, örneğin IBM'in Conversational Monitor System / Virtual Machine (VM/CMS) ve IBM'in "gerçek zamanlı işlem işleme" eklentileri, Customer Information Control System CICS ve 1970'lerde başlayan ve bugün hala birçok büyük bilgisayar rezervasyon sistemini (CRS) ve kredi kartı sistemini çalıştıran havayolu/finans sistemi ACP/TPF ile çalışan sistem programcıları tarafından yapılmıştır.

Tamamen farklı dillerde yazılmış kod üretmek için bir assembler'ın yalnızca makro işleme yeteneklerini kullanmak da mümkündür; örneğin, assembler'a rastgele kod üretme talimatı veren montaj zamanı operatörleri içinde COBOL kodu satırları içeren saf bir makro assembler programı kullanarak COBOL'da bir programın bir versiyonunu üretmek. IBM OS/360 sistem üretimini gerçekleştirmek için makroları kullanır. Kullanıcı bir dizi assembler makrosu kodlayarak seçenekleri belirtir. Bu makroların bir araya getirilmesi, sistemi oluşturmak için iş kontrol dili ve yardımcı program kontrol deyimleri de dahil olmak üzere bir iş akışı oluşturur.

Bunun nedeni, 1960'larda fark edildiği gibi, "makro işleme" kavramının "montaj" kavramından bağımsız olması, birincisinin modern anlamda nesne kodu üretmekten çok kelime işleme, metin işleme olmasıdır. Makro işleme kavramı, değişkenleri ayarlamak ve değerleri üzerinde koşullu testler yapmak için "önişlemci talimatlarını" destekleyen C programlama dilinde ortaya çıkmıştır. Montajcıların içindeki önceki bazı makro işlemcilerin aksine, C ön işlemcisi Turing-tam değildir çünkü döngü ya da "go to" yeteneğinden yoksundur, ikincisi programların döngü yapmasına izin verir.

Makro işlemenin gücüne rağmen, birçok yüksek seviyeli dilde (başlıca istisnalar C, C++ ve PL/I'dir) kullanılmaz hale gelirken, assembler'lar için uzun ömürlü olmaya devam etmiştir.

Makro parametre ikamesi kesinlikle isme göredir: makro işleme zamanında, bir parametrenin değeri metinsel olarak ismi ile değiştirilir. Ortaya çıkan en ünlü hata sınıfı, makro yazarı bir isim beklerken basit bir isim değil, kendisi bir ifade olan bir parametrenin kullanılmasıydı. Makroda:

foo: makro a
a*b yükle 

Buradaki amaç, çağıranın bir değişken adı vermesi ve "global" değişken veya sabit b'nin "a "yı çarpmak için kullanılmasıydı. Eğer foo a-c parametresiyle çağrılırsa, a-c*b yüklemesinin makro açılımı gerçekleşir. Olası bir belirsizliği önlemek için, makro işlemcilerin kullanıcıları makro tanımları içindeki resmi parametreleri parantez içine alabilir veya çağıranlar giriş parametrelerini parantez içine alabilir.

Yapılandırılmış programlama desteği

Yürütme akışını kodlamak için yapılandırılmış programlama öğeleri sağlayan makro paketleri yazılmıştır. Bu yaklaşımın en eski örneği, ilk olarak Harlan Mills (Mart 1970) tarafından önerilen ve IBM'in Federal Sistemler Bölümü'nde Marvin Kessler tarafından uygulanan ve OS/360 assembler programları için IF/ELSE/ENDIF ve benzeri kontrol akışı blokları sağlayan Concept-14 makro setidir. Bu, assembly dilinde spagetti koduna neden olan ana faktörlerden biri olan assembly kodunda GOTO işlemlerinin kullanımını azaltmanın veya ortadan kaldırmanın bir yoluydu. Bu yaklaşım 1980'lerin başında (büyük ölçekli assembly dili kullanımının son günleri) yaygın olarak kabul gördü. IBM'in High Level Assembler Toolkit'i böyle bir makro paketi içermektedir.

İlginç bir tasarım da 8080/Z80 işlemciler için "akış odaklı" bir assembler olan A-natural'dı (Whitesmiths Ltd. (Unix benzeri Idris işletim sisteminin geliştiricileri ve ilk ticari C derleyicisi olduğu bildirilen) tarafından geliştirilmiştir. Dil, işlem kodları, kayıtlar ve bellek referansları gibi ham makine öğeleriyle çalıştığı için bir assembler olarak sınıflandırıldı; ancak yürütme sırasını belirtmek için bir ifade sözdizimi içeriyordu. Parantezler ve diğer özel semboller, blok odaklı yapısal programlama yapıları ile birlikte, üretilen talimatların sırasını kontrol ediyordu. A-natural, elle kodlama için değil, bir C derleyicisinin nesne dili olarak inşa edilmiştir, ancak mantıksal sözdizimi bazı hayranlar kazanmıştır.

Büyük ölçekli assembly dili geliştirmenin gerilemesinden bu yana daha sofistike assembler'lara çok az talep olmuştur. Buna rağmen, kaynak kısıtlamaları veya hedef sistemin mimarisindeki özelliklerin daha yüksek seviyeli dillerin etkin kullanımını engellediği durumlarda hala geliştirilmekte ve uygulanmaktadır.

Güçlü bir makro motoruna sahip derleyiciler, Masm32 paketi ile sağlanan switch makrosu gibi makrolar aracılığıyla yapılandırılmış programlamaya izin verir (bu kod tam bir programdır):

include \masm32\include\masm32rt.inc ; Masm32 kütüphanesini kullan <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Support for structured programming&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Assembly_language#Support_for_structured_programming <span style="color:#dddddd">ⓘ</span>]</span>

.code
demomain:
  TEKRAR 20
	switch rv(nrandom, 9) ; 0 ile 8 arasında bir sayı üretin
	mov ecx, 7
	durum 0
		print "case 0"
	case ecx ; diğer programlama dillerinin çoğunun aksine,
		print "case 7" ; Masm32 anahtarı "değişken durumlara" izin verir
	case 1 ... 3
		.if eax==1
			print "durum 1"
		.elseif eax==2
			print "durum 2"
		.else
			print "1'den 3'e kadar olan vakalar: diğer"
		.endif
	Vaka 4, 6, 8
		print "case 4, 6 veya 8"
	varsayılan
		mov ebx, 19 ; 20 yıldız yazdır
		.Tekrarla
			print "*"
			dec ebx
		.Until Sign? ; işaret bayrağı ayarlanana kadar döngü
	endsw
	print chr$(13, 10)
  ENDM
  ÇIKIŞ
demomain'i sonlandır

Assembly dilinin kullanımı

Tarihsel perspektif

Assembly dilleri, saklı program bilgisayarının tanıtıldığı dönemde mevcut değildi. Kathleen Booth, 1947 yılında Londra Üniversitesi Birkbeck'te ARC2 üzerinde çalışırken, Andrew Booth'un (daha sonra kocası) İleri Araştırmalar Enstitüsü'nde matematikçi John von Neumann ve fizikçi Herman Goldstine ile yaptığı danışmanlık sonrasında başladığı teorik çalışmalara dayanarak "assembly dilini icat etmekle tanınır".

1948'in sonlarında, Elektronik Gecikmeli Depolama Otomatik Hesap Makinesi (EDSAC), önyükleme programına entegre edilmiş bir birleştiriciye ("ilk siparişler" olarak adlandırılır) sahipti. IEEE Bilgisayar Topluluğu tarafından ilk "assembler "ın yaratıcısı olarak gösterilen David Wheeler tarafından geliştirilen tek harfli anımsatıcıları kullanıyordu. EDSAC ile ilgili raporlar, alanların bir komut sözcüğünde birleştirilmesi işlemi için "assembly" terimini tanıttı. SOAP (Symbolic Optimal Assembly Program) 1955 yılında Stan Poley tarafından IBM 650 bilgisayarı için yazılmış bir assembly diliydi.

Assembly dilleri, ilk bilgisayarlarda ihtiyaç duyulan hataya eğilimli, sıkıcı ve zaman alıcı birinci nesil programlamanın çoğunu ortadan kaldırarak programcıları sayısal kodları hatırlamak ve adresleri hesaplamak gibi zahmetlerden kurtarır. Bir zamanlar her tür programlama için yaygın olarak kullanılıyorlardı. Ancak 1950'lerin sonlarına gelindiğinde, programlama verimliliğinin artırılması arayışıyla kullanımları büyük ölçüde üst düzey dillerle ikame edilmiştir. Günümüzde assembly dili hala doğrudan donanım manipülasyonu, özel işlemci talimatlarına erişim veya kritik performans sorunlarını ele almak için kullanılmaktadır. Tipik kullanım alanları aygıt sürücüleri, düşük seviyeli gömülü sistemler ve gerçek zamanlı sistemlerdir (bkz. § Güncel kullanım).

Tarihsel olarak, çok sayıda program tamamen assembly dilinde yazılmıştır. Burroughs MCP (1961) bir işletim sisteminin tamamen assembly dilinde geliştirilmediği ilk bilgisayardır; bir Algol lehçesi olan Executive Systems Problem Oriented Language (ESPOL) ile yazılmıştır. Büyük şirketler tarafından yazılan IBM mainframe yazılımlarının büyük bir kısmı da dahil olmak üzere birçok ticari uygulama assembly dilinde yazılmıştır. COBOL, FORTRAN ve bazı PL/I yazılımları sonunda bu çalışmaların çoğunun yerini aldı, ancak bazı büyük kuruluşlar assembly dili uygulama altyapılarını 1990'lara kadar korudu.

İlk mikro bilgisayarların çoğu, çoğu işletim sistemi ve büyük uygulamalar da dahil olmak üzere elle kodlanmış assembly diline dayanıyordu. Bunun nedeni, bu sistemlerin ciddi kaynak kısıtlamalarına sahip olması, kendine özgü bellek ve ekran mimarileri dayatması ve sınırlı, hatalı sistem hizmetleri sunmasıydı. Belki de daha önemlisi, mikrobilgisayar kullanımına uygun birinci sınıf üst düzey dil derleyicilerinin olmamasıydı. Psikolojik bir faktör de rol oynamış olabilir: ilk nesil mikrobilgisayar programcıları hobici, "teller ve pense" tutumunu sürdürdü.

Daha ticari bir bağlamda, assembly dilini kullanmanın en büyük nedenleri minimum şişkinlik (boyut), minimum ek yük, daha yüksek hız ve güvenilirlikti.

Bu döneme ait büyük assembly dili programlarının tipik örnekleri IBM PC DOS işletim sistemleri, Turbo Pascal derleyicisi ve elektronik tablo programı Lotus 1-2-3 gibi ilk uygulamalardır. Assembly dili, oyun geliştirmesi ve programlaması oldukça zor bir konsol olan Sega Saturn'den en iyi performansı almak için kullanılmıştır. 1993 tarihli arcade oyunu NBA Jam de bir başka örnektir.

Assembly dili 1980'lerin ve 1990'ların birçok popüler ev bilgisayarı için (MSX, Sinclair ZX Spectrum, Commodore 64, Commodore Amiga ve Atari ST gibi) uzun zamandır birincil geliştirme dili olmuştur. Bunun nedeni büyük ölçüde, bu sistemlerdeki yorumlanmış BASIC lehçelerinin yetersiz yürütme hızı sunmasının yanı sıra bu sistemlerdeki mevcut donanımdan tam olarak yararlanmak için yetersiz olanaklar sunmasıydı. Hatta bazı sistemler son derece gelişmiş hata ayıklama ve makro olanaklarına sahip entegre bir geliştirme ortamına (IDE) sahiptir. Radio Shack TRS-80 ve halefleri için mevcut olan bazı derleyiciler, satır içi montaj kaynağını yüksek seviyeli program ifadeleriyle birleştirme yeteneğine sahipti. Derlemenin ardından, yerleşik bir assembler satır içi makine kodu üretti.

Güncel kullanım

Assembly dilinin yüksek seviyeli dillere göre kullanışlılığı ve performansı konusunda her zaman tartışmalar olmuştur.

Assembly dilinin önemli olduğu belirli niş kullanım alanları olsa da (aşağıya bakınız), optimizasyon için başka araçlar da vardır.

Temmuz 2017 itibariyle, TIOBE programlama dili popülerliği endeksi, assembly dilini örneğin Visual Basic'in önünde 11. sıraya yerleştirmiştir. Assembler hız optimizasyonu ya da boyut optimizasyonu için kullanılabilir. Hız optimizasyonu söz konusu olduğunda, modern optimizasyon derleyicilerinin, bulunabilecek karşı örneklere rağmen, yüksek seviyeli dilleri elle yazılmış assembly kadar hızlı çalışabilen kodlara dönüştürdüğü iddia edilmektedir. Modern işlemcilerin ve bellek alt sistemlerinin karmaşıklığı, assembly programcıları için olduğu kadar derleyiciler için de etkili optimizasyonu giderek zorlaştırmaktadır. Dahası, artan işlemci performansı, çoğu CPU'nun çoğu zaman boşta kaldığı ve önbellek kaçırmaları, G / Ç işlemleri ve sayfalama gibi öngörülebilir darboğazların neden olduğu gecikmeler anlamına gelmektedir. Bu durum, ham kod yürütme hızını birçok programcı için sorun olmaktan çıkarmıştır.

Geliştiricilerin assembly dilini kullanmayı tercih edebileceği bazı durumlar vardır:

  • Atari 2600, Commodore 64 ve grafik hesap makineleri gibi sınırlı üst düzey dil seçeneklerine sahip eski işlemcili sistemler için kod yazmak. 1970'lerin ve 1980'lerin bu bilgisayarları için programlar genellikle demoscene veya retrogaming alt kültürleri bağlamında yazılır.
  • Donanımla doğrudan etkileşime girmesi gereken kod, örneğin aygıt sürücüleri ve kesme işleyicileri.
  • Gömülü bir işlemci veya DSP'de, yüksek tekrarlı kesmeler, saniyede 1000 veya 10000 kez meydana gelen bir kesme gibi, kesme başına en kısa döngü sayısını gerektirir.
  • Derleyicide uygulanmayan işlemciye özel talimatları kullanması gereken programlar. Yaygın bir örnek, birçok şifreleme algoritmasının çekirdeğinde yer alan bitsel döndürme talimatının yanı sıra bir baytın paritesini veya bir toplamanın 4 bitlik carry'sini sorgulamaktır.
  • Yüksek seviyeli bir dille ilişkili çalışma zamanı bileşenlerine veya kütüphanelere başvurmadan çalışması gereken kompakt boyutta bağımsız bir yürütülebilir dosya gereklidir. Örnekler arasında telefonlar, otomobil yakıt ve ateşleme sistemleri, klima kontrol sistemleri, güvenlik sistemleri ve sensörler için donanım yazılımları yer almaktadır.
  • Assembly dilinin yüksek seviyeli bir dilde elde edilmesi zor optimizasyon fırsatları sağladığı, performansa duyarlı iç döngüler içeren programlar. Örneğin, BLAS veya ayrık kosinüs dönüşümü ile doğrusal cebir (örneğin x264'ten SIMD assembly sürümü).
  • C gibi üst düzey dillerdeki programlar için vektörleştirilmiş fonksiyonlar oluşturan programlar. Üst düzey dilde bu bazen doğrudan SIMD anımsatıcılarına eşlenen derleyici içsel fonksiyonları tarafından desteklenir, ancak yine de verilen vektör işlemcisine özgü bire bir assembly dönüşümü ile sonuçlanır.
  • Simülasyonlar, uçuş navigasyon sistemleri ve tıbbi ekipman gibi gerçek zamanlı programlar. Örneğin, bir fly-by-wire sisteminde, telemetri yorumlanmalı ve katı zaman kısıtlamaları içinde hareket edilmelidir. Bu tür sistemler, (bazı) yorumlanmış diller, otomatik çöp toplama, çağrı işlemleri veya önleyici çoklu görevler tarafından yaratılabilecek öngörülemeyen gecikme kaynaklarını ortadan kaldırmalıdır. Bununla birlikte, bazı üst düzey diller bu tür gecikmelere yol açabilecek çalışma zamanı bileşenleri ve işletim sistemi arayüzleri içerir. Bu tür sistemler için assembly veya daha düşük seviyeli dillerin seçilmesi, programcılara işlem detayları üzerinde daha fazla görünürlük ve kontrol sağlar.
  • Kriptografik algoritmalar, zamanlama saldırılarını önlemek için her zaman kesinlikle aynı sürede yürütülmelidir.
  • IBM ana bilgisayarları için yazılmış eski kodun değiştirilmesi ve genişletilmesi.
  • Hiçbir şeyin hafife alınamayacağı son derece yüksek güvenlikli durumlarda, ortam üzerinde tam kontrolün gerekli olduğu durumlar.
  • Bilgisayar virüsleri, önyükleyiciler, belirli aygıt sürücüleri veya donanıma ya da düşük seviyeli işletim sistemine çok yakın diğer öğeler.
  • Ek yükün minimumda tutulduğu izleme, takip ve hata ayıklama için komut seti simülatörleri.
  • Çapraz derleyicinin bulunmadığı yeni veya özel bir işlemci üzerinde yüksek seviyeli bir dilin bulunmadığı durumlar.
  • Tersine mühendislik ve aşağıdaki gibi program dosyalarının değiştirilmesi:
    • Orijinal olarak yüksek seviyeli bir dilde yazılmış olabilecek veya olmayabilecek mevcut ikili dosyalar, örneğin kaynak kodu mevcut olmayan veya kaybolmuş programları yeniden oluşturmaya çalışırken veya tescilli yazılımın kopya korumasını kırarken.
    • Video oyunları (ROM hackleme olarak da adlandırılır), çeşitli yöntemlerle mümkündür. En yaygın kullanılan yöntem assembly dili seviyesinde program kodunu değiştirmektir.

Assembly dili halen çoğu bilgisayar bilimi ve elektronik mühendisliği programında öğretilmektedir. Günümüzde çok az programcı düzenli olarak assembly dilini bir araç olarak kullansa da, temel kavramlar önemini korumaktadır. İkili aritmetik, bellek ayırma, yığın işleme, karakter kümesi kodlama, kesme işleme ve derleyici tasarımı gibi temel konuları, bir bilgisayarın donanım düzeyinde nasıl çalıştığını kavramadan ayrıntılı olarak incelemek zor olacaktır. Bir bilgisayarın davranışı temelde komut seti tarafından tanımlandığından, bu tür kavramları öğrenmenin mantıklı yolu bir assembly dilini çalışmaktır. Modern bilgisayarların çoğu benzer komut setlerine sahiptir. Bu nedenle, tek bir assembly dilini çalışmak öğrenmek için yeterlidir: I) temel kavramlar; II) assembly dilinin kullanımının uygun olabileceği durumları tanımak; ve III) yüksek seviyeli dillerden ne kadar verimli çalıştırılabilir kod oluşturulabileceğini görmek.

Tipik uygulamalar

  • Assembly dili tipik olarak bir sistemin önyükleme kodunda, işletim sistemini başlatmadan önce sistem donanımını başlatan ve test eden ve genellikle ROM'da saklanan düşük seviyeli kodda kullanılır. (IBM uyumlu PC sistemlerindeki BIOS ve CP/M buna bir örnektir).
  • Assembly dili genellikle düşük seviyeli kodlar için, örneğin önceden var olan sistem çağrılarının kullanılabilirliğine güvenemeyen ve bunları sistemin üzerinde çalışacağı belirli işlemci mimarisi için gerçekten uygulaması gereken işletim sistemi çekirdekleri için kullanılır.
  • Bazı derleyiciler yüksek seviyeli dilleri tam olarak derlemeden önce assembly'ye çevirerek assembly kodunun hata ayıklama ve optimizasyon amacıyla görüntülenmesini sağlar.
  • Pascal veya C gibi nispeten düşük seviyeli diller için bazı derleyiciler, programcının assembly dilini doğrudan kaynak kodun içine yerleştirmesine izin verir (satır içi assembly olarak adlandırılır). Bu tür olanakları kullanan programlar daha sonra her donanım platformunda farklı montaj dili kullanarak soyutlamalar oluşturabilir. Sistemin taşınabilir kodu daha sonra bu işlemciye özgü bileşenleri tek tip bir arayüz aracılığıyla kullanabilir.
  • Assembly dili tersine mühendislikte kullanışlıdır. Birçok program yalnızca makine kodu biçiminde dağıtılır; bu kodların bir sökücü tarafından assembly diline çevrilmesi kolaydır, ancak bir derleyici aracılığıyla daha üst düzey bir dile çevrilmesi daha zordur. Interactive Disassembler gibi araçlar böyle bir amaç için demontajdan geniş ölçüde yararlanır. Bu teknik, bilgisayar korsanları tarafından ticari yazılımları kırmak için ve rakip şirketler tarafından benzer sonuçlara sahip yazılımlar üretmek için kullanılır.
  • Assembly dili, özellikle sınırlı işlem gücü ve RAM'e sahip ilk kişisel bilgisayarlarda yürütme hızını artırmak için kullanılır.
  • Assembler'lar, diğer kodlar tarafından kullanılmak üzere biçimlendirilmiş ve yorumlanmış kaynak koddan üst düzey dil ek yükü olmadan veri blokları üretmek için kullanılabilir.

Temel kavramlar

Çevirici (assembler)

Tipik olarak bir modern çevirici assembly (çeviri) komut “mnemonic”leri işlem kodlarına çevirerek (tercüme ederek), ve hafıza mahalleri (memory locations) ve diğer varlıklar için sembolik isimler belirleyerek “object code” unu oluşturur. Sembolik referansların kullanılması, program modifikasyonlarından sonra bıktırıcı hesaplamaları ve elle yapılan adres güncelleştirmelerini kaydettiğinden çeviricilerin en önemli (kilit) özelliğidir. Çeviricilerin çoğu 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 imkânları da içerirler.

Çeviriciler genellikle yüksek seviyeli dilleri yazma konusunda derleyicilerden (compilers) daha basittir, ve 1950’li yıllardan beri kullanılmaktadır. (Bilgisayarların ilk günlerindeki ilk çeviriciler yorgun programcıların bir jenerasyonu için önemli bir keşifti.) Modern çeviriciler, bilhassa MIPS, Sun SPARC ve HP PA-RISC gibi RISC’e dayalı mimariler CPU “pipeline” verimliliğini sağlamaya yönelik komutu (instruction) optimize ederler.

Daha sofistike (karmaşık) olan Yüksek Seviyeli çeviriciler aşağıda belirtilenler gibi dil özetlerini (abstractions) sağlarlar:

  • Yüksek kontrol yapıları
  • Yüksek seviyeli prosedür fonksiyon deklarasyonları ve talepleri
  • Yapılar/kayıtlar, birlikler, sınıflar ve takımlar dahil yüksek seviyeli özet veri türleri
  • Sofistike makro işleme

Daha fazla bilgi için aşağıdaki Dil tasarımına bakınız.

Normal profesyonel kullanımda çevirici teriminin sıklıkla farklı anlamlarda kullanıldığına dikkatinizi çekeriz; sıklıkla çevirici yararından ziyade bir çeviri dilinin kendisine atfen kullanılır. Böylece “ASM-H çok kullanılan bir S/370 çevirici olmuştur” ifadesine karşı “CP/CMS S/360 çeviricide yazılmıştır” ifadesi kullanılır.