Jag har sett många inlägg på BX. Jag tror idag att det är ett ”General Purpose Register”. Jag är förvirrad över varför folk kallar det basadressregistret,
- Varför det kallas basadressregistret historiskt.
- Är något av det som fortfarande är relevant idag ?
- Finns det en konvention för att reservera den för basadressering?
Du kan se den kallas det här .
Kommentarer
- Tänker du på det här är inte ’ t exakt en RC-fråga, eftersom den inte ’ inte riktar sig mot någonting om gammal dator – speciellt inte eftersom den ber om relevans idag . Denna fråga skulle vara bättre lämpad på SE: s huvudsida – och en snabb sökning visar att variationer har ställts mycket där.
- Jag tror att en nyckel här är att register på x86 bara är ” mer eller mindre allmänt ändamål ”, du kan använda någon av dem i de grundläggande operationerna men det finns / fanns situationer där du var begränsad till vilka register du kunde använda se.
- En annan viktig punkt är att jämförelse av historisk användning och modern användning är vilseledande när det gäller x86 (jag antar här att kommentaren om ”General Purpose Register” verkligen hänvisar till EBX / RBX än BX). Nuvarande x86 är bakåtkompatibel med 8086, men dagens x86-monteringsspråksprogrammering är väldigt mycket annorlunda jämfört med 8086-programmering (eller till och med 386-programmering); så användningen av BX säger inte nödvändigtvis mycket om användningen av EBX / RBX.
Svar
BX har alltid varit ett av de allmänna registren och det har alltid kallats basregistret (se till exempel 8086 Primer , sidan 19). Det är basregistret eftersom det kan användas i olika baserade adresseringslägen: lagring av en adress i BX och en förskjutning i SI eller DI (käll- och destinationsindexregistrerna) gör att minnet kan nås på BX + SI eller BX + DI ( ibid , sidan 31), eller BX + SI + omedelbar eller till och med BX + omedelbar . Det fungerar också som bas för XLAT
.
BP liknar och stöder alla ovanstående adresseringslägen. Skillnaden mellan BX och BP är att BX är standard för datasegmentet (DS), medan BP är standard för stack-segmentet (SS). (BX och BP har också sina egna specifika instruktioner – t.ex. XLAT
använder BX, ENTER
och LEAVE
använd BP.)
Dessa adresseringslägen finns fortfarande idag, så deras användning är fortfarande relevant, men indexerad och indirekt adressering är tillgängliga med alla allmänna, pekare eller indexregister som börjar med 32-bitars x86 . Medan BX och BP är ”speciella” på 16-bitars x86, eftersom de är de enda register med vilka indirekt eller indexerad adressering är möjlig, så är det inte längre fallet på 32- eller 64-bitars x86 så EBX, EBP, RBX och RBP är inte riktigt så speciella. (BP, EBP och RBP är fortfarande något speciella eftersom de väljer SS som basregister i 16- och 32-bitarsläge och inte kan användas som pekare utan förskjutning, dvs. det finns ingen opcode för MOV AX, [BP]
och MOV AX, [BP+0]
slutar användas istället.)
Det finns ingen konvention som jag känner till för att specifikt reservera användningen av BX för basadressering; om du behöver använda den för basadressering, ställer du in den på rätt sätt och använder den. Om den samtalskonvention som används föreskriver att BX bevaras måste du se till att du tar hänsyn till det (som uppringare eller callee beroende på konventionen och koden du skriver).
Kommentarer
- +2 för tillägg av XLAT / ENTER / LEAVE.
Svar
(Detta är förutom Stephen Kitts svar)
Varför det kallas basadressregistret historiskt.
Tja, det är inte det. Om allt, skulle det vara ”Base Index” (eller bättre Index Base), eftersom det var i original 16 bitar som adresserade det enda registret som kunde läggas till som en ”Base” i all indexerad adressering. Indexeras med SI
eller DI
det vill säga. (* 1)
Denna adressering var symmetrisk med BP
som baspekare. Grundidén var att en array kan pekas på med BX och adresseras via SI
eller DI
utan vidare ado – eller BP när det är inom stack (* 2)
Förutom att det är ett av de ursprungliga allmänna ändamålen två byteregister.
Är något av det fortfarande relevant idag?
Inte riktigt. Åtminstone inte i 32/64 bit-läge.REX
adressering tillåter användning av något av det ”klassiska” registret som (index) bas i 32-bitars läge – förutom BP
/ SP
(* 3). I 64-bitars läge kan 12 av de 16 registren användas på samma sätt (Inte BP
/ SP
/ R12
/ R13
(* 4)).
Med detta sagt kommer ”Long” -läge med 16-bitars skyddade lägeskodsegment . Här används klassisk (16-bitars) kodning tillsammans med 32/64 bitar registerstorlek. BX
bibehåller sin kodningsfördel eftersom SIB
inte behövs. Hur mycket detta ganska glömda läge är relevant kan diskuteras.
Finns det en konvention som reserverar användningen för basadressering?
Inte riktigt. Använd efter behov. När allt kommer omkring är detta församling – det finns ingen konvention som du inte vill ha :))
Det enda som du måste tänka på är att bevara den för din uppringare (såvida det inte uttryckligen inte är gjort)
Du kan se att det heter så här.
Err … lets säg att han inte har fel, men jag rekommenderar att du letar efter en bättre detaljerad beskrivning för att lära dig mer om x86 (Kontrollera Wiki (böcker) eller OSDEV-Wiki ). Eller om det är specifikt för klassisk (16-bitars) x86-programmering, så finns det bara en bok du kan läsa: Steve Morse ” 8086 Primer . 32/64 Bit är ändå annorlunda och måste läras utan dessa klassiska antaganden för att vara riktigt användbara istället för en ryggsäck med specialfall på specialfall.
* 1 – Om du vill tilldela mnemonic namn till de fyra grundläggande två byte-registren, det kan vara
- AX = A ccumulator . Används för A rithmetic (eller A låter den kortaste kodningen)
- BX = B ase. Används som en pekare till data (strukturer)
- CX = C ounter. Används i shift / rotate, string ops och loopar.
- DX = D ata. Används i aritmetik och I / O.
* 2 – Om ”standard” -programmering BP
håller stapelramen igen, så ett index här är alltid ett index i den ramen, såvida inte BP flyttas tillfälligt.
* 3 – SP
kan också användas med SIB
kodning.
* 4 – SP
/ R12
igen med SIB
kodning.
Kommentarer
-
REX addressing allows [using any register in 32-bit mode]
– menade du SIB här? - @ilkkachu Nop. Åtminstone inte så långt jag kommer ihåg. REX gör det möjligt att använda r / m-läge med alla register. SIB behövs bara för SP och R12. Och naturligtvis om du vill använda skalning … eller skruvade jag upp det? Jag måste kolla igen.
- Mm. Jag vet att det ’ är möjligt att använda alla register som pekare i 32-bitars läge, så det kan ’ t vara REX. Egentligen verkar det som om det i 32-bitars läge är bara modr / m-byte tillräckligt för att använda ett enda register som adress, ingen SIB behövs för det fallet (förutom ESP). wiki.osdev.org/…
- @ilkkachu Jup, men du ’ är också rätt, att använda ett register som bas med ett annat som index, SIB behövs. Låt mig dubbelkontrollera detta och korrigera mitt svar. ok?
Svar
BX är det äldsta indexeringsregistret. Normalt skulle ett element i en struktur nås av [BX + constant]
; därav namnet (eller eventuellt kommer namnet från [BX + SI]
; endast BX eller BP kunde användas på vänster sida, och endast SI och DI kunde användas på höger sida).
Jag kunde inte hitta en speciell sak om ebx / rbx förutom att det är det lägsta registret som inte klumpas av en specifik instruktion (mul / div / shl / shr) så det är ett bra ställe att sätta en pekare.
Å andra sidan är [esp + offset] en längre instruktion än [ebp + offset] så rampekarnas eliminering genererar inte alltid kortare kod.
Kommentarer
- Är du säker på att 32-bitars opcodes är kortare? I 16-bitarsläge finns det explicita kodningar för kombinationerna av BX / BP, SI / DI och en 8 eller 16-bitars förskjutning, och andra varianter kan inte kodas; i 32-bitarsläge används generisk registerkodning (EAX / ECX / EDX / EBX / ESP / EBP / ESI / EDI), förutom att 100b (vanligtvis ESP) används för att beteckna en SIB-byte och 101b (vanligtvis EBP ) utan förskjutning används för att beteckna en 32-bitars offset.
MOV EAX, [EBX+9]
tar 3 byte, liksomMOV EAX, [ECX+9]
; med ett extra register behöver du 4 byte. - @StephenKitt: Jag står rättad. Den enda som faktiskt är längre är [esp + x]