Кіріспе

Артқа қарай үйлесімді ассемблер тілдерінің отбасы
x86 ассемблер тілінің нақты нұсқаулар тізімі

x86 ассемблер тілі – 1972 жылдың сәуір айында шығарылған Intel 8008 микропроцессорынан бастап процессорлармен артқа қарай үйлесімділікті қамтамасыз ететін ассемблер тілдерінің отбасы. Ол x86 процессорлар класы үшін объектілік кодты жасау үшін қолданылады. Ассемблер бағдарламалау тілі ретінде қарастырылса, ол машинаға тәнді және төмен деңгейлі болып табылады. Барлық ассемблер тілдеріндей, x86 ассемблері негізгі процессор нұсқауларын немесе машиналық кодты көрсету үшін мнемоникаларды қолданады. Ассемблер тілдері көбінесе шағын, нақты уақыт режимінде жұмыс істейтін кіріктірілген жүйелер, операциялық жүйе ядролары және құрылғы драйверлері сияқты егжей-тегжейлі және уақытқа сезімтал қолданбалар үшін қолданылады, бірақ басқа да қолданбалар үшін де пайдаланылуы мүмкін. Компилятор жоғары деңгейдегі бағдарламаны машиналық кодқа аудару кезінде аралық қадам ретінде ассемблерлік кодты шығаруы мүмкін.

Режимдерді ауыстыру

Процессор қосылғаннан кейін бірден нақты режимде жұмыс істейді, сондықтан операциялық жүйе ядросы немесе басқа бағдарлама басқа режимде жұмыс істегісі келсе, оған қастықтан ауысуы тиіс. Режимдерді ауыстыру процессордың басқару тіркегіштерінің белгілі бір биттерін өзгерту арқылы, алдын ала дайындықтан кейін жүзеге асырылады, және ауысудан кейін қосымша орнату қажет болуы мүмкін.

Мысалдар

Ескі BIOS-ты қолданатын компьютерде BIOS және жүктеуші Реал режимінде жұмыс істейді. 64 биттік операциялық жүйе ядросы CPU-ны Ұзақ режимге ауыстырып, содан кейін 64 биттік кодты іске қосатын жаңа ядролық режимді жіберуді бастайды. UEFI-ді қолданатын компьютерде UEFI микробағдарламасы (CSM және ескі опциялық ROM-нан басқа), UEFI жүктеуіші және UEFI операциялық жүйе ядросы барлығы Ұзақ режимде жұмыс істейді.

Стейк нұсқаулары

x86 архитектурасы орындалу стегі механизмін аппараттық деңгейде қолдайды. Push, pop, call және ret сияқты командалар параметрлерді жіберу, жергілікті деректерге орын бөлу және шақырудан оралу нүктелерін сақтау және қайта қалпына келтіру үшін дұрыс орнатылған стекпен қолданылады. Ret size командасы, параметрлермен алынған стек кеңістігін босатуға жауапты болатын, кеңістікті тиімді (және жылдам) шақыру конвенцияларын іске асыру үшін өте пайдалы. Рекурсивті процедураның жергілікті деректерін сақтау үшін стек жинағын құру кезінде бірнеше таңдау бар: жоғары деңгейдегі enter командасы (80186 процессормен енгізілген) процедураның ішкі тереңдігі аргументін, сондай-ақ жергілікті өлшем аргументін қабылдайды және регистрлерді тікелей өңдеуге қарағанда жылдам болуы мүмкін (мысалы, push bp; mov bp, sp; sub sp, size). Оның жылдам немесе баяу болуы x86 процессорының нақтырақ іске асылуына, сондай-ақ компилятордың, бағдарламашының немесе нақты бағдарламалық кодтың шақыру конвенциясына байланысты. Көптеген x86 кодтары бірнеше өндірушілердің x86 процессорларында және процессорлардың әртүрлі технологиялық буындарында жұмыс істеуге арналған, бұл әртүрлі микроархитектуралар мен микрокодтық шешімдерді, сондай-ақ әртүрлі логикалық схемалар мен транзистор деңгейіндегі дизайн таңдауларын білдіреді. Push және pop сияқты командалар үшін де, адрестеу режимдерінің толық спектрі (тұрақты және базалық + офсетті қоса алғанда) бүтін сан, қалқыма нүкте және мекенжай деректері үшін стекті тікелей пайдалануды жеңілдетеді, сондай-ақ кейбір RISC архитектураларымен салыстырғанда ABI спецификациялары мен механизмдерін салыстырмалы түрде қарапайым етеді (шақыру стегінің толық егжей-тегжейін қажет етеді).

Бүкіл сандық ALU нұсқаулары

