Forum: Mikrocontroller und Digitale Elektronik 8086 Bitmanipulation


von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Hallo!

Weiß einer, ob es im 8086 möglich war, einzelne bits in einem Register 
oder einer 8Bit/1Byte-Speicherzelle direkt zu verändern?
Der/das instruction-set enthält ja nur Befehle wie schieben, UND/Oder, 
usw. die die gesamte Speicherzelle/Register betreffen.

Falls ja, wofür war sowas notwendig?

Mein Stand i.M. ist, dass die Select- und Writeleitungen z.B. im RAM 
immer die gesamte Speicherzelle betreffen, ist dies richtig?

p.s. das 5bit-FLAG-Register natürlich nicht inbegriffen

von S. R. (svenska)


Lesenswert?

Mike B. schrieb:
> Mein Stand i.M. ist, dass die Select- und
> Writeleitungen z.B. im RAM immer die gesamte
> Speicherzelle betreffen, ist dies richtig?

So ein PC/XT nutzt acht einbittige Speicherbausteine parallel, um die 
acht Datenbits für den Bus zu basteln. Das Thema "Speicherzelle" ist 
damit etwas vorbei.

Nein, um ein Bit zu verändern, muss der 8086 einen 
Read-Modify-Write-Cycle durchführen. Das dauert mehrere Takte, kann aber 
als ein Befehl ausgeführt werden.

von Johannes (Gast)


Lesenswert?

Es gibt, abseits von Mikrocontrollern, keinen Grund Befehle zu bauen die 
nur einzelne Bits verändern könnten.

Schon mit dem 286 wurde der Datenbus auf 16bit erweitert. Da werden also 
mindestens 2 Byte gelesen/geschrieben. Heutige CPUs lesen/schreiben 
üblicherweise ganze Cache Lines, d.h. da werden gleich mal 64 oder 128 
Byte am Stück verarbeitet.

von Johannes (Gast)


Lesenswert?

Korrektur: Quark, natürlich hatte schon der 8086 einen 16bit Datenbus. 
Mit dem 386 gibs auf 32bit hoch.

von pittiplatsch (Gast)


Lesenswert?

> Es gibt, abseits von Mikrocontrollern, keinen Grund Befehle zu bauen die
> nur einzelne Bits verändern könnten.

Das ist so pauschal nicht richtig. Es gibt durchaus Hochsprachen
die einen Nutzen aus Befehlen zur Bitmanipulation in ihrer
internen Datenrepraesentation ziehen koennen.
Z.B. LISP.

von Johannes (Gast)


Lesenswert?

Es gibt aber kein System mehr, das sowas praktisch umsetzen kann. 
Aktuelle Mikroarchitekturen würden aus solchen Befehlen auch keine 
Vorteile mehr ziehen.


Ich muss meine Aussage von oben aber noch ein wenig präzisieren:

Bis inkl. zum Pentium 1 wurde der Datenbus immer breiter, die 
Adressierung erfolgte jedoch stets auf Byte-Basis (also alle 
Adressleitungen herausgeführt) und es gab Byte-Select Outputs die 
darüber bestimmt haben, welche Bytes vom Datenbus tatsächlich 
verarbeitet werden sollen.

Vermutlich kommt das noch von der damals häufigen Anbindung des ISA 
Busses, der halt nur 8 oder 16 Bit kann.

Ab dem Pentium 2 wurden dann aufgeräumt. Die unteren 3 Adressleitungen 
wurden weggelassen, damit sind Zugriffe nur noch an 8 Byte Grenzen 
möglich. Dementsprechend müssen auch immer 8 Byte durch.

von Nils Pipenbrinck (Gast)


Lesenswert?

Jein.

Du konntest natürlich ein Bit modifizieren:

  OR al, 1

z.B. setzt das erste Bit in einem Register.

Was es seit dem 8086 gab war der Lock pin. Damit hat der Prozessor 
gesagt, das andere Bus Teilnehmer wie z.B. DMA bitte die Finger vom Bus 
lassen sollen. Das ganze konnte man über das LOCK Prefix des 
Befehlssatzes steuern.

Beispiel:

  LOCK OR [BYTE PTR DI], 1

Führt einen Read-Modify-Write Cycle auf eine Speicherzelle im RAM mit 
gesetztem Lock Pin aus. In der Theorie funktionierte das wie ein 
atomarer Speicherzugriff. Ob sich die anderen Busteilnehmer wirklich 
dran gehalten haben steht auf einem anderen Blatt (meistens schon, es 
gibt aber ISA Karten die sich das gespart haben).

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Nils Pipenbrinck schrieb:
> Jein.
> Du konntest natürlich ein Bit modifizieren:
>   OR al, 1
> z.B. setzt das erste Bit in einem Register.

