Bosh sahifa Wiki Machine code

Machine code

Machine code — protsessor bevosita dekodlab bajaradigan ikkilik ko‘rsatmalar va ularga tegishli ma’lumotlar ketma-ketligidir. Har bir ko‘rsatmaning bitlari opcode, registr, manzillash usuli va darhol beriladigan qiymat kabi maydonlarni ifodalaydi. Mashina kodi muayyan instruction set architecture uchun yaratiladi; boshqa ISA protsessori uni bevosita bajara olmaydi.

Kodlash va dekodlash

Ba’zi arxitekturalarda ko‘rsatmalar bir xil uzunlikda, boshqalarida esa o‘zgaruvchan uzunlikda bo‘ladi. Protsessor instruction pointer ko‘rsatgan manzildan baytlarni oladi, ko‘rsatma chegarasini aniqlaydi, opcode’ni dekodlaydi va kerakli bajarish bloklariga yuboradi. Operand registrda, ko‘rsatma ichida yoki hisoblangan xotira manzilida joylashishi mumkin.

Mashina kodi odatda o‘n oltilik shaklda ko‘rsatiladi, chunki uzun bit satriga qaraganda ixchamroq. Ammo bitta baytning ma’nosi uning ko‘rsatma ichidagi joyi va ISA rejimiga bog‘liq. Endianness ko‘p baytli ma’lumot va ayrim kod maydonlarining xotirada tartibiga ta’sir qiladi. Disassembler baytlarni assembly mnemoniklariga aylantiradi, lekin kod bilan ma’lumot chegarasi noma’lum bo‘lsa natija noaniq bo‘lishi mumkin.

Yaratilish jarayoni

Kompilyator yuqori darajali kodni oraliq tasvir orqali mashina ko‘rsatmalariga tushiradi. Assembler assembly manbasini obyekt fayldagi kod baytlariga aylantiradi. Tashqi funksiyalar yoki hali noma’lum manzillar uchun relocation yozuvlari qoldiriladi. Linker bo‘limlarni joylashtirib, symbollarni hal qilgach executable yoki shared library hosil bo‘ladi.

JIT kompilyator mashina kodini dastur ishlayotgan paytda xotirada yaratishi mumkin. Xavfsiz amalga oshirishda sahifa bir vaqtning o‘zida ham yoziladigan, ham bajariladigan bo‘lmasligi uchun write-then-execute siyosati qo‘llanadi. Instruction cache bilan data cache alohida bo‘lgan arxitekturada yangi kod ko‘rinishi uchun sinxronlash ham kerak bo‘ladi.

Bajarilish muhiti

Executable fayl faqat ko‘rsatmalardan iborat emas. U kod, read-only konstantalar, boshlang‘ich ma’lumot, symbol, relocation va debug bo‘limlarini saqlashi mumkin. Loader segmentlarni virtual xotiraga xaritalaydi, dinamik bog‘lanishlarni bajaradi va kirish nuqtasiga boshqaruv beradi. Privilege level qaysi ko‘rsatma va manzillar foydalanuvchi jarayoniga ruxsat etilganini cheklaydi.

Mashina kodi apparatga yaqin bo‘lgani uchun xatoni tahlil qilishda registr holati, stack, calling convention va aniq ko‘rsatma semantikasini bilish kerak. Debug symbol mavjud bo‘lsa, manzillar funksiya va manba qatorlariga bog‘lanadi. Binar xavfsizlikda control-flow protection, manzil tasodifiylashtirish va bajarilmaydigan ma’lumot sahifalari kodni suiiste’mol qilishni qiyinlashtiradi, ammo xotira xavfsizligi xatosini o‘zi bartaraf etmaydi.

Ma’lumot sifatida kod

Executable format kod baytlarining qayerdan boshlanishini metama’lumot bilan bildiradi, ammo xotira dumpi yoki o‘zgartirilgan binarda bu chegara yo‘qolishi mumkin. X86 kabi o‘zgaruvchan uzunlikdagi ISA’da boshqa offsetdan dekodlash butunlay boshqa, lekin sintaktik yaroqli ko‘rsatmalar beradi. Shu xususiyat reverse engineeringni murakkablashtiradi. Signed code mexanizmi baytlar nashriyotchidan kelganini va o‘zgarmaganini tekshirishi mumkin, ammo kodning mantiqan xavfsizligini kafolatlamaydi. Loader imzo, format chegaralari va platforma siyosatini tekshiradi; protsessor esa baribir faqat dekodlangan ko‘rsatma semantikasini bajaradi.

Self-modifying code va JIT uchun xotira ruxsatlari ketma-ket o‘zgartiriladi, yozish tugagach bajarish yoqiladi. Ko‘p oqimli muhitda boshqa yadro eski instruction cache nusxasini ko‘rmasligi uchun platforma ko‘rsatgan barrier bajariladi. Debugger breakpoint qo‘yishda ko‘rsatma baytini vaqtincha trap bilan almashtirishi va asl baytni saqlashi mumkin. Shu sababli ishlayotgan jarayon xotirasidagi kod diskdagi fayl bilan har doim aynan teng emas.

Bog‘liq tushunchalar

Assembly language, ISA, Opcode, Object file, Linker, Loader, Executable