Autor Thema: Wie ist das mit den Adressen? Bit beschreiben?  (Gelesen 6538 mal)

YoshiX650

  • Gast
Gespeichert
« am: 05. May 2014, 11:06 »
Erstmal Guten Morgen,
ich habe grade den CMOS-Artikel gelesen und frage mich wie der Computer zwischen den Adressen unterscheidet.
Wenn ich z.B. einfach auf 0x0B zeige bin ich dann wirklich im Statusregister B oder sonst wo?
Und wie beschriftet man einzelne Bits bzw. wie löscht man die? (z.B. Bit 7 beim Keyboard Controller)

LG

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 05. May 2014, 12:25 »
Eine x86-CPU unterscheidet historisch zwei Arten von Adressen, weil es zwei Adressräume gibt: Speicher und I/O. Die Unterscheidung wird durch den Befehl getroffen, mit dem der Zugriff stattfindet; der Adresse selbst sieht man das nicht an. Eine Adresse ist nur eine Zahl und ein Zeiger speichert auch nur diese Zahl.

Wenn du von "0x0B" liest, dann schreibt die CPU diese Zahl auf den Adressbus und sagt an, dass sie jetzt lesen möchte. Das ist eine Anweisung für alle anderen Geräte, von denen jetzt das eine Gerät, was sich bei "0x0B" angesprochen fühlt, die Daten auf den Datenbus legen soll. Bei den meisten (Speicher-)Adressen ist da entweder nichts (Lesen: Müll, Schreiben: passiert nichts) oder Speicher (Lesezugriffe lesen das, was Schreibzugriffe vorher da hingeschrieben haben). (Anmerkung: Grundsätzlich ist das immernoch so, aber die Details sind anders.)

Allerdings kann hinter einer Adresse auch eine Hardware stehen. Dafür ist der I/O-Adressraum da, geht aber auch im Speicheradressraum (MMIO). Dann liest man nicht das, was man da vorher reingeschrieben hat, sondern das, was die Hardware z.B. gerade denkt. Und man schreibt nicht, was man später wieder lesen will, sondern man weist das Gerät z.B. an, etwas zu tun. (Anmerkung: Deswegen sollte man nicht auf wahllose Adressen schreiben. Manche Hardware geht kaputt, wenn man sie falsch anspricht.)

Bits beschriften kann man in C z.B. mit Bitfeldern, oder man benutzt Bitmasken zusammen mit Bitoperationen:
0x80 ist dasselbe wie 1000 0000b, ~0x80 ist das Inverse davon (also dasselbe wie 0x7F oder 0111 1111b). Wenn du 0x80 ODER "irgendwas" machst, dann kommt als Ergebnis "irgendwas" raus, wo zusätzlich das Bit 7 gesetzt ist. Wenn du ~0x80 UND "irgendwas" machst, dann kommt als Ergebnis "irgendwas" raus, wo aber das Bit 7 gelöscht ist.

Direkt Bits adressieren kannst du auf einer x86-CPU nicht. Es gibt aber Mikrocontroller, wo das geht.

YoshiX650

  • Gast
Gespeichert
« Antwort #2 am: 05. May 2014, 14:02 »
Das versteh ich jetzt nicht,
also wenn ich auf 0x0B zeige kann ich auch irgendwas anderes ansprechen als die CMOS?
Wie sprech ich denn dann die CMOS an ohne das ich was falsches anspreche?

Ist das so richtig (mit den Bits)?:
typedef unsigned char  uint;

#define Bit0
#define Bit1
#define Bit2
#define Bit3
#define Bit4
#define Bit5
#define Bit6
#define Bit7

uint* address = (uint*)0x0B;
uint bit;

void read_bit()
{
*address = bit;
}

void change_bit()
{
*address = ((1 << Bit0) | (1 << Bit2 | (0 << Bit7)));
}

LG

Martin Erhardt

  • Beiträge: 165
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 05. May 2014, 20:33 »
Das versteh ich jetzt nicht,
also wenn ich auf 0x0B zeige kann ich auch irgendwas anderes ansprechen als die CMOS?
Wie sprech ich denn dann die CMOS an ohne das ich was falsches anspreche?

Ist das so richtig (mit den Bits)?:
typedef unsigned char  uint;

#define Bit0
#define Bit1
#define Bit2
#define Bit3
#define Bit4
#define Bit5
#define Bit6
#define Bit7

uint* address = (uint*)0x0B;
uint bit;

void read_bit()
{
*address = bit;
}

void change_bit()
{
*address = ((1 << Bit0) | (1 << Bit2 | (0 << Bit7)));
}

LG

Nun ja wenn du den Artikel gelesen hättest wüsstest du, dass über die I/O Ports ins CMOS geschrieben und daraus gelesen wird.

Außerdem liest du mit *address = bit; nicht den Wert an "address" in "bit" ein, sondern schreibst "bit" an "address" und wie schon Svenska angemerkt hat leerst du Bit7 an "address" so:

*address &= ~(1<<Bit7)Außerdem empfiehlt es sich die Makros auch mit den dazugehörigen Werten zu definieren was dann eg. so aus sieht:
#define Bit0 0
#define Bit1 1
#define Bit2 2
#define Bit3 3
#define Bit4 4
#define Bit5 5
#define Bit6 6
#define Bit7 7




