Асемблер x86

x86 асемблерски језик је фамилија уназад-компатибилних асемблерских језика, који дају одређени ниво компатибилности све до Интел 8008. x86 асемблерски језици се користе за прављење објектног кода за процесоре из класе x86. Као и сви асемблерски језици, користи кратку мнемотехнику за репрезентовање основних инструкција које ЦПЈ може да може да разуме и прати. Компајлери понекад праве асемблерски код при преводу асемблерских језика у машински језик. Асемблерски језик се сматра програмским језиком, и он је машински специфичан и језик ниског нивоа. Овај језик се користи за мале уграђене системе у реалном времену, или језгра оперативних система.

Историја

[уреди | уреди извор]

Интел 8088 и 8086 су били први процесори који су имали x86 скуп инструкција. Ови 16-битни процесори су били еволуција претходне генерације 8-битних процесора од којих су наследили многе карактеристике и инструкције, који су проширени за 16-битну еру. 8088 и 8086 су користили 20-битну адресну магистралу и 16-битне унутрашње регистре, али 8086 је имао 16-битну магистралу за податке, а 8088 8-битни. x86 асемблерски језик подржава разне верзије које су пратиле ове, од Интелових 80188, 80186, 80286, 80386,80486, Pentium, Pentium Pro, и тако даље, као и АМД и Сајриксове 5x86 и K6 процесоре и НЕЦ В20. Термин x86 односи се на ЦПД који може да ради на оригиналном асемблерском језику.

Модерни x86 инструцкијски скуп је надскуп 8086 скупа инструкција и серија екстензија овом скупу инструкција које је почело са Интел 8080 процесором. Скоро потпуна бинарна компатибилност уназад постоји између Интел 8086 чипа и свих чипова до тренутне генерације x86 процесора. У пракси је нормално да се користе инструкције које ће радити на било чему после Интел 80386 или Пентијума, мада су у задњим годинама разни оперативни системи почели да захтевају модерније процесоре или бар да подржавају новије екстензије за инструкцијски скуп.

Мнемотехника и операциони кодови

[уреди | уреди извор]

Свака x86 монтажна инструкција је представљена мнемотехником која комбинована са једним или више операнада, може да се претвори у један или више операционих кодова (опкода). НОП команда се преводи у 0x90, а ХЛТ инструкција се преводи у 0xF4.

Синстакса

[уреди | уреди извор]

x86 асемблерски језик има две главне бранше синтакси: Интел синтакса и АТиТ синтакса. Интел синтакса је домнантна у ДОС-у и Microsoft Windows свету, а АТиТ је доминантна у Јуникс свету, пошто је створена у АТиТ Беловим лабораторији. Овде је преглед главних разлика између Интел и АТиТ синтакси:

АТиТ Интел
редослед параметара Извор пре одредишта

eax := 5 је mov $5, %eax

Одредиште пре извора

eax := 5 је mov eax, 5

Parameter Size На мнемотехнику се ставља суфикс са писмом које индијује величину операнада ("q" за qword, "l" за long (dword), "w" за word, и "b" за бајт)

addl $4, %esp

Изведено из имена регистра који се користи (rax, eax, ax, al имплицирају q,l,w,b тим редом)
add   esp, 4
Сигили тренутне вредности Са префиксом "$", и регистри морају имати префикс "%" Асемблер аутоматски детектује тип симбола, да ли су регистри, константе, или нешто друго.
Ефективне адресе Генерална синтакса DISP(BASE,INDEX,SCALE)

Пример:

movl mem_location(%ebx,%ecx,4), %eax
Користе промењиве, и морају да буду у угластим заградама; додатно, величинске речи као byte, word, или dword морају бити коришћени.

Пример:

mov eax, dword [ebx + ecx*4 + mem_location]

Многи x86 асембелри користе Интел синтаксу, укључујући МАСМ, ТАСМ, НАСМ, ФАСМ, и ЈАСМ. ГАС је подржавао обе синтаксе под .интел_синтакс директивом.

Регистри

[уреди | уреди извор]

x86 процесори имају колекцију регистара која је дозвољена за складиштење бинарних података. Заједно се подаци и адресни регистри зову генерални регистри. Сваки регистар има специјалну примену.

  • AX множење-дељење, вађење и чување стринга
  • CX бројач за операције над стрингом
  • DX порт адреса за IN и OUT
  • BX регистар индекса за MOVE
  • SP показју на врх стека
  • BP показује на базу стека
  • SI покзује на извор у стрим операцијама
  • DI показује на дестинацију у стрим операцијама

