Autor Thema: PM mode  (Gelesen 4126 mal)

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« am: 20. August 2004, 13:20 »
Hallo,

so habe mal so nen paar Fragen zum Tutorial vom TeeJay zum Thema PM
mov        eax, cs        
    mov        ds, ax        
       
    shl        eax, 4                
                               
    mov        [CODE_Desc+2], ax    
    mov        [DATA_Desc+2], ax    
    shr        eax, 16                
    mov        [CODE_Desc+4], al
    mov        [DATA_Desc+4], al

    mov        eax, cs                
    shl        eax, 4
    add        eax, NULL_Desc

    mov        [Base], eax            
    mov        [Limit], WORD gdt - NULL_Desc -1    

    lgdt    [gdt]                ;GDT laden


sind eigentlich recht triviale Sachen die ich bisher nicht verstanden habe, und komme grad irgendwie auch net weiter.. Vielleicht kann mir da jemand etw. helfen

Warum nimmt man für den Code - Deskriptor die gleiche Adresse wie für den Daten - Deskriptor ?

und dann würd ich gern wissen, was man genau mit den Rechnung bezweckt. Ich weiß schon wofür man die Befehle shr und shl verwendet nur weiß ich im MOment nicht warum wir denn den Wert aus CS verwenden und nicht etwa aus DS. Wenn mir jemand erklären könnte wie die Berechnung gemacht wird, wäre ich sehr dankbar!


Grüße
Vamp

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #1 am: 20. August 2004, 16:47 »
Auch wenn ich TJ's Variante im Tut etwas kompliziert finde und das ja selbst nicht mache so...naja ich versuchs mal zu erklärn. Die GDT befindet sich bei TJ mit in dem "Kernel" also in dem Segment wo auch CS hinzeigt, da nehmen wir CS einfach und packen es nach DS damit wir an die richtige Stelle schreiben. Dann shiften wir um 4 nach links im Prinzip also eine Division durch 16, damit haben wir dann einen Teil der Basisadresse, das muss an die angebene Stelle. Dann um 16 nach rechts, das gibt den nächsten Teil der Basis, der kommt an die nächste Stelle, es könnte zwar noch einmal gemacht werden da die Basis aus noch einem Byte besteht, wie man aus dem Deskriptoraufbau erkennen kann aber ist hier nicht notwendig für den Anfang. Der folgende Teil besimmt die Basis der GDT im Speicher, im Prinzip auf die Selbe Art CS<<4=lineare Adresse+Adresse des Null Deskriptors, das Limit erklärt sich von selbst denke ich.
So CS verwendet man deshalb weil: wir nicht unbedingt wissen wohin ds bisher zeigte, aber da CS ja im ausführenden Segment liegen muss sind wir sicher das wir richtig sind.
Daten und Code haben die selbe Adressen weil wir ganz einfach den Anfang der Segmente gleich haben wollen, und so nicht umrechnen müssen. Denn der Bereich in den du Daten schreibst wird relativ zum Segmentanfang berechnet.
Beispiel: wenn dein Segment die Basis 15 hat und du nach 3 schreibst schreibst du theoretisch nach 18. So wenn dein Codesegement bei 18 beginnen würde würdest du damit Code überschreiben  deshalb macht man es gleich, C-Compiler gehen auch vom flachen Addressraum aus, also das alle Segmentregister auf den Selben Bereich zeigen.
Ich hoffe das war nicht zu wirr und hat geholfen.
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 23. August 2004, 10:25 »
ähm.. mal ne Frage, wenn ich nach links schifte ist dies doch ne Multiplikation

10b   => 2d
4 Position nach links schiften:
100000b => 32d
oder verwechsel ich das gerade ???

die andere Frage eine ADresse ist doch 20 Bit groß im Real Mode da aber das Segment CS nur 16 Bit ist, wird das ja noch woanders hingeschrieben, glaub das dürfte IP sein oder ?
also wenn ich dann 4 nach links schifte ist in AX ja dann die Adresse ohne die 4 vorderen Bit und wenn ich danach 16 Bits nach rechts shifte habe ich doch in al 0 oder nicht ???

Vielleicht stelle cih mich auch einfach nur zu dumm an, aber find das irgendwie unlogisch..

