İhtiyacınız olan ilk şey bu dosya gibi bir şey . Bu NASM montajcı tarafından kullanılan x86 işlemciler için talimat veritabanı (ki aslında talimatları çeviren parçalar olmasa da, yazmaya yardımcı oldum). Veritabanından rastgele bir satır seçelim:
ADD rm32,imm8 [mi: hle o32 83 /0 ib,s] 386,LOCK
Bunun anlamı, talimatı tanımlamasıdır ADD. Bu komutun birden fazla varyantı vardır ve burada tarif edilen spesifik, 32 bitlik bir kayıt veya bellek adresi alan ve hemen 8 bitlik bir değer ekleyen varyanttır (yani talimatta doğrudan dahil edilen bir sabit). Bu sürümü kullanacak örnek bir montaj talimatı şudur:
add eax, 42
Şimdi, metin girişinizi almanız ve bireysel talimatlara ve işlenenlere ayrıştırmanız gerekir. Yukarıdaki talimat için, bu muhtemelen talimatı içeren bir yapıya ADDve bir işlenen dizisine (kayıt EAXve değere referans 42) neden olacaktır. Bu yapıya sahip olduğunuzda, talimat veritabanını çalıştırırsınız ve hem komut adı hem de işlenen türleriyle eşleşen satırı bulursunuz. Bir eşleşme bulamazsanız, bu, kullanıcıya sunulması gereken bir hatadır ("opcode ve işlenenlerin yasadışı kombinasyonu" veya benzeri, normal metindir).
Veritabanından satır aldıktan sonra, bu talimat için üçüncü sütuna bakıyoruz:
[mi: hle o32 83 /0 ib,s]
Bu, gerekli makine kodu talimatının nasıl oluşturulacağını açıklayan bir dizi talimattır:
- Bu
mi, işlenenlerin bir tanımlamasıdır: bir a modr/m(kayıt veya bellek) işleneni (yani modr/m, talimatın sonuna bir bayt eklememiz gerekeceği anlamına gelir, daha sonra geleceğiz) ve bir acil talimat ( talimatın açıklamasında kullanılmalıdır).
- Sıradaki
hle. Bu, "kilit" önekini nasıl ele aldığımızı tanımlar. "Kilit" kullanmadık, görmezden geldik.
- Sıradaki
o32. Bu bize 16 bit çıkış biçimi için kod monte edersek, talimatın işlenen boyut geçersiz kılma önekine ihtiyacı olduğunu söyler. 16-bit çıktı üretiyor olsaydık, şimdi öneki ( 0x66) üretirdik , ama öyle olmadığımızı ve devam edeceğimizi varsayacağım.
- Sıradaki
83. Bu, onaltılı olarak gerçek bir bayttır. Biz çıkardık.
Sıradaki /0. Bu, modr / m bytem içinde ihtiyaç duyacağımız bazı ekstra bitleri belirtir ve üretmemize neden olur. modr/mBayt kodlamak kayıtları veya dolaylı bellek başvuruları için kullanılır. Tek bir işlenen var, bir sicil. Kayıt başka bir veri dosyasında belirtilen bir numaraya sahiptir :
eax REG_EAX reg32 0
reg32Orijinal veritabanından gerekli talimat boyutunu kabul edip etmediğini kontrol ediyoruz (öyle). 0Kasan sayıdır. Bir modr/mbayt işlemcisi tarafından belirlenen bir veri yapısı, böyle bu görünüm olup:
(most significant bit)
2 bits mod - 00 => indirect, e.g. [eax]
01 => indirect plus byte offset
10 => indirect plus word offset
11 => register
3 bits reg - identifies register
3 bits rm - identifies second register or additional data
(least significant bit)
Bir sicille çalıştığımız için, modalan öyle 0b11.
regTarla, Kullandığımız kayıt sayısıdır0b000
- Bu talimatta yalnızca bir kayıt olduğundan,
rmalanı bir şeyle doldurmamız gerekiyor . Belirtilen ekstra veriler bunun /0içindi, bu yüzden bunu rmalana koyduk 0b000.
- Bu
modr/mnedenle bayt 0b11000000veya 0xC0. Bunun çıktısını alıyoruz.
- Sıradaki
ib,s. Bu, imzalı bir anlık baytı belirtir. İşlenenlere bakarız ve hemen bir değere sahip olduğumuzu not ederiz. İşaretli bir bayta dönüştürüyoruz ve çıktısını veriyoruz ( 42=> 0x2A).
Tamamen montajlı talimat nedenle: 0x83 0xC0 0x2A. Baytların hiçbirinin bellek referansı oluşturmadığını (çıkış modülünün çalışıp çalışmadığını bilmeleri gerekebilir) bir notla birlikte çıkış modülünüze gönderin.
Her talimat için tekrarlayın. Referans alındığında ne ekleyeceğinizi bilmeniz için etiketleri takip edin. Nesne dosyası çıkış modüllerinize aktarılan makrolar ve yönergeler için olanaklar ekleyin. Temel olarak bir montajcı bu şekilde çalışır.