Заједно са генералним регистрима, ту су обично и:

  • ИП инструкциони показивач
  • Заставе
  • Сегментни регистри (CS, DS, ES, FS, GS, SS) који одређују где 64к сегмент почиње (нема FS и GS у 80286 и ранијим)
  • Додатни екстензиони регистри (MMX, 3DNow!, SSE, итд.) (само Пентијум и каснији).

ИП регистар показује на меморијски офсет следеће инструкције у кодном сегменту (показује на први бајт инструкције). Програмер не може приступити ИП регистру директно. x86 регистри се могу користити применом MOV инструкција. На пример:

mov ax, 1234h
mov bx, ax

копира вредност 1234h (4660d) у регистар AX и онда копира вредност AX регистра у BX регистар (Интелова синтакса).

Сегмнетнтно адресирање

[уреди | уреди извор]

x86 архитектура у реалном и виртуелном 8086 режиму користи процес који се зове сегментација за адресирање меморије, а не равни меморијски модел који се користи у разним другим окружењима. Сегментација се састоји из компоновања меморијске адресе из два дела, сегмента и офсета. Сегмент показује на почетак групе од 64 kB адреса и офсет одређује колико је отакле удаљена жељена адреса. У сегментном адресирању, два регустра су потребна за комплетирање меморијске адресе: један да држи сегмент, а други да држи офсет. Да би се ово превело на равни меморијски модел, сегментна вредност је померена за 4 бита улево (еквавилентно множењу са 16) и онда додато на офсет да се направи цела адреса, што дозвољава ломљење 64к баријере кроз паметан избор адреса, иако то чини програмирање комплекснијим.

У реалном (заштићеном) режиму, ако DS садржи хексадецималну вредност 0xDEAD и DX садржи број 0xCAFE они би заједно показивали на адресу 0xDEAD * 0x10 + 0xCAFE = 0xEB5CE. Стога, ЦПЈ може адресирати до 1.048.576 бајтова (1 MB) у реалном режиму. Мешајући сегментну и офсет вредност налазимо 20-битну адресу.

Оригинални IBM ПЦ је забрањивао програме веће од 640 kB али проширена меморијска спецификација је коришћена за спровођење банке прекидачке шеме која се није користила када су каснији оперативни системи као што је Windows, користили веће адресне опсеге новијих процесора и спровели своје шеме виртуелне меморије.

Заштићени режим је започео са Интелом 80386. Неколико недостатака, као што је немогућност приступу БИОС-у и немогућност за враћањем на реални режим без ресетовања процесора су онемогућили широко коришћење. 80286 је такође био ограничен на адресну меморију у 16-битним сегментима, што значи да се може адресирати само 64 kB меморије одједном. За приступ проширеној функционалности 80286 процесор би поставио процесор у заштићени режим, што би омогућило 24-битно адресирање и 16 MB меморије.

У заштићеном режиму, сегментни селектор се може раставити на три дела: 13-битни индекс, индикатор табле који одређује да ли је улаз у GDT или LDT и двобитни Requested Privilege Level.

Када се говори о адреси са сегментом, и офсетирању нотације сегмента, офсет се користи, па се у горњем примеру равна адреса 0xEB5CE може написати као 0xDEAD:0xCAFE или као сегмент и офсет регистрованог пара; DS:DX.

Постоје специјалне комбинације сегментних регистара и генералних регистара које показују на битне адресе:

  • CS:IP (CS је Code Segment, IP је Instruction Pointer) показује на адресу са које ће процесор узети следећи кодни бајт.
  • SS:SP (SS је Stack Segment, SP је Stack Pointer) показује на адресу врха стека, односно на последњи стављен бајт.
  • DS:SI (DS је Data Segment, SI је Source Index) је често коришћен за показивање на стринг податке који се требају копирати на ES:DI.
  • ES:DI (ES је Extra Segment, DI је Destination Index) је често коришћен за показивање на одредиште за копирање стринга, као што је наведено горе.

Интел 80386 има три оперативна режима: реални, заштићени и виртуелни режим. Заштићени режим, који је први пут био у 80286 је проширен за допуштање да 80386 адресира до 4 GB меморије, потпуно нови 8086 режим (VM86) је омогућио покретање једног или више реално-режимних програма у заштићеном окружењу које је емулирало реални режим, иако неку програми нису били компатибилни (типично због трикова у вези са адресирањем меморије или коришћењем неспецифираних опкодова).

