Forum: PC-Programmierung Bitmanipulation


von Appel0 A. (Gast)


Lesenswert?

Hallo,

ich soll von einer 8 bit Zahl die Bits 2-4 von rechts als Zahl zwischen 
0 und 7 interpretieren und das Ergebnis dann einer Variablen zuweisen.

Leider verstehe ich den Eintrag hier über Bitmanipulation nicht 
wirklich.
Würde mich über Hilfe freuen und hoffe ich hab die Frage deutlich genug 
ausgedrückt.

von Dennis S. (eltio)


Lesenswert?

Welchen Eintrag verstehst du nicht?
Wie ist dein Ansatz?

Generell brauchst du ja nur die entsprechenden Bits zum LSB schieben und 
anschließend die nicht notwendigen Bits ausmaskieren. Am besten 
schreibst du dir das mal auf (x sind "dont care", 1 die relevanten 
Bits):
1
xxx111xx --> Wie musst du schieben?

Gruß
Dennis

von Jonas B. (jibi)


Lesenswert?

Hallo,

du wirst wohl Bits maskieren müssen (Bits 2-4), anschließend schieben 
(von Stelle 2-> Stelle 0) und dann einmal neu interpretieren...
Das geht mit Bitoperationen...
Den Rest kriegst du selber raus :)

Gruß J

: Bearbeitet durch User
von Paul B. (paul_baumann)


Lesenswert?

Jonas B. schrieb:
> du wirst wohl Bits maskieren müssen (Bits 2-4), anschließend schieben

Na, lieber anders herum: Erst den Kram richtig hinschieben und dann die 
nicht benötigten Bits "flachdrücken". Dann kann man in Ruhe den 
verbliebenen Stumpf in eine neue Variable tun.

(Ich stelle mir die Sache gerne "mechanisch" vor, wie man sieht)

MfG Paul

von Karl H. (kbuchegg)


Lesenswert?

Appel0 A. schrieb:
> Hallo,
>
> ich soll von einer 8 bit Zahl die Bits 2-4 von rechts als Zahl zwischen
> 0 und 7 interpretieren

ps. du musst da nichts wortwörtlich 'interpretieren'. Wenn die Bits an 
der richtigen Stelle sind, dann ist das automatisch eine Zahl.
Der Hinweis, dass du das als Zahl zwischen 0 und 7 auffassen sollst, ist 
nichts anderes als der Hinweis, dass du die bewussten Bits ganz nach 
rechts schieben musst. Das ist sozusagen das Gegenstück, wie wenn ich 
dir sage, dass du von der Zahl 5623 die Zehner und die Hunderter 
extrahieren sollst (x62x) und das ganze dann als 2-stellige Zahl 
zwischen 0 und 99 interpretieren sollst. Aus x62x wird dann die Zahl 62. 
Dazu musst du x62x um 1 Stelle nach rechts verschieben (damit aus x62x 
das neue x62 wird) und dann die nicht gebrauchten führenden Stellen 
loswerden, damit aus x62 letztendlich 62 wurde. Der Hinweis auf den 
Zahlenumfang des Zielbereiches ist eher ein Hinweis darauf, welche Teile 
nicht benötigt werden und wie das Ergebnis zu verschieben ist.

von xy (Gast)


Lesenswert?

y=(x>>2)&7;

von Dennis S. (eltio)


Lesenswert?

xy schrieb:
> y=(x>>2)&7;

Das musste ja kommen.

von Rolf M. (rmagnus)


Lesenswert?

Appel0 A. schrieb:
> hoffe ich hab die Frage deutlich genug ausgedrückt.

Du hast gar keine Frage gestellt.

von RAX (Gast)


Lesenswert?

In Assembler könnte das so aussehen:

Angenommen, die 8 Bit-Zahl steht im AX-Register, genaugenommen im 
unteren Teil von AX, also in AL.
Eine Multiplikation mit 2 schiebt die ganze (binäre) Zahl um eine Stelle 
nach vorne.

z.B. 0100b ist 4 und das mal zwei ist 8 also 1000b
Da man multiplizieren kann, ließe sich auch mit dem Befehl LEA 
herumprobieren.
siehe http://dflund.se/~john_e/gems/gem0009.html (Titel: LEA a power 
command)

Um  "Alignment" im Register zu erreichen, kann man mit 4 multiplizieren.
Dadurch wird der Inhalt von AX um zwei Stellen nach links geschoben.

Der gefragte Inhalt liegt jetzt oberen Teil vom AL-Register.
Da nützt er aber nicht unbedingt viel. Wie kommt man jetzt passend in 
den unteren Teil im AH Registerteil?

Umgekehrt kann man jeweils, um die gewünschten Stellen nach rechts zu 
bekommen, mit 2 dividieren. Mit 2 dividieren heißt, die ganze Zahl um 
eine Stelle nach rechts schieben. Aus 1000b wird dann 0100b.

Mit dem Assemblerbefehl SHR AL, 2 (Shift Right) wird die Zahl in AL um 
zwei Stellen nach rechts geschoben (aber durch 4 geteilt). Die linke 
Seite wird normalerweise mit Nullen aufgefüllt. Bei einem arithmetischen 
Rechtsshift bleibt das Vorzeichen (die 1 am Anfang bei negativen Zahlen 
erhalten).

Um den Rest Bits loszuwerden, die noch unpassend im AX-Register 
abhängen, hilft eine logische Operation weiter xxxx xyyy -> 0000 0111.

Also: AND AL, 07.

Für ASCII-Ausgabe (Interrupt) bräuchte man nur noch 30h Draufzählen.

Siehe hierzu auch: 
http://andremueller.gmxhome.de/befehle.html#bitschiebebefehle

Was auch noch ginge, ist z.B. mit dem Assemblerbefehl BT (Bittest) 
herumzumachen. BT speichert das Prüfergebnis im Carryflag.
Dieses kann man ausgeben mit dem ADC Befehl, also Add Carry wohin und 
was dazu?
1
BT eax, 4                ; Ist Bit Nummer 4 von rechts gesetzt?
2
MOV dl, 0                ; dl initialisieren
3
ADC dL, 0                ; Ausgabe des Übertrags in dl, aber sonst nichts. 
4
LEA edx, [edx + edx *1]  ; zum Bits nach links schieben, Platz machen.
5
BT eax, 3
6
ADC dL, 0
7
LEA edx, [edx + edx *1]; 
8
BT eax, 2
9
ADC DL, 0
So (oder so ähnlich) hätte man dann alle drei Bits zum Ausgeben als 
Variable zusammen.

von Wolfgang (Gast)


Lesenswert?

Appel0 A. schrieb:
> Leider verstehe ich den Eintrag hier über Bitmanipulation nicht
> wirklich.

Dann mach es einfach direkt, ohne den Eintrag

von F. F. (foldi)


Lesenswert?

Karl H. schrieb:
> nichts wortwörtlich 'interpretieren'.

Es ist einfach immer wieder toll zu lesen, wie du die Sachen so einfach 
und verständlich und in wenigen Worten erklärst.

Du weißt ja noch ... das Buch. :-)

Ganz ehrlich, Karl Heinz, ich bin ein absoluter Fan von deinen 
Erklärungen zur Programmierung. Im Anfang haben mir deine Beiträge oft 
riesig weiter geholfen. Obwohl ich selten selbst gefragt hatte, so habe 
ich doch alle Threads mit diesem Inhalt gelesen.

von Appel0 A. (Gast)


Lesenswert?

Danke für die vielen Antworten, war auch was hilfreiches dabei (y)

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.