Bunu birçok kez yaptım ve yapmaya devam ediyorum. Öncelikli amacınızın assembler okumak ve yazmak olduğu bu durumda, bunun geçerli olduğunu düşünüyorum.
Kendi sökücünüzü yazın. Bir sonraki en büyük sökücüyü yapmak amacıyla değil, bu kesinlikle sizin için. Amaç, talimat setini öğrenmektir. Bir zamanlar tanıdığım bir platform için assembler'ı hatırlayarak, yeni bir platformda assembler öğreniyor olsam da. Yalnızca birkaç satır kodla başlayın, örneğin yazmaçlar ekleyin ve ikili çıkışın sökülmesi ile giriş tarafına gittikçe daha karmaşık talimatlar eklemek arasında ping pinging yapın:
1) belirli bir işlemci için talimat setini öğrenin
2) her komutta her opcode bitini sallayabilmeniz için söz konusu işlemci için assemble kod yazmanın nüanslarını öğrenin
3) talimat setini, geçimini sağlamak için bu talimat setini kullanan mühendislerin çoğundan daha iyi öğrenirsiniz.
Sizin durumunuzda birkaç sorun var, normalde başlamak için ARM komut setini öneriyorum, bugün diğerlerinden daha fazla ARM tabanlı ürün gönderiliyor (x86 bilgisayarlar dahil). Ancak, şu anda ARM kullanıyor olmanız ve ARM'ın yapmaya çalıştığınız şeye yardımcı olabileceğini veya olmayabileceğini bilerek başlatma kodunu veya diğer rutinleri yazması için yeterli derleyici bilmeme olasılığınız. ARM için ikinci ve daha önemli neden, komut uzunluklarının sabit boyutta ve hizalı olmasıdır. X86 gibi değişken uzunluktaki komutları sökmek, ilk projeniz gibi bir kabus olabilir ve buradaki amaç, bir araştırma projesi oluşturmamak için talimat setini öğrenmektir. Üçüncü ARM, iyi hazırlanmış bir komut setidir, kayıtlar eşit oluşturulur ve bireysel özel nüanslara sahip değildir.
Yani hangi işlemciyle başlamak istediğinizi belirlemeniz gerekecek. Önce msp430 veya ARM'yi, ardından ARM'yi önce veya ikinci olarak sonra x86'nın kaosunu öneririm. Hangi platform olursa olsun, kullanmaya değer herhangi bir platformun, talimat setini ve işlem kodlarının (makine dilinin bitleri ve baytları) kodlamasını içeren, satıcıdan bağımsız veri sayfaları veya programcı referans kılavuzları vardır. Derleyicinin ne yaptığını ve derleyicinin uğraşmak zorunda olmadığı kodun nasıl yazılacağını öğrenmek amacıyla, birkaç komut seti bilmek ve her optimizasyonda her derleyici ile her komut setinde aynı yüksek seviyeli kodun nasıl uygulandığını görmek iyidir. ayarı. Kodunuzu yalnızca bir derleyici / platform için daha iyi, ancak her biri için çok daha kötü hale getirdiğinizi bulmak için optimize etmek istemezsiniz.
Değişken uzunluktaki komut setlerini sökmek için, basitçe başlangıçta başlayıp her dört baytlık kelimeyi, ARM'de yaptığınız gibi veya msp430 gibi her iki baytta olduğu gibi bellekte doğrusal olarak sökmek yerine (msp430'un değişken uzunluklu talimatları vardır, ancak yine de kesme vektör tablosundaki giriş noktalarında başlarsanız, bellekte doğrusal olarak ilerler). Değişken uzunluk için bir vektör tablosuna dayalı bir giriş noktası bulmak veya işlemcinin nasıl önyüklendiğini ve kodu yürütme sırasına göre takip etmek istiyorsunuz. Kaç bayt kullanıldığını bilmek için her komutun kodunu tamamen çözmeniz gerekir, o zaman komut koşulsuz bir dal değilse, bu komuttan sonraki baytı başka bir komut olarak kabul edin. Tüm olası şube adreslerini de saklamanız ve bunların daha fazla talimat için başlangıç bayt adresleri olduğunu varsaymanız gerekir. Başarılı olduğum bir seferde ikili dosyadan birkaç geçiş yaptım. Giriş noktasından başlayarak, bu baytı bir talimatın başlangıcı olarak işaretledim ve ardından koşulsuz bir dala ulaşana kadar bellek yoluyla doğrusal olarak kodunu çözdüm. Tüm şube hedefleri, bir talimatın başlangıç adresleri olarak etiketlendi. Yeni şube hedefi bulana kadar ikili üzerinden birden çok geçiş yaptım. Herhangi bir anda 3 baytlık bir talimat söylerseniz, ancak herhangi bir nedenle ikinci baytı bir talimatın başlangıcı olarak etiketlediyseniz, bir sorununuz varsa. Kod yüksek seviyeli bir derleyici tarafından oluşturulmuşsa, derleyici kötü bir şey yapmadıkça bu gerçekleşmemelidir, Eğer kodun elle yazılmış assembler'ı varsa (örneğin eski bir arcade oyunu gibi), r0 = 0 gibi asla gerçekleşemeyen koşullu dallar ve ardından sıfır değilse de bir sıçrayış olması oldukça olasıdır. Devam etmek için bunları ikili programın dışında düzenlemeniz gerekebilir. X86'da olacağını düşündüğüm acil hedefleriniz için bir sorununuz olacağını düşünmüyorum.
Gcc araçlarını öneririm, mingw32, hedefiniz x86 ise Windows'ta gcc araçlarını kullanmanın kolay bir yoludur. Eğer mingw32 plus msys değilse, binutils ve gcc kaynaklarından çapraz derleyici oluşturmak için mükemmel bir platformdur (genellikle oldukça kolaydır). mingw32'nin cygwin'e göre çok daha hızlı programlar gibi bazı avantajları vardır ve cygwin dll cehenneminden kaçınırsınız. gcc ve binutils, C veya assembler'da yazmanıza ve kodunuzu parçalarına ayırmanıza izin verir ve üçünden birini veya tümünü nasıl yapacağınızı gösteren okuyabileceğinizden daha fazla web sayfası vardır. Bunu değişken uzunlukta bir komut seti ile yapacaksanız, bir sökücü içeren bir alet seti kullanmanızı şiddetle tavsiye ederim. Örneğin, x86 için üçüncü taraf bir parçalayıcı, doğru şekilde sökülüp sökülmediğini asla bilemeyeceğiniz için kullanımı zor olacak. Bunların bir kısmı da işletim sistemine bağlıdır, amaç, modülleri, veriden bilgi işaretleme talimatlarını içeren bir ikili formatta derlemek, böylelikle ayırıcı daha doğru bir iş yapabilir. Bu birincil hedef için diğer seçiminiz, incelemeniz için doğrudan assembler'a derleyebilen bir araca sahip olmak ve ardından ikili formatta derlendiğinde aynı talimatları oluşturmasını ummaktır.
Sorunuzun kısa (tamam, biraz daha kısa) cevabı. Bir talimat setini öğrenmek için bir sökücü yazın. RISCy ve ARM gibi öğrenmesi kolay bir şeyle başlardım. Bir komut setini öğrendikten sonra, diğerlerini almak çok daha kolay hale gelir, genellikle birkaç saat içinde, üçüncü komut setiyle, sözdizimi için veri sayfasını / referans kılavuzunu kullanarak neredeyse anında kod yazmaya başlayabilirsiniz. Kullanmaya değer tüm işlemcilerin, talimatları işlem kodlarının bit ve baytlarına kadar açıklayan bir veri sayfası veya başvuru kılavuzu vardır. ARM gibi bir RISC işlemcisini ve x86 gibi bir CISC'yi, farklılıklar konusunda bir fikir edinmeye yetecek kadar öğrenin, her şey için kayıtlardan geçmek zorunda kalmak veya daha az kayıtla veya hiç kayıt olmadan doğrudan bellek üzerinde işlem yapabilmek gibi şeyler. Üç işlenen komutuna karşı iki vb. Yüksek seviye kodunuzu ayarlarken, birden fazla işlemci için derleyin ve çıktıyı karşılaştırın. Öğreneceğiniz en önemli şey, yüksek seviyeli kod ne kadar iyi yazılırsa yazılsın derleyicinin kalitesinin ve yapılan optimizasyon seçimlerinin gerçek talimatlarda büyük bir fark yaratmasıdır. Llvm ve gcc'yi (binutils ile) öneririm, ne üretmezharika kod, ancak bunlar çok platformlu ve çok hedeflidir ve her ikisinin de optimize edicileri vardır. Ve her ikisi de ücretsizdir ve çeşitli hedef işlemciler için kaynaklardan kolayca çapraz derleyiciler oluşturabilirsiniz.