Проширење заштићеног режима 32-битног равног меморијског модела 80386-ице је можда најбитнија промена у фамилији x86 процесора све док АМД није избацио x86-64 у 2003, пошто је помогло велико примање Windows-а 3.1 (који се ослањао на заштићени режим) пошто је Windows сада могао да покреће више апликација одједном, укључујући ДОС алпикцаије, коришћењем виртуелне меморије и простог мултитаскинга.

Режими извршавања

[уреди | уреди извор]

x86 процесори подржавају пет режима операција за x86 код, Реални режим, Заштићени режим, Дуги режим, Виртуелни 86 режим, и Режим за системски менаџмент, у ком су неке инструкције доступне а неке нису. 16-битни подскуп инструкција је доступан у реалном режиму (сви x86 процесори), 16-битни заштићени режим (80286 па надаље), V86 режим (80386 па надаље) и SMM (Интел i386SL, i486 и каснији). У 32-битном заштићеном режиму (Интел 80386 па надаље), 32-битне инструкције (укључукући каснија проширења) су такође доступни; у дугом режиму (АМД Оптерон па надаље), 64-битне инструкције, и више регистара су такође доступни. Инструкциони скуп је у сваком режима али мморијско адресирање и величина речи варирају, што захтева другачије програмерске стратегије.

Режими у којима се x86 код може извршити су:

  • Реални режим (16-битни)
  • Заштићени режим (16-битни и 32-битни)
  • Дуги режим (64-битни)
  • Виртуелни 8086 режим (16-битни)
  • Режим за менаџмент система (16-битни)

Прекидачки режими

[уреди | уреди извор]

Процесор улази у реални режим одмах након паљења, тако да оперативни систем или неки други програм морају експлицитно да га промене на други режим ако жели да ради у било чему осим у реалном режиму. Прекидачки режими су омогућени модификацијом одређених битова процесорских контролних регистра иако је нека припрема неопходна у највећем броју случајева, и неко чишћење после мењања.

Типови инструкција

[уреди | уреди извор]

Генерално, функције модерног x86 скупа инструкција су:

  • Компактно кодирање
    • Промењива дужина и сврставање су независни (кодирани као мали ендиан, као и сви подаци у x86 архитектури)
    • Угланом једноадресне или двоадресне инструкције, односно први опреранд је и дестинација.
    • Меморијски операнди и као извор и као дестинација су подржани (често коришћени за читање и писање стек елемената адресираних помоћу малих тренутних офсета).
    • И генерално и имплицитно коришћење регистара. Иако су свих седам генералних регистара у 32-битном режиму, и свих 15 генералних регистара у 64-битном режим се могу користити као алумулатори или за адресирање, већина њих је имплицитно коришћена за специјалне инструкције. Погођени регистри онда морају да буду сачувани.
  • Прави кондиционе флегове имплицитно кроз већину АЛУ инструкција.
  • Подржава разне адресионе режиме укључујући тренутне, офсет, и скалирани индекс але не ПЦ-релативни, осим за џампове (уведеним као побољшање у x86-64 архитектури).
  • Садржи покретни зарез за стек регистара.
  • Садржи специјалну подршку за атомски читај-модификуј-пиши инстукције xchg, cmpxchg/cmpxchg8b, xadd, и инструкције целог броја које комбинују са lock префиксом).
  • СИМД инструкције (инструкције које извршавају паралелне истовремене појединачне инструкције на много операнада кодирани у суседним ћелијама ширих регистара).

Инструкције за стек

[уреди | уреди извор]

x86 архитектура има хадрверску подршку за извршавање стек механизма. Инструкције попут push, pop, call и ret се користе са стеком да алоцирају простор за локалне податке и да чувају и враћају call-return тачке. ret инструкцијаје веома корисна за имплементирање просторно ефикасних и брзих конвенција позивања где је позивани одговоран за враћање стек простора.

Када се поставља стек фрејм да чува локалне податке или рекурзивну процедуру постоји неколико избора. Инструкција на високом нивоу enter узима procedure-nesting-depth аргумент као и local size аргумент, и може да буде бржа од експлицитнијих манипулација регистрима. Да ли је бржа или не зависи од x86 имплементације, као и од конвенције позивања и кода потребном да ради на више процесора.

Пуни опсег адресних режима (укључујући тренутне и база + офсет) чак и за инструкције попут push и pop чини директно коришћење стека за цели број, покретни зарез и адресне податке једноставним, као што и АБИ спецификације и механизме истају једноставни у поређењу са неким РИСЦ архитектурама (захтевају експлицитније детаље позива стека).

