Care este scopul registrelor CS și IP în ansamblul Intel 8086? (Programare, X86, Intel, X86 16)

idjuradj a intrebat.

Deci, așa cum spune întrebarea, care este scopul registrelor CS și IP în Intel 8086

Am găsit această explicație:

Segmentul de cod (CS) este un registru de 16 biți care conține adresa segmentului de 64 KB cu instrucțiuni ale procesorului. Procesorul folosește segmentul CS pentru toate accesările la instrucțiunile la care face referire registrul indicator de instrucțiuni (IP). Registrul CS nu poate fi modificat direct. Registrul CS este actualizat automat în timpul instrucțiunilor far jump, far call și far return.

și aceasta pentru IP:

Pointerul de instrucțiuni (IP) este un registru pe 16 biți.

Nu prea înțeleg ce înseamnă în esență acest lucru, așa că, dacă cineva ar putea oferi o explicație mai „vie”, ar fi minunat 🙂

6 răspunsuri
utilizator1666959

Din moment ce Instruction Pointer (IP) este pe 16 biți înseamnă că poți avea doar 64k instrucțiuni (2^16), ceea ce nu era mult nici măcar în anii ’80. Așa că pentru a extinde spațiul de adresare ai un al doilea registru care adresează blocuri de 64k. Ați putea considera cs:ip împreună ca fiind un singur registru de 32 de biți care este capabil să adreseze 2^32 de octeți…adică 4G, ceea ce se obține pe un procesor care folosește adrese de 32 de biți. 8086 folosea adrese de 20 de biți, deci puteai accesa 1M de memorie.

Comentarii

  • Și unde este folosit CS? Am citit un pic despre segment și offset și pot spune că am înțeles mecanismul segment/offset. –  > Por idjuradj.
  • Am extins întrebarea mea: Și unde se folosește CS? Am citit puțin despre segment și offset și pot spune că am înțeles mecanismul segment/offset. Dar, unde este folosit registrul Code Segment? Din câte știu eu, există segmentul de date, segmentul de stivă, segmentul extra și segmentul de cod menționat? Și din moment ce CS este „împerecheat” cu registrul IP și folosește cei 4 biți ai acestuia pentru offset, celelalte registre sunt, de asemenea, împerecheate cu registrele IP sau fiecare dintre aceste 4 registre de segment are propriul său registru de offset? –  > Por idjuradj.
  • De fiecare dată când o nouă instrucțiune este preluată de procesor (de la IP), cs este utilizat implicit. CS indică segmentul de cod al programului, iar adresa fizică unde se află următoarea instrucțiune este asamblată în mod transparent. Și, în mod similar, de fiecare dată când accesați o bucată de date (mov ax, [1234] — 1234 este implicit prefixat de ds) care rezidă în ds. Nu puteți face mare lucru cu CS, dar când faceți un salt lung este folosit. –  > Por user1666959.
  • cs:ip împreună ca un singur registru de 32 de biți care este apoi capabil să adreseze 2^32 octeți . Acest lucru este greșit. CS:IP împreună, chiar și pe un procesor pe 32 de biți în modul real, este încă capabil să adreseze folosind doar 20 de biți.(Tehnic vorbind, pe un 286 sau 386+ CS:IP este capabil să adreseze de la 0 la 0x10FFEF, având în vedere că 0xFFFFFF_0xFFFFFF=(0xFFFFFF<<4)+0xFFFFFF = 10FFEF. Pentru a adresa 4gb de memorie pe un 386, registrul IP a fost extins la registrul de 32 de biți EIP, care poate adresa 4gb. –  > Por Michael Petch.
  • Sunt de acord cu comentariul lui Michael Petch. CS:IP pe 16 biți poate adresa cel mult 0x10FFEF, pe baza definiției lor. Adresa de pornire pe care o adresează CS este fixă, care este valoarea sa multiplicată cu 0x10. –  > Por robbie fan.
kiran james

Adresa fizică este calculată din 2 părți. i) adresa de segment.ii) adresa de offset.CS(code segment register) este utilizat pentru a adresa segmentul de cod al memoriei, adică o locație din memorie unde este stocat codul. IP (indicator de instrucțiuni) conține deplasarea în cadrul segmentului de cod al memoriei. Prin urmare, CS:IP este utilizat pentru a indica locația (adică pentru a calcula adresa fizică) a codului în memorie.

Ciro Santilli新疆棉花TRUMP BAN BAD

Instrucțiunea care va fi executată în continuare este cea de la adresa de memorie egală cu:

16 * CS + IP

Acest lucru permite adresarea a 20 de biți de memorie, în ciuda faptului că registrele au o lățime de numai 16 biți (și creează, de asemenea, două moduri distincte de codificare a majorității adreselor).

Efectul lui CS este analog cu cel al celorlalte registre de segment. De ex, DS incrementează accesările de date (care nu specifică un alt registru de segment) cu 16 * DS.

CS

Instrucțiunile care modifică CS sunt:

  • ljmp (salt îndepărtat)
  • lcall (far call), care împinge ip și cs pe stivă, apoi face salturi îndepărtate
  • lref (far return), care inversează apelul îndepărtat
  • int, care citește IP / CS din tabelul vectorilor de întreruperi
  • iret, care inversează un int

CS nu poate fi modificat de către mov ca și celelalte registre de segment. Încercarea de a-l codifica cu identificatorul standard pentru CS, ceea ce GNU GAS 2.24 face fără să se plângă dacă scrieți:

mov %ax, %cs

conduce la o excepție de cod invalid atunci când este executat.

Pentru a observa efectul CS, încercați să adăugați următoarele la un sector de pornire și să îl rulați în QEMU, așa cum este explicat aici https://stackoverflow.com/a/32483545/895245

/* $1 is the new CS, $1f the new IP. */
ljmp $1, $after1
after1:
/* Skip 16 bytes to make up for the CS == 1. */
.skip 0x10
mov %cs, %ax
/* cs == 1 */

ljmp $2, $after2
after2:
.skip 0x20
mov %cs, %ax
/* cs == 2 */

IP

IP crește automat ori de câte ori este executată o instrucțiune cu lungimea codificării acelei instrucțiuni: acesta este motivul pentru care programul avansează!

IP este modificat de aceleași instrucțiuni care modifică CS, precum și de versiunile neafară ale acestor instrucțiuni (cazul cel mai frecvent).

IP nu poate fi observată direct, deci este mai greu să te joci cu ea. Consultați această întrebare pentru alternative: Citirea directă a contorului de program

Comentarii

  • În exemplul pe care l-ați oferit, se poate $1 și $2 să fie valori arbitrare (valide)? Deoarece $after1 și $after2 sunt valori relative la IP-ul curent, nu trebuie să fie $1 și $2 nu trebuie să fie 0 pentru ca saltul să fie corect (dacă registrele de segment nu sunt 0, atunci 16*CS+IP nu se va potrivi cu eticheta, deoarece $after a luat deja în calcul diferența)? –  > Por tartaruga_casco_mole.
  • @tartaruga_casco_mole (nick frumos) Cred că $after nu este relativ, ci absolut, de ex. EA cd codificarea de la c9x.me/x86/html/file_module_x86_id_147.html iar GNU Gas decide corect tipul de relocare în funcție de codificarea exactă a instrucțiunilor care urmează să fie utilizate. Vă sugerez să confirmați acest lucru din dezasamblare. –  > Por Ciro Santilli新疆棉花TRUMP BAN BAD.
Amrish Ak

din moment ce procesorul 8086 folosește o adresare pe 20 de biți, putem accesa 1MB de memorie, dar registrele lui 8086 sunt doar pe 16 biți, astfel încât pentru a accesa datele din memorie combinăm valorile prezente în registrele segmentului de cod și în registrele indicatorului de instrucțiuni pentru a genera o adresă fizică, acest lucru se face prin mutarea valorii CS pe 4 biți spre stânga și apoi prin adăugarea ei cu valoarea IP.

EXEMPLU:

valoarea CS este 1234Hex(hexa decimal).

valoarea IP este 5678Hex

acum, valoarea CS după mutarea a 4 biți spre stânga este 12340Hex, apoi, după adăugarea cu valoarea IP, este 179B8Hex, care este adresa fizică.

zeimer

Odată ce ați scris .code în textul programului de asamblare, acel .code indică valoarea cs. orice comandă ulterioară sau anterioară în fișier va fi adresată conform cs:ip , unde ip este o valoare de decalaj de la cs.

Desigur, trebuie să țineți cont de faptul că compilatorul de asamblare va converti mai întâi textul în instrucțiuni de cod mașină.

masood qazi

Registrul IP – IP este pointerul de instrucțiuni. Funcția sa este aceeași cu cea a PC (program counter) din alte microprocesoare, și anume de a indica următoarea instrucțiune care urmează să fie preluată de unitatea BIU pentru a fi introdusă în unitatea EU.