x86 құрастыруда стандартты математикалық операциялар бар: қосу, алу, теріс өрнек, иммуль және идив (белгілі бүтін сандар үшін), муль және див (белгісіз бүтін сандар үшін); логикалық операторлар және, немесе, xor, емес; арифметикалық және логикалық биттік ығыстыру, саль/сар (белгілі бүтін сандар үшін), шл/шр (белгісіз бүтін сандар үшін); тасымалдаумен және тасымалдаусыз айналдыру, rcl/rcr, rol/ror, BCD арифметикалық нұсқауларына толықтыру, aaa, aad, daa және басқалары.

Жылжымалы нүктелік нұсқаулар

x86 құрастыру тілі стекке негізделген қозғалатын нүктелік процессор (FPU) нұсқауларын қамтиды. FPU, 8086-дан 80386-ға дейінгі процессорлар үшін қосымша, бөлек копроцессор болды, 80486 сериясы үшін чиптегі опция ретінде, ал 80486-дан бастап, Pentium-мен бірге барлық Intel x86 процессорларында стандартты мүмкіндікке ие болды. FPU нұсқауларына қосу, алу, теріс мәнге айналдыру, көбейту, бөлу, қалдық табу, квадрат түбірді табу, бүтін санды қысқарту, бөлшекті қысқарту және екінің дәрежесіне қарай масштабтау кіреді. Операцияларға сонымен қатар түрлендіру нұсқаулары да кіреді, олар жадтан келесі форматтардың кез келгенінде мәнді жүктеуге немесе сақтауға мүмкіндік береді: екілік кодталған ондық, 32 биттік бүтін сан, 64 биттік бүтін сан, 32 биттік қозғалатын нүкте, 64 биттік қозғалатын нүкте немесе 80 биттік қозғалатын нүкте (жүктеу кезінде мән қазіргі қолданылып жатқан қозғалатын нүкте режиміне түрлендіріледі). x86 сонымен қатар трансценденттік функцияларды қамтиды, олардың ішінде синус, косинус, тангенс, арктангенс, 2-ге негізделген экспонента және 2, 10 немесе e негіздері бойынша логарифмдер бар. Нұсқаулардың стек регистрінен стек регистріне форматы әдетте fop st, st(n) немесе fop st(n), st түрінде болады, мұнда st – st(0) эквиваленті, ал st(n) – 8 стек регистрінің бірі (st(0), st(1), …, st(7)). Бүтін сандар сияқты, бірінші операнд – бірінші көз операнды және сонымен қатар нәтиже операнды болып табылады. fsubr және fdivr нұсқауларын бөліп көрсету қажет, себебі олар алу немесе бөлу операциясын орындау алдында көз операндарын ауыстырады. Қосу, алу, көбейту, бөлу, сақтау және салыстыру нұсқауларына олардың жұмысы аяқталғаннан кейін стек жоғарғы жағынан мәнді шығарып тастайтын нұсқау режимдері кіреді. Мысалы, faddp st(1), st нұсқауын орындау st(1) = st(1) + st(0) есептеуін жүзеге асырады, содан кейін стек жоғарғы жағынан st(0) мәнін алып тастайды, осылайша st(1) нәтижесі стектегі st(0) позициясына көшеді.

SIMD нұсқаулары

Қазіргі x86 процессорлары SIMD нұсқауларын қамтиды, олар кең SIMD тіркелгішінде кодталған көптеген мәндерге қатысты бірдей операцияны параллель түрде орындайды. Әртүрлі нұсқау технологиялары әртүрлі тіркелгіш жиынтықтарында әртүрлі операцияларды қолдайды, бірақ толығымен алғанда (MMX-тен SSE4.2-ге дейін) олар бүтін сандар немесе қозғалмалы нүкте арифметикасы бойынша жалпы есептеулерді қамтиды (қосу, алу, көбейту, ығысу, ең кішіні табу, ең үлкенін табу, салыстыру, бөлу немесе квадрат түбір табу). Мысалы, paddw mm0, mm1 нұсқаулы командасы mm0 мәндеріне mm1-дің 4 параллель 16 биттік (w белгісімен көрсетілген) бүтін сан қосындысын (padd белгісімен көрсетілген) орындайды және нәтижені mm0 тіркелгішінде сақтайды. Ағынды SIMD кеңейтімдері немесе SSE қозғалмалы нүкте режимін де қамтиды, онда тіркелгіштердің тек алғашқы мәні ғана өзгереді (SSE2-де кеңейтілген). Видео сығылымындағы (мысалы, MPEG-дегідей) қозғалыс бағалау үшін қолданылатын абсолютті айырмалардың қосындысы және бағдарламалық альфа араластыру мен цифрлық сүзгілеуге пайдалы 16 биттік көбейту-жинақтау нұсқаулары сияқты кейбір басқа да ерекше нұсқаулар қосылды. SSE (SSE3 нұсқасынан бастап) және 3DNow! кеңейтімдері кешенді сандар сияқты жұпталған қозғалмалы нүкте мәндерін өңдеуге арналған қосу және алу нұсқауларын қамтиды. Бұл нұсқаулар жиынтығына тіркелгіштердегі мәндерді араластыру, енгізу және алу үшін көптеген бекітілген сөз нұсқаулары да кіреді. Сонымен қатар, бүтін сандар тіркелгіштері мен XMM (SSE-де қолданылады) / FPU (MMX-де қолданылады) тіркелгіштері арасында деректерді жылжытуға арналған нұсқаулар бар.