war dies ebenfalls ein Read-Modify-Write Cycle auf die gesamte 
Registerbreite oder wurde gezielt dieses einzelne bit angesprochen ohne 
die anderen bits anzufassen.
Wenn ja ging dies nur im Register oder auch im RAM, später evtl. auch im 
Cache?

Nils Pipenbrinck schrieb:
> Beispiel:
>   LOCK OR [BYTE PTR DI], 1
> Führt einen Read-Modify-Write Cycle auf eine Speicherzelle im RAM

Solange immer die ganze Wortbreite auf einmal angefasst wird benötigt 
man ja nur eine Select/Writeline für die gesamte Breite
ansonsten müsste es soviel Select/Writelines geben wie die Wortbreite 
ist, also 16 im 8086-RAM bzw 2*8 in den Registern für low und High.

von (prx) A. K. (prx)


Lesenswert?

Mike B. schrieb:
> war dies ebenfalls ein Read-Modify-Write Cycle auf die gesamte
> Registerbreite

Natürlich.

> oder wurde gezielt dieses einzelne bit angesprochen ohne
> die anderen bits anzufassen.

TI hatte mit 990/9900 die einzige mir bekannte Architektur, bei der 
jedes Peripheriebit individuell ansprechbar war. Weil 1 Bit breiter 
I/O Bus.

Allerdings hatte die 9900 keine Byte Selects auf dem Speicherbus, 
weshalb auch Byteoperationen über RMW liefen. Auch bei Registern, denn 
die lagen im RAM.

: Bearbeitet durch User
von heinz (Gast)


Lesenswert?

Gib mal in eine Suchmaschine deiner Wahl "80386 btr bsr"

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

heinz schrieb:
> 80386 btr bsr

"Besides the standard logical, shift, and rotate instructions, there are 
instructions to test bitswithin an operand, to test and set, clear, or 
invert specific bits in an operand,"

Sagt leider nichts darüber aus, ob hier mit Read-Modify-Write Cycle oder 
mit direktem Zugriff auf die einzelnen bits gearbeitet wird/wurde.

Und wenn ja, würde ja ein direkter bit-Zugriff in der ALU dafür 
ausreichen, die Register bräuchten dafür diese Funktionalität gar nicht.
Korrigiert mich bitte wenn ich falsch denke.

Ich bin jetzt nur beim 8086, aber gut zu wissen, dass später 
Erweiterungen in diese Richtung eingebaut wurden.

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

(prx) A. K. schrieb:
> TI hatte mit 990/9900 die einzige mir bekannte Architektur, bei der
> jedes Peripheriebit individuell ansprechbar war. Weil 1 Bit breiter
> I/O Bus.

Gut, da es keine gegenteiligen Angaben gibt, sind wir uns einig, dass 
zumindest im 8086 keine einzelnen bits direkt geändert werden konnten 
sondern sämtliche derartigen Operationen immer in Cycles liefen.
Sowohl in den Registern als auch im RAM.

Ich bedanke mich für die Antworten!

von Jim M. (turboj)


Lesenswert?

Mike B. schrieb:
> Sagt leider nichts darüber aus, ob hier mit Read-Modify-Write Cycle oder
> mit direktem Zugriff auf die einzelnen bits gearbeitet wird/wurde

Mal in die Details einer modernen CPU geschaut?
Du kannst nur Bits setzen/löschen wenn der Register Wert durch die ALU 
gejagt wird.

von c-hater (Gast)


Lesenswert?

Jim M. schrieb:

> Mal in die Details einer modernen CPU geschaut?
> Du kannst nur Bits setzen/löschen wenn der Register Wert durch die ALU
> gejagt wird.

Welche moderne CPU hat denn deiner Meinung nach eine derartige 
Einschränkung?

von MCUA (Gast)


Lesenswert?

> Mal in die Details einer modernen CPU geschaut?
> Du kannst nur Bits setzen/löschen wenn der Register Wert durch die ALU
> gejagt wird.
....nein.....

von Runni (Gast)


Lesenswert?

Nimm nen 8051 oder einen der vielen Derivate, die können einen Teil des 
Speichers Bit weise verändern.

von Johannes (Gast)


Lesenswert?

c-hater schrieb:
> Jim M. schrieb:
>
>> Mal in die Details einer modernen CPU geschaut?
>> Du kannst nur Bits setzen/löschen wenn der Register Wert durch die ALU
>> gejagt wird.
>
> Welche moderne CPU hat denn deiner Meinung nach eine derartige
> Einschränkung?