Allerdings kann hinter einer Adresse auch eine Hardware stehen. Dafür ist der I/O-Adressraum da, geht aber auch im Speicheradressraum (MMIO). Dann liest man nicht das, was man da vorher reingeschrieben hat, sondern das, was die Hardware z.B. gerade denkt. Und man schreibt nicht, was man später wieder lesen will, sondern man weist das Gerät z.B. an, etwas zu tun. (Anmerkung: Deswegen sollte man nicht auf wahllose Adressen schreiben. Manche Hardware geht kaputt, wenn man sie falsch anspricht.)

:-o Im moment liegen bei mir in x86_64(src/kernel/inc/HAL/x86_64/macros.h):
//-------------------------------------------------------------------------memory-map--------------------------------------------------------------
#define GDT_X86_64 0x114000
#define INIT_PAGE_TBL_ADDR 0x113000
#define INIT_PAGEDIR_TBL_ADDR 0x112000
#define INIT_PAGEDIRPTR_TBL_ADDR 0x111000
#define INIT_PAGEMAPLEVEL4_TBL_ADDR 0x110000
#define BSP_STACK 0x104000
#define TRAMPOLINE 0x007000
und in x86(src/kernel/inc/HAL/x86/macros.h):
#define BSP_STACK 0x104000
#define TRAMPOLINE 0x007000
Ich wusst zwar schon, dass das auf die Dauer nicht so gut ist(falls die addressen nicht frei sind in der Bios memory map), aber die Vorstellung damit Hardware zu beschädigen ist schon - ich nenns mal gruselig.
« Letzte Änderung: 05. May 2014, 20:36 von Martin Erhardt »

Paula

  • Gast
Gespeichert
« Antwort #4 am: 05. May 2014, 21:56 »

*address &= ~(1<<Bit7)

Wird so nicht der Wert 1 in Bit7 geschrieben? Oder Wert 0? (Komm grade durcheinander)

Außerdem empfiehlt es sich die Makros auch mit den dazugehörigen Werten zu definieren was dann eg. so aus sieht:
#define Bit0 0
#define Bit1 1
#define Bit2 2
#define Bit3 3
#define Bit4 4
#define Bit5 5
#define Bit6 6
#define Bit7 7

Sorry, wenn das jetzt wieder falsch ist was ich schreibe, aber ist nicht die 7 bei Bit7 der Wert?
Wenn das falsch ist ... kann mir wer dann mal ein gutes Buch für C/C++/Assembler vorschlagen, das was ich habe ist nicht das wahre.

LG und gute Nacht  :-)

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 06. May 2014, 01:00 »
Das versteh ich jetzt nicht,
also wenn ich auf 0x0B zeige kann ich auch irgendwas anderes ansprechen als die CMOS?
Wie sprech ich denn dann die CMOS an ohne das ich was falsches anspreche?
Dein "0x0B" sagt eigentlich nicht mehr aus als "Dorfstraße 5". Welches Dorf gemeint ist, steht da nicht drin.

Wenn du im I/O-Adressraum auf Adresse 0x0B zugreifst, dann greifst du auf das CMOS zu, deswegen auch die inb()- oder outb()-Funktionen. Das gilt natürlich nur, wenn da auch ein CMOS angeschlossen ist, aber davon darfst du ausgehen. Würdest du ganz normal einen Zeiger auf die Adresse erzeugen und davon lesen, dann liest du ganz normalen RAM. Anders ist es, wenn du einen ganz normalen Zeiger auf 0xB8000 erzeugst und den benutzt: Dann greifst du direkt auf die Grafikkarte zu (sofern vorhanden). Was sich wo befindet, ist in der Memory Map der Plattform dokumentiert. Die ist beim PC aus historischen Gründen recht komplex und außerdem von Chipsatz zu Chipsatz verschieden, deswegen fragst du normalerweise das BIOS (wenn du dem Tutorial aus dem Wiki folgst, dann fragt der Bootloader für dich und legt dir das Ergebnis vor die Nase).

Ist das so richtig (mit den Bits)?
Nein. Lies dir bitte mal den Artikel auf Mikrocontroller.net durch. Da ist das gut beschrieben.

Ich wusst zwar schon, dass das auf die Dauer nicht so gut ist(falls die addressen nicht frei sind in der Bios memory map), aber die Vorstellung damit Hardware zu beschädigen ist schon - ich nenns mal gruselig.
Es ist sehr unwahrscheinlich, dass Hardware kaputt geht. Das war vor 20 Jahren alles noch gefährlicher. :-D Wahrscheinlicher ist es dagegen schon, dass das System schlicht abstürzt, wenn du einem Gerät quer auf die Füße trittst. Moderne Bussysteme (z.B. PCI, USB, ISAPnP) verraten dem System, welche Geräte dort angeschlossen sind. ISA-Geräte muss man aber proben, d.h. ansprechen und gucken, ob da was reagiert. Zuckt da nichts (oder falsch), dann war die gesuchte Hardware nicht angeschlossen, und im schlimmsten Fall hast du die dort angeschlossene Hardware gerade verwirrt. :-)

Paula

  • Gast
Gespeichert
« Antwort #6 am: 06. May 2014, 15:11 »
Denn Artikel hab ich schon gefunden

 

Einloggen