Bellek bozulması, assembly dilinde yazılmış büyük programlarda yaygın bir sorun muydu?

Jan 21 2021

Bellek bozulması hataları, büyük C programlarında ve projelerinde her zaman yaygın bir sorun olmuştur. O zamanlar 4.3BSD'de bir problemdi ve bugün hala bir problem. Program ne kadar dikkatli yazılırsa yazılsın, yeterince büyükse, kodda başka bir sınır dışı okuma veya yazma hatası bulmak çoğu zaman mümkündür.

Ancak, C'nin değil, işletim sistemleri de dahil olmak üzere büyük programların derlemede yazıldığı zamanlar vardı. Bellek bozulması, büyük derleme programlarında yaygın bir sorun muydu? Ve C programlarına kıyasla nasıldı?

Yanıtlar

53 Jean-FrançoisFabre Jan 21 2021 at 17:23

Montajda kodlama acımasızdır.

Sahte işaretçiler

Assembly dilleri daha çok işaretçilere (adres kayıtları aracılığıyla) güvenir, bu nedenle C'nin aksine bu tür bellek bozulmaları / arabellek taşmaları konusunda sizi uyarmak için derleyiciye veya statik analiz araçlarına bile güvenemezsiniz.

Örneğin C'de, iyi bir derleyici orada bir uyarı verebilir:

 char x[10];
 x[20] = 'c';

Bu sınırlıdır. Dizi bir işaretçiye dönüştüğü anda, bu tür kontroller gerçekleştirilemez, ancak bu bir başlangıçtır.

Montajda, uygun çalışma zamanı veya resmi yürütme ikili araçları olmadan bu tür hataları tespit edemezsiniz.

Sahte (çoğunlukla adres) kayıtları

Montaj için bir başka ağırlaştırıcı faktör, kayıt koruma ve rutin arama kurallarının standart / garantili olmamasıdır.

Bir rutin çağrılırsa ve belirli bir kaydı yanlışlıkla kaydetmezse, arayan kişiye değiştirilmiş bir kayıtla geri döner (çıkışta çöpe atıldığı bilinen "sıfırdan" kayıtların yanında) ve arayan kişi beklemiyor yanlış adrese okumaya / yazmaya yol açar. Örneğin 68k kodunda:

    move.b  d0,(a3)+
    bsr  a_routine
    move.b  d0,(a3)+   ; memory corruption, a3 has changed unexpectedly
    ...

a_routine:
    movem.l a0-a2,-(a7)
    ; do stuff
    lea some_table(pc),a3    ; change a3 if some condition is met
    movem.l (a7)+,a0-a2   ; the routine forgot to save a3 !
    rts

Aynı kayıt kaydetme kurallarını kullanmayan bir başkası tarafından yazılmış bir rutin kullanmak da aynı soruna yol açabilir. Başkasının rutinini kullanmadan önce genellikle tüm kayıtları kaydederim.

Öte yandan, bir derleyici yığın veya standart kayıt parametresi geçişini kullanır, yığın / diğer aygıtı kullanarak yerel değişkenleri işler, gerekirse kayıtları korur ve derleyici tarafından garanti edilen tüm programda tutarlıdır (hatalar yoksa, kurs)

Sahte adresleme modları

Eski Amiga oyunlarındaki birçok hafıza ihlalini düzelttim. Bunları MMU etkinleştirilmiş bir sanal ortamda çalıştırmak bazen tam sahte adreslerde okuma / yazma hatalarını tetikler. Çoğu zaman bu okuma / yazma işlemlerinin hiçbir etkisi yoktur çünkü okumalar 0 döndürür ve yazmalar ormana gider, ancak bellek yapılandırmasına bağlı olarak kötü sonuçlar doğurabilir.

Hataların ele alındığı durumlar da vardı. Şunun gibi şeyler gördüm:

 move.l $40000,a0

hemen yerine

 move.l #$40000,a0

bu durumda, adres kaydı $40000, $40000adresi değil, içinde olanı (muhtemelen çöp kutusu) içerir . Bu, bazı durumlarda yıkıcı bellek bozulmasına yol açar. Oyun genellikle bunu düzeltmeden başka bir yerde işe yaramayan eylemi yapar, böylece oyun çoğu zaman düzgün çalışır. Ancak, uygun davranışı geri yüklemek için oyunların düzgün bir şekilde düzeltilmesi gereken zamanlar vardır.