AMD K7, K8, Bulldozer, Ryzen, Intel P4, Core, alle aktuellen.

Auch für bit set Operationen wird das gesamte Register verändert. Such 
doch ein Beispiel wo es nicht so ist.

von (prx) A. K. (prx)


Lesenswert?

Runni schrieb:
> Nimm nen 8051 oder einen der vielen Derivate, die können einen Teil des
> Speichers Bit weise verändern.

Ohne Byteverarbeitung, direkt im Speicher?

Auch das Bitbanding von ARMs Cortex M ist read-modify-write.

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

Johannes schrieb:
> Korrektur: Quark, natürlich hatte
> schon der 8086 einen 16bit Datenbus.

Stimmt natürlich, allerdings hat IBM den nie in PCs verbaut.

Mike B. schrieb:
> Gut, da es keine gegenteiligen Angaben gibt, sind wir uns einig, dass
> zumindest im 8086 keine einzelnen bits direkt geändert werden konnten
> sondern sämtliche derartigen Operationen immer in Cycles liefen.

Schau dir doch einfach mal den Pinout vom Chip an.

Wenn du da Steuerleitungen findest, mit denen die CPU ein bestimmtes 
Bit adressieren kann, dann ist das ein starkes Indiz für 
Bitadressierbarkeit. Letztere ist notwendig, um einzelne Bits ohne 
Read-Modify-Write zu ändern.

von c-hater (Gast)


Lesenswert?

Johannes schrieb:

> Auch für bit set Operationen wird das gesamte Register verändert.

Natürlich. Aber es wird nicht zwingend die ALU damit befasst! Das ist 
der Punkt.

von Bernd (Gast)


Lesenswert?

c-hater schrieb:
>> Auch für bit set Operationen wird das gesamte Register verändert.
>
> Natürlich. Aber es wird nicht zwingend die ALU damit befasst! Das ist
> der Punkt.
Sondern welche Einheit dann?
Ich dachte immer das L in ALU steht für logic....

von Johannes (Gast)


Lesenswert?

Das lässt sich bei einer modernen CPU gar nicht so genau zurück 
verfolgen, beispiel XOR EAX,EAX. Obwohl das prinzipiell eine logische 
Operation ist, wird innerhalb der CPU ein einfaches LOAD draus. Darüber 
hinaus würde es mich nicht wundern, wenn moderne CPUs eine extra 
Instruktion nur zum nullen eines Registers hätten.

Ein bisschen mehr Präzision wäre bei der Antwort von c-hater aber schon 
wünschenswert gewesen, da sich das zentrale Thema ja nun doch darum 
dreht, ob man Bits einzeln modifizieren kann.

von Johannes (Gast)


Lesenswert?

Noch eine Ergänzung @bernd:

Moderne CPUs sind nicht so einfach gestrickt. Die Frage macht in der 
Form keinen Sinn, am besten schaust du dir mal ein Blockschaltbild dazu 
an. Auf die Schnelle z.B. hier: 
https://en.wikichip.org/w/images/thumb/0/02/zen_block_diagram.svg/1106px-zen_block_diagram.svg.png

von foobar (Gast)


Angehängte Dateien:

Lesenswert?

Der RP2040 unterstützt Einzelbitoperationen auf I/O-Registern, nennt 
sich "atomic write".  Dadurch können beide Cores ohne Spinlocks auf das 
gleiche I/O-Register zugreifen.  Oder auch ISR und main ohne IRQs zu 
sperren.

Das "atomic XOR on write" entspricht dem Schreiben in die PIN-Register 
bei den neueren AVRs.

von Johannes (Gast)


Lesenswert?

Wobei sich hier wieder die Frage stellt, ob das von der CPU unterstützt 
wird oder vom Peripherial.

Da die CPU dafür keine speziellen Instruktionen verwendet wohl eher 
letzteres; für die CPU handelt es sich um normale byte oder word-große 
Writes.

von rbx (Gast)


Lesenswert?

Es gibt auch noch die Flags. Sowas wie ADC DL, 30h.
Und anderswo (z.B. bei SSE-Regisstern) kann man sehr wohl an einzelnen 
Bits herumfummeln, man muss halt nur wissen wie.
Deswegen kann man sich auch darüber streiten, was die Frage soll.

Außerdem wurden ja nicht ganz aus Spiel und Spaß die Datenworte 
eingeführt.

Interessant wäre natürlich auch, wie die jeweiligen Hochsprachen die 
Bitmanipulation implementieren.