Grüße
Morti

lobmann

  • Beiträge: 243
    • Profil anzeigen
    • http://www.fallek.de.vu
Gespeichert
« Antwort #3 am: 23. August 2004, 19:30 »
Jo aber in den Segmentregister sind ja immer die oberen 16-BIT der linearen Adresse und der Offset wird einfach drauf gerechnet.
Man kann doch nem alten Mann nicht in den Bart spucken und sagen es hat geschneit

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #4 am: 23. August 2004, 19:47 »
im RM fängt alle 16 Byte ein neues Segment an, ich denk das weisst du also ein CS=0 fängt bei 0 an ein CS=1 bei 16, linear gesehen. So dazu kommt der Offset also um die 16 Byte auch nutzen zu können brauchts nur 4 Bit also 16Bit Segement+4Bit Offset=20Bit linear. Ich versuchs mal mit einem Rechenbeispiel für den Code oben:
Sagen wir wir haben im CS Segment 0x3E0F (warum auch immer) das kommt nach eax also eax=0x00003E0F
Dann shift um 4 nach links eax=0x0003E0F0 (Das wäre dann die lineare Startadresse des Segements) dann nehmen wir das was in ax drin ist und schmeissen es an die richtige stelle im Deskriptor, also ax=E0F0
so jetzt eax um 16 nach rechts vorher eax=0x0003E0F0 nachher eax=0x00000003 das kommt dann an die nächste stelle.
Soviel zu deiner 2./3. Frage glaub ich hoffe das ist soweit klar. 1.Frage ja linkshift=Multiplikation rechtsshift=division
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 24. August 2004, 12:55 »
Solangsam wir mir einiges klar und verstehe jetzt auch diese ADressierungsart...

jetzt habe ich nur noch eine Frage. Ist es beabsichtigt, dass die OFFSET Adresse nicht verwendet wird ?? Oder ist es nur eine ungenauigkeit ?? Weiß dass die OFSET im Prinzip nur der Zeilennummer des Codes entspricht, will aber lieber nochmal fragen, damit ich alles genaustens weiß :)

ansonsten DANKE

Gruß Vampire

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #6 am: 24. August 2004, 19:56 »
Wir sind doch dazu da zum Verständniss zu verhelfen^^
In diesem Falle wird der Offset nicht benötigt, wo sollte der auch hingeschrieben werden;) wir wollen nur wissen wo das Segment anfängt mehr nicht.
Es ist nicht ganz richtig das Offset=Zeilennummer ist, denn manche Opcodes (AsmBefehle) brauchen 1 Byte andere 2 oder 3 usw, bis zu 15 Byte kann ein einziger Opcode sein! also Zeile 3 heisst nicht das du 3 Byte im Code stehst, und nach 15 Byte bist du nicht in der 15 Zeile, jedenfalls nicht zwangsläufig, das hängt immer vom Opcode ab. Wenn du z.B. eine Zahl in ein Register schieben willst, also über mov dann brauchst du bis zu 5 Byte (oder sogar 6 will nix falsches sagen), 1Byte Codiert den mov Befehl, gibt an wohin und wieviel also z.b eax ebx usw und dann die Zahl selbst die dann bei eax ja 4 Byte gross sein muss, also bist du 5 Byte weiter aber nicht in Zeile 5 sondern in Zeile 1, der näcshte Befehl ist dann ein cli der nur ein Byte verbraucht, also Zeile 2 Byte 6. Du siehst Offset und Zeilennummer hat nix miteinander zu tun, sonst wäre ja die Offset Berechnung seeeeehr einfach, ein Assembler muss erst den Code assemblieren um zu wissen an welcher Stelle ein String beispielsweise steht. Das macht schon ein gutes Stück Programmierarbeit
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

Vampire

  • Beiträge: 52
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 25. August 2004, 10:19 »
ok nochmal danke, das ist klar dass Offset net ganz den Zeilenummern entspricht, dass ist mir nach dem Post auch wieder eingefallen (immer diese Alzheimer). Doch hat mich schon recht weitergebracht deine Hilfe !!! Danke

Grüße
Morti

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #8 am: 25. August 2004, 17:45 »
Zu irgendwas muss ich doch gut sein^^
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

 

Einloggen