C'de, bir işaretçi için bir değeri yanıltmak bir uyarıya yol açar.

(Seviyeleri geçme şeklinize ve sıralarına bağlı olarak gittikçe daha fazla grafik bozulması olan "Wicked" gibi bir oyundan vazgeçtik ...)

Sahte veri boyutları

Montajda tip yoktur. Bu demektir ki yaparsam

move.w #$4000,d0           ; copy only 16 bits
move.l #1,(a0,d0.l)    ; indexed write on d1, long

d0kayıt sadece değiştirilen verilerin yarısını alır. İstediğim şey olabilir, belki de değil. Daha sonra d0, en önemli 32-16 bit üzerinde sıfır içeriyorsa, kod bekleneni yapar, aksi halde ekler a0ve d0(tam aralık) ve sonuçta ortaya çıkan yazma "ormanda" olur. Bir düzeltme şudur:

move.l #1,(a0,d0.w)    ; indexed write on d1, long

Ama eğer d0> $7FFFo da yanlış bir şey yapar, çünkü o zaman olumsuzd0 olarak kabul edilir (durum böyle değil ). Yani işaret genişletme veya maskeleme gerekiyor ...d0.ld0

Bu boyut hataları, örneğin bir shortdeğişkene atarken (sonucu kısaltır) bir C kodunda görülebilir, ancak o zaman bile, yukarıdaki gibi ölümcül sorunları değil, çoğu zaman yanlış bir sonuç alırsınız (yani: 't yalan yanlış türde yayınları zorlayarak derleyiciye)

Birleştiricilerin türü yoktur, ancak iyi derleyiciler, STRUCTyapı ofsetlerini otomatik olarak hesaplayarak kodu biraz yükseltmeye izin veren yapıların ( anahtar sözcük) kullanılmasına izin verir. Ancak, yapıları / tanımlı uzaklıkları kullansanız da kullanmasanız da kötü boyutta okuma felaket olabilir

move.w  the_offset(a0),d0

onun yerine

move.l  the_offset(a0),d0

işaretlenmez ve size yanlış veri verir d0. Kod yazarken yeterince kahve içtiğinizden emin olun veya bunun yerine sadece belgeler yazın ...

Sahte veri hizalaması

Birleştirici genellikle hizalanmamış kod hakkında uyarır, ancak hizalanmamış işaretçilerde (çünkü işaretçilerin tipi yoktur), bu veri yolu hatalarını tetikleyebilir.

Yüksek seviyeli diller türleri kullanır ve hizalama / doldurma gerçekleştirerek bu hataların çoğunu önler (bir kez daha yalan söylenmedikçe).

Ancak assembly programlarını başarıyla yazabilirsiniz. Parametre geçirme / kayıt kaydetme için katı bir metodoloji kullanarak ve kodunuzun% 100'ünü testlerle ve bir hata ayıklayıcıyla (sembolik olsun ya da olmasın, bu hala yazdığınız koddur) kapsamaya çalışarak. Bu, özellikle yanlış giriş verilerinin neden olduğu tüm olası hataları ortadan kaldırmayacak, ancak yardımcı olacaktır.

24 jackbochsler Jan 22 2021 at 05:41

Kariyerimin çoğunu assembler, solo, küçük ekipler ve büyük ekipler (Cray, SGI, Sun, Oracle) yazarak geçirdim. Gömülü sistemler, işletim sistemleri, sanal makineler ve önyükleme yükleyicileri üzerinde çalıştım. Bellek bozulması nadiren bir sorundur. Zeki insanları işe aldık ve başarısız olanlar becerilerine daha uygun farklı işlerde idare edildi.

Ayrıca hem ünite düzeyinde hem de sistem düzeyinde fanatik olarak test ettik. Hem simülatörler hem de gerçek donanım üzerinde sürekli çalışan otomatik testler yaptık.

Kariyerimin sonuna doğru bir şirketle görüştüm ve otomatik testlerini nasıl yaptıklarını sordum. "Ne?!?" duymam gereken tek şeydi, görüşmeyi bitirdim.

19 RETRAC Jan 21 2021 at 23:10

Ne kadar dikkatli olursanız olun, montajda çok sayıda basit aptalca hatalar vardır. Zayıf tanımlanmış yüksek seviyeli diller için (C gibi) aptal derleyiciler bile anlamsal veya sözdizimsel olarak geçersiz olan çok çeşitli olası hataları kısıtlıyor. Tek bir fazladan veya unutulmuş tuş vuruşuyla yapılan bir hata, derlemeyi reddetmekten çok daha olasıdır. Montajda geçerli bir şekilde ifade edebileceğiniz yapılar , herhangi bir anlam ifade etmiyor çünkü tamamen yanlış yapıyorsanız, geçerli C olarak kabul edilen bir şeye dönüşme olasılığınız daha düşüktür. gözlerini kısarak "ha" demesi daha olası. ve az önce yazdığınız canavarı yeniden yazın.

Dolayısıyla, montaj geliştirme ve hata ayıklama gerçekten de acı verici bir şekilde affetmez. Ancak bu tür hataların çoğu işleri zorlaştırır ve geliştirme ve hata ayıklamada ortaya çıkar. Eğitimli tahmininizi, eğer geliştiriciler aynı temel mimariyi ve aynı iyi geliştirme uygulamalarını takip ediyorlarsa, nihai ürünün yaklaşık olarak sağlam olması gerektiği konusunda tehlikeye atarım. Bir derleyici yakalar iyi bir gelişme uygulamalarıyla takılabilir hataların sıralayabilir ve hatalar derleyici tür yok yakalamak veya bu tür uygulamalarla yakalanmış olabilir veya olmayabilir. Yine de aynı seviyeye ulaşmak çok daha uzun sürecek.

14 WalterMitty Jan 23 2021 at 02:48

Lisp benzeri bir dil olan MDL için orijinal çöp toplayıcıyı 1971-72'de yazdım. O zamanlar benim için oldukça zordu. ITS çalıştıran PDP-10 için bir derleyici olan MIDAS'ta yazılmıştır.

Bu projedeki oyunun adı bellek bozulmasından kaçınmaktı. Tüm ekip, çöp toplayıcı çalıştırıldığında başarılı bir demo çökmesi ve yanmasından korktu. Ve bu kod için gerçekten iyi bir hata ayıklama planım yoktu. Daha önce veya o zamandan beri yaptığımdan daha fazla masa kontrolü yaptım. Çit direği hatası olmadığından emin olmak gibi şeyler. Bir grup vektör hareket ettirildiğinde, hedefin çöp olmayan herhangi bir şey içermediğinden emin olmak. Tekrar tekrar varsayımlarımı test ediyorum.

Bu kodda, masa başı kontrolünde bulunanlar dışında hiçbir zaman hata bulamadım. Canlı yayına girdikten sonra, saatimde hiçbiri ortaya çıkmadı.

Elli yıl önceki kadar akıllı değilim. Bugün böyle bir şey yapamam. Ve bugünün sistemleri MDL'den binlerce kat daha büyük.

7 Raffzahn Jan 22 2021 at 00:00

Bellek bozulması hataları, büyük C programlarında her zaman yaygın bir sorun olmuştur [...] Ancak, C'nin değil, işletim sistemleri de dahil olmak üzere büyük programların derlemede yazıldığı zamanlar vardı.

Başlarda oldukça yaygın olan başka dillerin de olduğunu biliyor muydunuz? COBOL, FORTRAN veya PL / 1 gibi mi?

Bellek bozulması hataları, büyük montaj programlarında yaygın bir sorun muydu?

Bu elbette birçok faktöre bağlıdır, örneğin

  • Assembler, farklı assembler programları farklı seviyelerde programlama desteği sunduğundan kullanılır.
  • özellikle büyük programlar kontrol edilebilir yapıya bağlı olduğundan program yapısı
  • modülerleştirme ve açık arayüzler
  • Yazılan program türü, çünkü her görev işaretçi ile oynamayı gerektirmez
  • en iyi uygulama stili

İyi bir derleyici yalnızca verilerin hizalandığından emin olmakla kalmaz, aynı zamanda karmaşık veri türlerini, yapıları ve benzerlerini soyut bir şekilde işlemek için araçlar sunarak işaretçileri 'manuel olarak' hesaplama ihtiyacını azaltır.

Herhangi bir ciddi proje için kullanılan bir birleştirici, her zaman olduğu gibi bir makro derleyicidir (* 1), bu nedenle, ilkel işlemleri daha yüksek seviyeli makro talimatlara sığdırabilir, daha uygulama merkezli bir programlama sağlarken işaretçi işlemenin birçok tuzağından kaçınır (* 2).

Program türleri de oldukça etkilidir. Uygulamalar genellikle çeşitli modüllerden oluşur ve bunların çoğu, işaretçi kullanımı olmadan (veya yalnızca kontrollü) neredeyse veya eksiksiz olarak yazılabilir. Yine, derleyici tarafından sağlanan araçların kullanımı daha az hatalı kod için anahtardır.

Bir sonraki, en iyi uygulama olacaktır - bu, öncekilerin çoğu ile el ele gider. Basitçe, adanmış istek yapıları yerine büyük bellek parçalarını aktaran, çoklu taban yazmaçlara ihtiyaç duyan programları / modülleri yazmayın.

Ancak en iyi uygulama zaten erken yaşlarda ve görünüşte basit şeylerle başlar. 6502 gibi, performans için sayfa sınırlarına göre ayarlanmış bir dizi tabloya sahip ilkel (üzgünüm) bir CPU örneğini ele alalım. Bu tablolardan birinin adresini indekslenmiş erişim için sıfır sayfa işaretçisine yüklerken, derleyicinin gitmek istediği araçların kullanımı

     LDA   #<Table
     STA   Pointer

Gördüğüm epeyce bazı programlar gitmeyi tercih ediyor

     LDA   #0
     STA   Pointer

(veya daha kötüsü, 65C02'de ise)

     STZ   Pointer

Genel argümantasyon "Ama yine de hizalı" dır. Bu mu? Bu, gelecekteki tüm yinelemeler için garanti edilebilir mi? Adres alanının daraldığı ve hizalanmamış adreslere taşınmaları gereken bir güne ne dersiniz? Beklenecek çok sayıda harika (diğer bir deyişle bulması zor) hatalar.

Bu yüzden En iyi uygulama, bizi tekrar Assembler'ı ve sunduğu tüm araçları kullanmaya geri getiriyor.

Assembler yerine Assembler oynamaya çalışmayın - bırakın işini sizin için yapsın.

Ve sonra, tüm diller için geçerli olan ancak çoğu zaman unutulan bir çalışma zamanı var. Parametrelerde yığın denetimi veya sınır denetimi gibi şeylerin yanı sıra, işaretçi hatalarını yakalamanın en etkili yollarından biri, ilk ve son bellek sayfasını yazma ve okumaya karşı kilitlemektir (* 3). Sadece tüm sevilen boş işaretçi hatasını yakalamakla kalmaz, aynı zamanda tüm düşük pozitif veya negatif sayıları da yakalar ve bunlar genellikle daha önceki bazı indekslemelerin yanlış gitmesinin bir sonucudur. Elbette, Runtime her zaman son çare, ancak bu kolay bir seçenek.

Her şeyden önce, belki de en alakalı neden

  • makinenin ISA'sı

işaretçilerle başa çıkma ihtiyacını azaltarak bellek bozulması olasılığını azaltmada.

Bazı CPU yapıları, diğerlerinden daha az (doğrudan) işaretçi işlemi gerektirir. Akümülatör tabanlı yükleme / depolama mimarileri gibi, bellekten belleğe işlemlerini içeren mimariler ile olmayanlar arasında büyük bir boşluk vardır. Doğası gereği, tek bir öğeden (bayt / kelime) daha büyük herhangi bir şey için işaretçi işlemeyi gerektirir.

Örneğin, bir alanı aktarmak için, hafızadaki bir müşteri adı diyelim, a / 360, veri tanımından derleyici tarafından oluşturulan adresler ve aktarım uzunluğu ile tek bir MVC işlemi kullanırken, her bir baytı işlemek için tasarlanmış bir yükleme / depolama mimarisi ayrı, yazmacılarda işaretçiler ve uzunluk kurmalı ve hareketli tek bir eleman etrafında döngü oluşturmalıdır.

Bu tür işlemler oldukça yaygın olduğu için, ortaya çıkan hata potansiyeli de yaygındır. Veya daha genel bir şekilde şöyle söylenebilir:

CISC işlemcileri için programlar genellikle hatalara RISC makineleri için yazılanlara göre daha az eğilimlidir.

Elbette ve her zamanki gibi, kötü programlama her şeyi alt üst edebilir.

Ve C programlarına kıyasla nasıldı?

Hemen hemen aynı - veya daha iyisi, C, en ilkel CPU ISA'nın HLL eşdeğeridir, bu nedenle daha yüksek seviyeli talimatlar sunan herhangi bir şey daha iyi olacaktır.

C doğası gereği bir RISCy dilidir. Sağlanan işlemler minimuma indirilir ve bu, istenmeyen işlemlere karşı minimum kontrol yeteneği ile gider. Denetlenmemiş işaretçilerin kullanılması yalnızca standart olmakla kalmaz, aynı zamanda birçok işlem için gereklidir ve bellek bozulması için birçok olasılık açar.

Aksine, ADA gibi bir HLL'yi ele alalım, burada işaretçi hasarı yaratmak neredeyse imkansızdır - amaçlanmadıkça ve açık bir seçenek olarak belirtilmedikçe. Bunun iyi bir kısmı (önceki ISA'da olduğu gibi) daha yüksek veri türleri ve bunların tip güvenli bir şekilde işlenmesidir.


Deneyim kısmı için, profesyonel hayatımın çoğunu (> 30 yıl) Montaj projelerinde,% 80 Mainframe (/ 370)% 20 Micros (çoğunlukla 8080 / x86) - artı özel çok daha fazlası ile yaptım :) Mainframe programlama kapsamındaki projeler 2+ milyon LOC (yalnızca talimatlar) kadar büyük, mikro projeler ise 10-20.000 LOC civarında tutuyor.