АЛУ инструкције над целим бројем

[уреди | уреди извор]

x86 има стандардне математичке опције add, sub, mul, са idiv, логички оператори and, or, xor, neg аритметику за померање битова sal/sar, shl/shr, ротирање са и без ношења, rcl/rcr, rol/ror, комплемент БЦД аритметичких инструкција, aaa, aad, daa и друго.

Инструкције над покретним зарезом

[уреди | уреди извор]

x86 асемблерски језик садржи инструкције за јединицу за покретни зарез базиран на стеку. Она садржи сабирање, одузимање, негацију, множење, дељење, остатак, квадратни корнен и квадрирање. Операције такође садрже инструкције за конвертовање који могу да узимају или чувају вредност из меморије у свим следећим форматима: бинарно кодиране децимале, 32-битни цели бројеви, 64-битни цели бројеви, 64-битни бројевеи са покретним зарезом или 80-битни бројеви (који се након узимања конвертују у тренутно коришћен режим). x86 такође садржи функције попут синуса, косинуса, тангенса, аркус тангенса, рачунање са експонентима са базом 2 и логаритмовање са базама 2, 10 или е.

Стек регистар до стек регистар инструкције су обично fop st, st(*) или fop st(*), st, где је st еквевилентно st(0), и st(*) је један од 8 стек регистара (st(0), st(1), ..., st(7)). Као и цели бројеви, први операнд је и изворни операнд и дестинациони операнд. Додавање, одузимање, множење, дељење, чување и компензационе инструкције садрже инструкционе режиме који ће се попети на врх стека када су њихове инструкције извршене. Дакле на пример faddp st(1), st извршава рачунање st(1) = st(1) + st(0), онда уклања st(0) од врха стека, и тако мења оно што је био резултат у st(1)на врх стека у st(0).

СИМД инструкције

[уреди | уреди извор]

Модерни x86 процесори садрже СИМД инстукције, које углавном одрађују исте операције паралелно на много вредносту кодираних у широком СИМД регустру. Разне инструкционе технологије подржавају различите операције на различитим регистарским скуповома, али гледано као целина (од MMX до SSE4.2) садрже генерална рачунања на целобројну или децималну аритметику (сабирање, одузимање, множење, shift, минимализација, максимизација, поређење, дељење или квадратни корен). Дакле на пример, paddw mm0, mm1 одрађује 4 паралелних 16-битних (индиковано w) целобројних додавања (индиковано padd) mm0 вредности на mm1 и чува резултате у mm0. Streaming SIMD Extensions или ССЕ такође садрже децимални режим у коме је само прва вредност регистра заправо модификована (тоје проширено у ССЕ2). Неке друге необичне инструкције су додате укључујући суму апсолутних разлика (коришћених за предвишање померања у компресији видеа, као што се ради у MPEG) и 16-битну акумулациону инструкцију (корисно за софтверско алфа блендовање и дигитално филтеровање). ССЕ (од ССЕ3) и 3DNow! екстензије садрже инструкције за сабирање и одузимањеза третирање упарених децималних вредности као што су комплексни бројеви.

Ови инстукцијски скупови такође садрже мноштво фискираних под-инструкција за мешање, убацивање и вађење вредности из тих регистара. Додатно ту су инструкције за померање података између целобројних регистара и XMM (коришћени у SSE)/FPU (коришћени у MMX) регистара.

Инструкције за манипулисање подацима

[уреди | уреди извор]

x86 процесор такође садржи комплексне адресне режиме за адресирање меморије са тренутним офсетом, регистар, регистар са офсетом, скалирану верзију са офсетом, или без њега, и регистар са обционим офсетом и још један скалирани регистар. Тако на пример, један може да кодира mov eax, [Table + ebx + esi*4] као једну инструкцију која чита 32 бита података са адресе израчунате као (Table + ebx + esi * 4) офсет од ds селектора, и чува га у eax регистру. Генерално x86 могу да читају и корсите меморију погођену са величином било ког регистра на којем ради. (СИМД инструкције такође садрже инструкције за полу-увођење.) x86 инструкцијски скуп садржи читање стринга, чување, померање, скенирање и инструкције за поређење (lods, stos, movs, scas и cmps) које одрађују сваку операцију на специфирану величину (b за 8-битну, w за 16-битну и d за 32-битну дуплу реч) онда увећање и умањење (зависно од DF, direction flag) имплицитни адресни регистар (si за lods, di за stos за scas, и оба за movs и cmps). За читање, чување и операције скенирања, имплицитни регистар за циљ/извор/поређење је у al, ax или eax регистар (зависно од величине). Имплицитни сегменти регистри који се користе су ds за si и es за di. cx или ecx регистар се користи као бројач смањивања, и операција стаје кад бројач дође до нуле или (за скенирање или поређење) када је неједнакост детектована.