von S. R. (svenska)


Lesenswert?

rbx schrieb:
> Interessant wäre natürlich auch, wie die jeweiligen Hochsprachen
> die Bitmanipulation implementieren.

In der Regel mit den vorhandenen CPU-Instruktionen, teilweise optimiert 
auf vorteilhafte Varianten, wenn es unterschiedliche Encodings gibt.

von (prx) A. K. (prx)


Lesenswert?

rbx schrieb:
> Und anderswo (z.B. bei SSE-Regisstern) kann man sehr wohl an einzelnen
> Bits herumfummeln, man muss halt nur wissen wie.

Ohne read-modify-write auch der anderen Bits?

Von internen Ablauf her betrachtet gibt es in einigen x86 Prozessoren in 
Registern auch keine echten 8/16/32-Bit Operationen mehr, obwohl die 
Befehle natürlich noch existieren.

In Operationen auf Teilregistern wird bei diesen stets das gesamte 
Register als Einheit betrachtet. Das kann auch SSE Register betreffen.

Beim Pentium 4 galt das sogar für die Flags. Ein Befehl, der nicht alle 
4 Condition-Flags zusammen beeinflusste, war vom vorherigen Zustand 
dieser Flags abhängig. Das konnte sowas wie INC r gegenüber ADD r,1 
ziemlich ausbremsen.

: Bearbeitet durch User
von Mike B. (mike_b97) Benutzerseite


Lesenswert?

rbx schrieb:
> Außerdem wurden ja nicht ganz aus Spiel und Spaß die Datenworte
> eingeführt.

wohl sicher, weil es effizienter ist oder auch nur billiger war(ist, 
mehrere Takte für einen cycle zu verwenden als zusätzlich 
Steuerleitungen und MUX/DEMUX in Anzahl der Wordbreite in die Register, 
die ALU und den RAM einzubauen und damit wertvollen Platz auf dem Die zu 
verwenden.

Als op bin ich recht überrascht, dass es über die Frage im ersten post 
so viele unterschiedliche AUssagen gibt.

von MCUA (Gast)


Lesenswert?

>>> Auch für bit set Operationen wird das gesamte Register verändert.
>> Natürlich. Aber es wird nicht zwingend die ALU damit befasst! Das ist
>> der Punkt.
> Sondern welche Einheit dann?
> Ich dachte immer das L in ALU steht für logic....
Man kann zwar, muss aber nicht die zentrale ALU bemühen, um ein paar 
Bits in sep. Register zu setzen oder zu veranden.
Es gibt auch Logic ausserhalb dieser ALU.
Es gibt einige MCUs, die das ohne diese zentrale ALU machen können.

von (prx) A. K. (prx)


Lesenswert?

MCUA schrieb:
> Es gibt einige MCUs, die das ohne diese zentrale ALU machen können.

Beispielsweise die erste Mikroarchitektur des Pentium 4. Da gibts eine 
eigene Shift-Unit, die auch Bit- und Bitfeldbefehle handhabt.

von Johannes (Gast)


Lesenswert?

So was haben alle modernen (x86) CPUs als AGU, die ist für einfache 
Adressberechnungen zuständig. (Einfache Addition/Subtraktion, auch mit 3 
Operanden, und Shift in 2er Potenzen z.B. - man schaue sich die 
indirekten Adressierungsmodi oder den LEA Befehl von x86 an)


An den TO: Eigentlich sind sich hier alle halbwegs einig, dass es so was 
in den etablierten Architekturen nicht gibt.

von MCUA (Gast)


Lesenswert?

Jede CPU benötigt eine (mehr oder weniger complexe) AGU.
Das hat aber nichts mit der hier gefragten Bitmanipul. zu tun.

von Johannes (Gast)


Lesenswert?

Indirekt schon.

Der Bulldozer schickt z.B. ein ADD EAX, EBX je nach Verfügbarkeit, auch 
mal durch die AGU. Ebenso einfache Bitoperationen. Die Zuordnung von 
Opcode zu Funktionseinheit funktioniert wegen der Übersetzung in µOps 
nicht mehr so einfach.

Quelle: https://www.agner.org/optimize/microarchitecture.pdf Seite 206

von MCUA (Gast)


Lesenswert?

Ja, die AGU könnte das, ist aber vornehmlich für Adressberechn 
zuständig.
Und die neuen grossen X86er wird man hier wohl eher weniger verwenden.

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Johannes schrieb:
> An den TO: Eigentlich sind sich hier alle halbwegs einig, dass es so was
> in den etablierten Architekturen nicht gibt.

Danke für die (vielen) Infos!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.