* 1 - Hayır, metin bölümlerini önceden hazırlanmış metinle değiştirmeyi öneren bir şey, en iyi ihtimalle bir metin ön işlemcisidir, ancak bir makro derleyici değildir. Bir makro derleyici, bir proje için gereken dili oluşturmak için bir meta araçtır. Derleyicinin kaynak hakkında topladığı bilgilere (alan boyutu, alan türü ve daha fazlası) ve uygun kodu oluşturmak için kullanılan işleme formüle etmek için kontrol yapılarına dokunmak için araçlar sunar.

* 2 - C'nin herhangi bir ciddi makro yeteneklere uygun olmadığına inanmak kolaydır, sadece birçok belirsiz yapıya olan ihtiyacı ortadan kaldırmakla kalmaz, aynı zamanda yeni bir dil yazmaya gerek kalmadan dili genişleterek çok fazla ilerlemeyi mümkün kılar.

* 3 - Şahsen ben 0 sayfasını sadece yazma korumalı yapmayı ve ilk 256 baytı ikili sıfır ile doldurmayı tercih ediyorum. Bu şekilde, tüm boş (veya düşük) işaretçi yazmaları yine de bir makine hatasıyla sonuçlanır, ancak boş göstericiden okuma, türe bağlı olarak, sıfır içeren bir bayt / yarım kelime / kelime / çift-kuyu veya bir boş dizge döndürür :) Biliyorum, tembel, ama kolaysa, diğer insanların kodlarını uyumsuz hale getirmek hayatı çok daha iyi hale getirir. Ayrıca kalan sayfa, çeşitli küresel kaynaklara işaretçiler, kimlik dizeleri, sabit alan içeriği ve çevirme tabloları gibi kullanışlı sabit değerler için kullanılabilir.