Бағдарлама ағыны

x86 құрастырмасында шартты емес секіру операциясы бар, jmp, ол дереу адрес, регистр немесе жанама адрес параметрі ретінде қабылдауы мүмкін (көбінесе RISC процессорлары тек сілтеме регистрін немесе секіру үшін қысқа аралықты қолдайды). Сондай-ақ, бірнеше шартты секірулер қолдайды, оның ішінде jz (нөлге секіру), jnz (нөлден өзгеше секіру), jg (үлкен, таңбалы), jl (кішкентай, таңбалы), ja (үлкен немесе тең, таңбасыз), jb (кішкентай немесе тең, таңбасыз). Бұл шартты операциялар (E)FLAGS тіркеліміндегі белгілі бір биттердің күйіне негізделген. Көптеген арифметикалық және логикалық операциялар осы флагтарды нәтижесіне қарай орнатады, тазартады немесе инверттейді. cmp (салыстыру) және test нұсқаулары операндтардың мәнін өзгертпей, тиісінше, азайту немесе биттік ЖӘНЕ операциясын орындағандай флагтарды орнатады. Сондай-ақ, clc (тасымалды флагты тазалау) және cmc (тасымалды флагты инверттеу) сияқты флагтармен тікелей жұмыс жасайтын нұсқаулар бар. Қозғалатын нүктемен салыстыру fcom немесе ficom нұсқаулары арқылы жүзеге асырылады, олар ақырында бүтін сан флагтарына түрлендірілуі керек. Әрбір секіру операциясы операнттың мөлшеріне байланысты үш түрлі формада болады. Қысқа секіру 8 биттік таңбаланған операндыны пайдаланады, бұл ағымдағы нұсқаудан салыстырмалы ауытқу. Жақын секіру қысқа секіруге ұқсас, бірақ 16 биттік таңбаланған операндыны (нақты немесе қорғалған режимде) немесе 32 биттік таңбаланған операндыны (тек 32 биттік қорғалған режимде) пайдаланады. Алыс секіру толық сегмент базасын: офсет мәнін абсолюттік адрес ретінде пайдаланады. Олардың әрқайсысының жанама және индекстелген түрлері де бар. Жай секіру операцияларынан басқа, call (ішкі бағдарламаны шақыру) және ret (ішкі бағдарламадан қайтару) нұсқаулары бар. Басқаруды ішкі бағдарламаға беру алдында, call нұсқаудан кейінгі нұсқаудың сегменттік офсетін стекке салады; ret осы мәнді стекден шығарып, оған секіреді, нәтижесінде басқару ағыны бағдарламаның сол бөлігіне қайтарылады. Алысқа call жағдайында сегмент базасы офсеттен кейін стекке салады; алыс ret офсетті, содан кейін сегмент базасын шығарып қайтаруды жүзеге асырады. Сондай-ақ екі ұқсас нұсқау бар, int (үзіліс), ол стекке ағымдағы (E)FLAGS тіркелімінің мәнін сақтайды, содан кейін алыс call орындайды, бірақ адрес орнына үзіліс векторын, үзіліс өңдеуші адрестер тізіміне индекс қолданады. Әдетте, үзіліс өңдеушісі пайдаланған барлық басқа CPU тіркелімдерін сақтайды, егер олар операцияның нәтижесін шақырушы бағдарламаға қайтару үшін пайдаланбаса (бағдарламалық үзілістер деп аталады). Үзілістен қайтару нұсқаулығы iret, ол қайтарылғаннан кейін флагтарды қалпына келтіреді. Жоғарыда сипатталған типтегі жұмсақ үзілістер кейбір операциялық жүйелерде жүйелік шақырулар үшін қолданылады, сондай-ақ қатты үзіліс өңдеушілерін жөндеу үшін де қолданылуы мүмкін. Қатты үзілістер сыртқы аппараттық оқиғалар арқылы туындайды және қазіргі уақытта орындалып жатқан бағдарламаның күйі белгісіз болғандықтан барлық тіркелімдердің мәнін сақтауы керек. Қорғалған режимде операциялық жүйе тапсырманы ауыстыруға болатын үзілістерді орнатуы мүмкін, бұл белсенді тапсырманың барлық тіркелімдерін автоматты түрде сақтайды.

Мысалдар

Келесі мысалдарда Intel синтаксисінің Microsoft MASM, NASM және көптеген басқа құрастырушылар қолданатын түрі қолданылады. (Ескерту: AT&T синтаксисінің тағы бір түрі бар, онда бастапқы және нәтижелік операндардың орны ауыстырылған, сондай-ақ көптеген басқа да айырмашылықтар бар.)