Стек је имплементиран са имплицитним декрементирањем (push) и инкрементирањем (pop) показивача на стек. У 16-битном режиму, овај имплицитни показивач стека је адресиран као SS:[SP], у 32-битном је SS:[ESP], а у 64-битном режиму је [RSP]. Показивач стека заправо показује на последњу вредност која је сачувана, под претпоставком да ће његова величина одговарати оперативном режиму процесора (16, 32, или 64 бита) да би одговарао нормалној ширини push/pop/call/ret инструкција. Такође су укључене enter и leave које чувају и бришу податке од врха стека док постављају стек фрејм показивач bp/ebp/rbp. Међутим, директно подешавање, или додавање или одузимање на sp/esp/rsp регистар је такође подржано, па су enter/leave инструкције генерално непотребне.

Овај код је почетак функције:

push    ebp       ; save calling function's stack frame (ebp)
mov     ebp, esp  ; make a new stack frame on top of our caller's stack
sub     esp, 4    ; allocate 4 bytes of stack space for this function's local variables

и функционално је једнак:

enter   4, 0

Друге инструкције за манипулисање стеком укључују pushf/popf за чување и враћање (E)FLAGS регистра. pusha/popa инструкције ће чувати и враћати стање целог броја у и из стека.

Претпоставља се да су вредности за СИМД чување или враћање паковане на суседне позиције за СИМД регистар и да ће их поређати у секвенцијални низ. Неке SSE инструкције за чување и враћање захтевају 16-бајтно ређање да би функционисали. СИМД инстукциони скупови садрже и "prefetch" инструкције које одрађују узимање али не циљају ниједан регистар који се користи за узимање кеша.. SSE инструкцијски скуп такође садржи не-временске инстукције за чување које ће извршити чување право у меморију без алоцирања кеша ако одредиште није већ кеширано (иначе ће се понашати као регуларно чување).

Већина генеричких инструкција за целе и децималне бројеве (али не и СИМД) могу да користе један параметар као комплексну адресу као параметар другог извора. Целобројне инструкције такође могу прихватити један меморијски параметар као операнд одредишта.

"Hello world!" програм за ДОС у МАСМ стилу монтаже

[уреди | уреди извор]

Користећи interrupt 21h за излаз - други примери користе libc printf за писање на stdout.

.model small
.stack 100h

.data
msg	db	'Hello world!$'

.code
start:
	mov	ah, 09h ; Прикажи поруку
	lea	dx, msg
	int	21h
	mov	ax, 4C00h ; Прекини извршавање
	int	21h

end start

"Hello World!" програм за Windows у МАСМ стилу монтаже

[уреди | уреди извор]
; захтева /coff прекидач на верзији 6.15 и каснијим
.386
.model small,c
.stack 100h
 
.data
msg db "Hello World!",0
 
.code
includelib MSVCRT
extrn printf:near
extrn exit:near
 
public main
main proc
        push    offset msg
        call    printf
        push    0
        call    exit
main endp
 
end main

"Hello world!" програм за Линукс у НАСМ стилу монтаже

[уреди | уреди извор]
;
; Овај програм ради у 32-битном заштићеном режиму.
; build: nasm -f elf -F stabs name.asm
; link: ld -o name name.o
;
; У 64-битном режиму се могу користити 64-битни регистри (rax уместо eax, rbx уместо ebx, итд.)
; Такође се мења "-f elf " за "-f elf64" у команди грађења.
;
section .data ; секција за иницијализоване податке
str: db 'Hello world!', 0Ah ; стринг поруке са карактером нове линије на крају (10 decimal)
str_len: equ $ - str ; израчунава дужину стринга у бајтовима одузимајући адресу ($ symbol)
                                            ; од str почетне адресе

section .text ; ово је кодна секција
global _start ; _start је улазна тачка и потребан му је глобалан обим да би био видљив
                                            ; linker -    еквавилентан main() у C/C++