6 waltinator Jan 22 2021 at 09:17

CDC G-21, Univac 1108, DECSystem-10, DECSystem-20, tüm 36 bit sistemler ve 2 IBM 1401 derleyicisine montajda işletim sistemi modları yazdım.

"Bellek bozulması", çoğunlukla "Yapılmayacak Şeyler" listesinde bir giriş olarak vardı.

Bir Univac 1108'de, bir donanım kesintisinden sonraki ilk yarım kelimeli getirmenin (kesme işleyici adresi), adresin içeriği yerine tüm 1'leri döndürdüğü bir donanım hatası buldum. Yabani otların içine, kesintiler devre dışı, hafıza koruması yok. Dönüp durur, kimsenin bilmediği yerde durur.

5 Peter-ReinstateMonica Jan 22 2021 at 19:31

Elmaları ve armutları karşılaştırıyorsunuz. Programlar, assembler ile yönetilemez bir boyuta ulaştığı için yüksek seviyeli diller icat edildi. Örnek: "V1, çekirdeği, başlatması ve kabuğu için 4,501 satırlık derleme koduna sahipti. Bunlardan 3,976'sı çekirdek için ve 374'ü kabuk için." ( Bu cevaptan .)

. V1. Kabuk. Vardı. 347. Satırlar. Nın-nin. Kod.

