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.
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):
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
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
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.
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.
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.