_start: ; процедура start
	mov	eax, 4 ; спецификовати sys_write код функције (од векторске табеле ОС-а)
	mov	ebx, 1 ; спецификовати опис фајла stdout -in Линукс, све се третира као фајл,
                                             ; чак и хардверски уређаји
	mov	ecx, str ; померити почетну _адресу_ стринг поруке до ecx регистра
	mov	edx, str_len ; померити дужину поруке (у бајтовима)
	int	80h ; рећи језгру да изврши системски позив који је управо постављен
                                             ; у Линуксу се сервиси траже преко језгра
	mov	eax, 1 ; спецификовати sys_exit код функције (од векторске табеле ОС-а)
	mov	ebx, 0 ; спецификовати код враћања за ОС (0 = све је у реду)
	int	80h ; рећи језгру да изврши системски позив

"Hello world!" програм за Линукс у НАСМ стилу монтаже користећи C стандардну библиотеку

[уреди | уреди извор]
;
; Овај програм ради у 32-битном заштићеном режиму.
; gcc подразумевано веже стандардну C библиотеку

; build: nasm -f elf -F stabs name.asm
; link: gcc -o name name.o
;
; У 64-битном дугом режиму се могу користити 64-битни регистри (rax уместо eax, rbx уместо ebx, etc..)
; Такође променити "-f elf " за "-f elf64" у монтажној команди.
;
        global  main                                ;main мора бити дефинисан као да је компајлиран против C стандардне библиотеке
        extern  printf                              ;декларише коришћење ектерног симбола као што је printf декларисан у другом објектном модулу. Линкер касније решава ово.
        
segment .data ;секција за иницијализоване податке
	string db 'Hello world!', 0Ah ;стринг поруке са новолинијским карактером на крају (10 decimal)
                                                    ;стринг сада реферише на почетну адресу на којој је 'Hello, World' постављен. 

segment .text
main:
        push    string                              ;гурнути адресу првог карактера стринга на стек. Ово ће бити аргумент за printf
        call    printf                              ;зове printf
        add     esp, 4                              ;инкрементира показивач на стек за 4 бришући гурнути аргумент стринга
        ret                                         ;return
[уреди | уреди извор]
section .text
global _start, write
write:
	mov	al, 1 ; write syscall
	syscall
	ret
_start:
	mov	rax, 0x0a68732f6e69622f ; /bin/sh\n
	push	rax
	xor	rax, rax
	mov	rsi, rsp
	mov	rdi, 1
	mov	rdx, 8
	call	write
 
exit: ; just exit not a function
	xor	rax, rax
	mov	rax, 60
	syscall

Коришћење заставног регистра

[уреди | уреди извор]

Заставе су коришћене за поређење у x86 архитектури. Када је поређење урађено између два податка, ЦПЈ поставља релевантну заставу или заставе. Пратећи ово, кондиционе jump инструкције се могу користити за проверу застава и гранање до кода који се треба извршити, на пример:

	cmp	eax, ebx
	jne	do_something
	; ...
do_something:
	; овде се нешто ради..

Заставе се такође корсите у x86 архитектури да се функције или режими упале и угасе. На пример, да се угасе сва маскабилна прекидања, може се користити следећа фунскција:

	cli

Регистри флеша се такође могу директно адресирати. Нижих 8 битова заставиног регистра се може унети у ah користећи lahf инструкцију. Цео флеш регистар се може ставити и склонити са стека користећи инструкције pushf, popf, int (укључујући into) и iret.

Коришћење регистра инструкционог показивача

[уреди | уреди извор]

Инструкциони показивач се зове ip у 16-битном режиму, eip у 32-битном режиму, и rip у 64-битном режиму. Регистар инструкционог показивача показује на меморијску адресу коју ће процесор следећи пут покушати да изврши; не може јој се директно приступити у 16-битном или 32-битном режиму, али секвенца као што следи се може написати да се постави адреса од next_line у eax:

	call	next_line
next_line:
	pop	eax

Ова секвенца инструкција генерише позиционо независтан код јер call узима инструцкионом показивачу релативан тренутни операнд описујући офсет у бајтовима инструкције циљане инструкције од следеће инструкције, у овом случају 0.

Писање по инструкцијском показивачу је једноставно — jmp инструкција поставља инструкциони показивач на циљану адресу, па на пример секвенца као што следи ће ставити садржај eax у eip:

	jmp	eax

У 64-битном режиму, инструкције могу референцирати податке релативне инструкционом показивачу, па има мање потребе за копирањем вредности инструкционог показивача на други регистар.

Спољашње везе

[уреди | уреди извор]