Bugünkü bash, readline ve localization gibi merkezi kütüphaneleri saymayan, belki 100.000 satır koda sahiptir (repo üzerinde bir wc 170k verir). Yüksek seviyeli diller kısmen taşınabilirlik için kullanımdadır, ancak aynı zamanda montajcıda bugünün boyutunda programlar yazmanın neredeyse imkansız olması nedeniyle de kullanılmaktadır. Bu sadece hataya daha yatkın değil - neredeyse imkansız.

4 supercat Jan 22 2021 at 03:45

Bellek bozulmasının, benzer görevleri gerçekleştiren programları karşılaştırırken denetlenmemiş dizi abonelik işlemlerini kullanan diğer dillerden daha genel olarak assembly dilinde bir sorun olduğunu düşünmüyorum. Doğru birleştirme kodu yazarken, C gibi bir dilde ilgili olabilecek ayrıntıların ötesinde ayrıntılara dikkat etmek gerekebilir, montaj dilinin bazı yönleri aslında C'den daha güvenlidir. Assembly dilinde, kod bir dizi yükleme ve depolama gerçekleştirirse, bir derleyici tümünün gerekli olup olmadığını sorgulamadan verilen sırayla yükleme ve depolama talimatları üretin. C'de, aksine, clang gibi akıllı bir derleyici, aşağıdakilerden başka herhangi bir optimizasyon ayarıyla çağrılırsa -O0ve buna benzer bir şey verilirse:

extern char x[],y[];
int test(int index)
{
    y[0] = 1;
    if (x+2 == y+index)
        y[index] = 2;
    return y[0];
}

bunun o değerini belirleyebilir y[0]zaman returndeyimi yürütür her zaman 1 olacak ve yazdıktan sonra değerini yeniden yüklemeniz gerekmez böylece orada y[index]eğer endeks yazma olacağını oluşabilir sadece tanımlanmış durum bile, x[]iki bayt, y[]olur hemen takip etmek ve indexsıfırdır, bu y[0]da aslında 2 sayısını tuttuğunu ima eder .

3 phyrfox Jan 23 2021 at 23:33

Assembler, kullandığınız donanım hakkında C veya Java gibi diğer dillerden daha fazla bilgi gerektirir. Gerçek şu ki, assembler ilk bilgisayarlı arabalardan, erken video oyun sistemlerinden 1990'lara, bugün kullandığımız Nesnelerin İnterneti cihazlarına kadar hemen hemen her şeyde kullanılıyor.

C tip güvenliği sunarken, yine de geçersiz işaretçi kontrolü veya sınırlı diziler (en azından ekstra kod olmadan) gibi başka güvenlik önlemleri sunmuyordu. Herhangi bir assembler programı kadar çökecek ve yanacak bir program yazmak oldukça kolaydı.

Assembler'da onbinlerce video oyunu yazıldı, onlarca yıldır sadece birkaç kilobaytlık kod / veri ile küçük ama etkileyici demolar yazmak için besteler yapıldı , binlerce araba bugün hala bir çeşit assembler kullanıyor ve daha az bilinen birkaçı işletim sistemleri (örn. MenuetOS ). Evinizde, assembler'da programlanmış, bilmediğiniz düzinelerce hatta yüzlerce şey olabilir.

Assembly programlamayla ilgili temel sorun, C gibi bir dilde olduğundan daha güçlü bir şekilde planlama yapmanız gerektiğidir. Assembler'da tek bir hata olmadan 100 bin satırlık kod içeren bir program yazmak mükemmel bir şekilde mümkündür ve ayrıca bir program yazmak da mümkündür 5 bug içeren 20 satır kodlu program.

Sorun araç değil, programcı. Bellek bozulmasının genel olarak erken programlamada yaygın bir sorun olduğunu söyleyebilirim. Bu, assembler ile sınırlı değildi, aynı zamanda C (bellek sızıntısı ve geçersiz bellek aralıklarına erişim ile ün salmıştı), C ++ ve belleğe doğrudan erişebileceğiniz diğer diller, hatta BASIC (belirli I / CPU'daki O bağlantı noktaları).

Güvenli korumalara sahip modern dillerde bile, oyunları çökerten programlama hatalarını göreceğiz. Neden? Çünkü uygulamayı tasarlarken yeterince özen gösterilmiyor. Bellek yönetimi ortadan kalkmadı, görselleştirmenin daha zor olduğu bir köşeye sıkıştırıldı ve modern kodda her türlü rastgele tahribata neden oldu.

Neredeyse her dil, yanlış kullanıldığında çeşitli bellek bozulmalarına karşı hassastır. Günümüzde en yaygın sorun, kapanmalar ve soyutlamalar nedeniyle yanlışlıkla ortaya çıkması her zamankinden daha kolay olan bellek sızıntılarıdır.

Assembler'ın doğası gereği diğer dillerden daha fazla veya daha az bellek bozucu olduğunu söylemek haksızlıktır, sadece doğru kod yazmanın ne kadar zor olduğu için kötü bir üne kavuşmuştur.

2 JohnDoty Jan 23 2021 at 02:12

Bu çok yaygın bir sorundu. IBM'in 1130 için FORTRAN derleyicisinde epeyce vardı: Hatırladığım kadarıyla algılanamayan yanlış sözdizimi vakaları vardı. Makineye yakın daha yüksek seviyeli dillere geçmek açıkça yardımcı olmadı: PL / I ile yazılan erken Multics sistemleri sık sık çöktü. Bence programlama kültürü ve tekniğinin bu durumu düzeltmekle dilden daha fazla ilgisi var.

2 JohnDallman Jan 24 2021 at 21:26

Birkaç yıl montajcı programlaması yaptım, ardından onlarca yıllık C programı yaptım. Assembler programlarında C'den daha kötü işaretçi hataları yok gibi görünüyordu, ancak bunun önemli bir nedeni, assembler programlamasının nispeten yavaş çalışmasıydı.

Bulunduğum ekipler, her 10-20 montajcı talimatında bir işlevsellik artışı yazdıklarında çalışmalarını test etmek istiyorlardı. Daha yüksek seviyeli dillerde, genellikle çok daha fazla işlevselliğe sahip benzer sayıda kod satırından sonra test yaparsınız. Bu, bir HLL'nin güvenliğine karşı takas ediyor.

Assembler, daha düşük üretkenlik sağladığından ve genellikle diğer bilgisayar türlerine taşınabilir olmadığı için büyük ölçekli programlama görevleri için kullanılmayı bıraktı. Son 25 yılda yaklaşık 8 satır assembler yazdım ve bu bir hata işleyiciyi test etmek için hata koşulları oluşturmak içindi.

1 postasaguest Jan 22 2021 at 23:25

O zamanlar bilgisayarlarla çalışırken değil. Pek çok sorun yaşadık ama bellek bozulması sorunlarıyla hiç karşılaşmadım.

Şimdi birkaç IBM makinesi 7090,360,370, s / 3, s / 7 ve ayrıca 8080 ve Z80 tabanlı mikrolarda çalıştım. Diğer bilgisayarlarda bellek sorunları olabilir.