Autor Thema: Speicherzugriffe  (Gelesen 13394 mal)

bscreator

  • Gast
Gespeichert
« am: 09. December 2011, 17:22 »
Hallo,

ich möchte an die Speicherstelle 0800:0100 den Wert 1 schreiben

mitSeg dw 0x0800
Off dw 0x0100
...
mov bx, Seg
mov es, bx
mov bx, Off
mov es:bx, 1
funktioniert alles einwandfrei, aber bei dem CodeSeg dw 0x0800
...
mov bx, Seg
mov es, bx
mov es:0x100, 1
schreibt er irgendwo anders hin die 1, nur nicht an 0800:0100.

Kann ich nur mit mov es:bx, 1 den Wert der Speicherstelle ändern, oder geht das auch ohne BX als Offsetregister ?

Vielen Dank,
bsc



kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 09. December 2011, 17:50 »
Fehlen da nicht ein paar eckige Klammern?

Für welchen Assembler soll das überhaupt geschrieben sein? nasm assembliert das so nicht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 09. December 2011, 21:11 »
Hallo,


ich finde ja das da noch die Angabe fehlt wie groß die Speicherstelle eigentlich ist (Byte/Word/DWord/...), ich könnte mir vorstellen dass das Assemblieren auch deswegen scheitert.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 10. December 2011, 13:35 »
Seg dw 0x0800
...
mov bx, Seg
mov es, bx
mov dword ptr [es:0x100], 1

Alternativ kannst du den Opcode auch manuell schreiben, auch wenn das nicht so wahnsinnig angenehm ist.
Seg dw 0x0800
...
mov bx, Seg
mov es, bx
db 0x26, 0xC6    ; Use ES, MOV r/m8, imm8
db 0x06            ;r/m8=add16 (modR/M byte)
dd 0x100           ; add16=0x100
db 1                 ; imm8=1
« Letzte Änderung: 10. December 2011, 18:25 von Sannaj »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 10. December 2011, 14:01 »
Ich würde sagen es muss mov bx, [Seg] heißen, Seg ist doch nur ein Label.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bscreator

  • Gast
Gespeichert
« Antwort #5 am: 10. December 2011, 14:22 »
So, habs jetzt nochmal anders versucht:
Off dw 0x0100
W_ok db 'Werte in Ordnung',0
...
mov bx, 0x0800
mov es, bx
mov bx, 0x0100
mov ax, 0x0001
mov [es:bx], ax  ;Den Wert 0x0001 an Speicherstelle 0800:0100 schreiben
cmp [es:Off], ax ;Prüfen, ob Werte gleich
je Werte_ok
hlt

Werte_ok:
mov si, W_ok
call putstr
hlt
putstr ist definiert und funktioniert. Beim Ausführen mit Bochs wird allerdings keine Meldung ausgegeben => Werte stimmen nicht überein
Wenn die Zeile cmp [es:Off], ax durch cmp [es:0x0100] ersetzt wird, funktioniert alles wunderbar.

Warum funktioniert das ganze mit cmp [es:Off], ax nicht ?
« Letzte Änderung: 10. December 2011, 14:27 von bscreator »

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 10. December 2011, 17:04 »
Hallo,


Warum funktioniert das ganze mit cmp [es:Off], ax nicht ?
Off ist doch nur ein Label und ich vermute der Assembler wird einen Befehl erzeugen der an das Offset von 'Off' (also das Offset von "dw 0x0100") aber über das Segmentregister ES einen Speicherzugriff tätigt und das wird nicht das sein was Du willst. Was Du beabsichtigst ist das der Befehl erst den Wert von 'Off' liest (also die 0x0100 aber dazu wird dessen Adresse benötigt) und dann diesen Wert als Offset für den Zugriff über ES nutzt aber das wären ja zwei verschiedene Speicherzugriffe an zwei verschiedene Adressen in einem Befehl und das kann x86 nicht (jedenfalls nicht so). Dein Befehl würde funktionieren wenn 'Off' ein define ist so das der Assembler den Befehl "cmp [es:0x0100],ax" sieht, dann würde auch "mov bx,Off" funktionieren (und Du könntest Dir die 2 Byte Speicherverbrauch sparen).


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

bscreator

  • Gast
Gespeichert
« Antwort #7 am: 10. December 2011, 20:24 »
Bin eben grad auf folgenden Abschnitt im NASM-Manual gestossen:
Zitat
For example :
mov ax, wordvar

Loads AX with the address of the variable 'wordvar'
Damit hast du vollkommen Recht, erik.vikinger.
Habs mit %define Off 0x0100 versucht und damit funktionierts wunderbar.

Also springt der Assembler, bei Off dw 0x0100 zu der Adresse im Datensegment, in welcher Off definiert wurde, oder ?

Vielen Dank und viele Grüße,
bsc
« Letzte Änderung: 10. December 2011, 20:35 von bscreator »

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 11. December 2011, 14:16 »
Hallo bscreator,


sorry wenn ich das so direkt schreibe, aber ich persönlich bin der Meinung Du solltest Dich erst mal mit dem Datenblatt von Deiner CPU beschäftigen damit Du eine konkrete und möglichst detaillierte Vorstellung davon entwickelst was die Befehle eigentlich wirklich tun und welche Art Parameter sie alles nutzen können. Ich weiß nicht ob es für Assembler heute noch anständige Bücher gibt aber in meinem Regal steht noch eines aus der 286-Zeit (es handelt auch nur vom Real-Mode) welches in gutem Deutsch sehr detailliert auf die Funktionsweise der einzelnen Befehle eingeht und erklärt wie man diese so kombiniert das daraus ein Programm entsteht das die gewünschte Funktionalität hat. Ich kann Dir da leider wirklich kein aktuelles Buch empfehlen, vielleicht hat hier ja jemand anderes einen guten Tipp, aber da Weihnachten kurz bevor steht solltest Du sowas mal in Erwägung ziehen (zusätzlich zum CPU-Datenblatt, aber das ist eigentlich nur ein Nachschlagewerk für jemanden der im wesentlichen weiß was er tut).


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

bscreator

  • Gast
Gespeichert
« Antwort #9 am: 11. December 2011, 23:00 »
OK,
danke für den Beitrag, aber der hat meine Frage zu 0% beantwortet

Grüße,
bsc

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 12. December 2011, 01:10 »
Andersrum: Du kommst immer wieder mit ähnlichen (Grundlagen-)Fragen an und wunderst dich, dass dir regelmäßig empfohlen wird, die Grundlagen für das, was du möchtest zu schaffen? Oder zu überdenken, was du eigentlich schaffen möchtest?

Wer Assembler als Hauptsprache nimmt, sollte sowohl die CPU-Architektur als auch den Assembler genauestens kennen. (Und selbst schuld ist derjenige auch.) Deine Fragen lassen darauf schließen, dass du nicht genau weißt, was du da tust. Daher stimme ich erik zu: Schaff dir die Grundlagen an, dann erübrigen sich auch die Fragen.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 12. December 2011, 10:38 »
Also springt der Assembler, bei Off dw 0x0100 zu der Adresse im Datensegment, in welcher Off definiert wurde, oder ?
Der Assembler springt gar nicht, sondern die CPU. Und beim ersten sagst du der CPU, sie soll zum Label Off springen, was sie dann auch tut. Da steht natürlich kein Code, sondern ein Word mit dem Inhalt 0x100, und anschließend eben, was da nach diesem Label sonst so kommt. (Stimmt nicht, siehe Erik. Du springst gar nicht und ich hab mir den Code nicht angeschaut. In Wirklichkeit greifst du auf einen Pointer auf 0x100 statt auf 0x100 selbst zu.)

Oder machen wir es kurz: Wenn du es benutzen willst, dann lern Assembler erstmal. Es gibt dafür Tutorials.
« Letzte Änderung: 12. December 2011, 12:25 von taljeth »
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 12. December 2011, 11:02 »
Hallo bscreator,


Sorry, das ich einfach so Deine Frage ignoriert hatte. Wie taljeth schon erklärte: der Assembler ist ein Programm und spring daher nirgends hin und da die CPU fest mit dem Mainboard verbunden ist springt diese auch nicht einfach irgendwo hin sondern wenn dann wird der nächste Befehl von einer anderen Stelle geholt aber da Du gar keinen JMP-Befehl in Deinem Code hast ist auch das nicht die richtige Antwort. Was Du wissen möchtest ist das Off nichts weiter als ein Label ist und der Assembler beim Generieren der Befehle dieses Label gegen die Adresse von dem was als nächstes nach diesem Label kommt, also vom "dw 0x0100", austauscht (eigentlich macht das auch erst der Linker aber so weit wollen wir das jetzt nicht treiben), bei x86 genau genommen nur gegen das Offset und da Du wohl für den Real-Mode programmierst wird auch immer noch das Segment benötigt das Du auch passend angeben musst. Wenn Du in Deinem Assembler-Quell-Text ordentliche Sektionen anlegst und dem Assembler sagst über welche Segment-Register er diese Sektionen erreichen kann dann könnte um die 0x0100 nach BX zu laden theoretisch sogar ein "mov bx,[Off]" (ohne Segmentregister) funktionieren aber in Deinem Fall dürfte "mov bx,ds:[Off]" eher zum Ziel führen (falls der Assembler weiß das die Sektion in der "Off: dw 0x0100" sich befindet über DS erreichbar ist würde er aus dem ersten Befehl automatisch den zweiten Befehl generieren).

Eigentlich hatte ich doch schon Samstag Nachmittag erklärt was der Befehl wirklich macht und was ich vermute was Du möchtest das er macht. Man wird mir sicher wieder Unhöflichkeit vorwerfen aber ich muss dazu ganz ehrlich sagen das wenn andere Leute die Zeit investieren Dir eine anständige Antwort zu geben dann solltest Du auch die Zeit investieren diese gründlich zu lesen.

Gerade die Diskrepanz zwischen dem was die Befehle wirklich machen und dem was Du vermutest was die Befehle machen ist es die sich durch all (zumindest die meisten) Deine Fragen zieht wie ein roter Faden. Da ist wiederholtes RTFM als Antwort gar nicht verwunderlich.

Ich würde Dir wirklich gern ein gutes Buch, wo der Leser an die Hand genommen wird und ihm schrittweise gut erklärt wird was die CPU macht und wie die Befehle funktionieren, empfehlen aber leider kenne ich keines. Ob es dafür gute Tutorials gibt kann ich ebenfalls nicht beurteilen. Vielleicht hat zu dem einen oder anderen ja hier doch noch jemand einen guten konkreten Vorschlag. Der Punkt ist das sowas in einem Forum nicht wirklich geleistet werden kann. Ich will gar nicht Deine Entscheidung für Assembler kritisieren (da gibt es auch nichts zu kritisieren, diese Entscheidung ist völlig legitim) aber irgendwann musst Du Dich wirklich mal mit den Basics beschäftigen wenn Du auch mal vorwärts kommen möchtest.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Relbmessa

  • Beiträge: 73
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 12. December 2011, 12:27 »
Aus Lowlevel
Herzlich willkommen im Wiki der Lowlevel-Community!
Hier können angehende und fortgeschrittene Betriebssystementwickler Informationen finden, die sie unterstützen. Die Artikelserie OS-Dev für Einsteiger ist speziell an Neulinge gerichtet und gibt einen kleinen Einblick über die steinige Welt der Betriebssystementwicklung.

Ich muss jetzt mal eine Lanze für die/Den Anfänger (ich schliese mich nicht aus) brechen.
Wenn man als Anfänger-Neuling so niedergemacht wird verliert man vielleicht schnell die Lust
hier oder überhaupt Fragen zu stellen.
Ist die Frage zu einfach , muss man sie ja nicht beantworten.

Bscreator
Deine Frage ist mir zu ungenau:
Wo ist der Code eingebunden ?
Welche Plattform benutzt du? Windows -Linux (zum Bearbeiten)
Welchen Assembler? NASM
Dieser Code macht bei mir Fehler!
Seg dw 0x0800
Off dw 0x0100
;...
mov bx, Seg
mov es, bx
mov bx, Off
mov es:bx, 1

Seg ist auch ungünstig (Pseudobefehl-bei NASM)
lieber so Seg_

Code NASM:
 
Seg_ dw 0x0800
Off dw 0x0100
;
mov bx, [Seg_]
mov es, bx
mov bx, [Off]
mov byte [es:bx], 1

Es fehlen Fakten – Wie schon bei den Beiträgen erkennbar ist, entstehen dadurch sehr viele
Antworten die nicht weiterhelfen.
Der Rest denk ich mal ist schon recht gut beschrieben .
Gruß Relbmessa
Viel Spaß beim weiteren Programmieren   
« Letzte Änderung: 12. December 2011, 12:30 von Relbmessa »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 12. December 2011, 12:29 »
Man wird mir sicher wieder Unhöflichkeit vorwerfen aber ich muss dazu ganz ehrlich sagen das wenn andere Leute die Zeit investieren Dir eine anständige Antwort zu geben dann solltest Du auch die Zeit investieren diese gründlich zu lesen.
Berechtigte Unhöflichkeit. Dass ich jemandem ein "Lern C/Assembler" an den Kopf werfe, muss er sich vorher schon hart erarbeiten.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

DerHartmut

  • Beiträge: 236
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #15 am: 12. December 2011, 12:34 »
Ich zitiere mal kurz OS-Dev für Einsteiger:

Zitat
Unverzichtbar

    Programmiererfahrung! Wenn du noch nie ein Programm geschrieben hast, bist du hier ziemlich sicher falsch. Das Programmieren eines richtigen Betriebssystems ist keine Anfängerübung zum Erlernen des Programmierens, ein gewisser Level an Programmiererfahrungen ist dafür zwingend erforderlich. Wenn du erst einmal einen Einstieg in das Programmieren als solches suchst, dann werden dir die Lowlevel-Forenmitglieder sicher trotzdem dabei helfen, Tutorials und Ressourcen zu finden.
    Gute Kenntnis des Systems und der benutzten Tools, also Compiler, Linker und deren Kollegen. Wenn du regelmäßig mit der Bedienung deines Betriebssystems oder der benötigten Programmierwerkzeuge kämpfst, dann ist es schwer, dabei Arbeit getan zu kriegen. Ein Windowsnutzer braucht eventuell sogar mehr Erfahrung als ein Linuxer, da sich manche Tools auf Windows zu Beginn recht zickig verhalten können. Auch die Zusammenhänge von Compiler - Assembler - Linker und den dazwischen liegenden Dateiformaten (linkbare Objekt-Dateien und ausführbare Programm-Dateien) sollten zumindest in Grundzügen geläufig sein.
    Neugier und Geduld. Vermutlich die heimlichen Kernqualifikationen jedes Programmierers. Ohne Neugier und Geduld wird es schwer, die Frustrationen der Betriebssystementwicklung zu überstehen.
    Kenntnisse über die Funktionsweise eines Computers. Ein Betriebssystem hat die Aufgabe, den Anwendungsprogrammen einen funktionierenden und fairen Zugang zu den Ressourcen eines Computers zu ermöglichen. Dafür ist es natürlich von Vorteil, wenn man weiß, was den Computer in seinem Innersten zusammenhält. Du solltest also schon recht konkret wissen, was die einzelnen Komponenten eines Computers machen und wie diese zusammenspielen.
    Umrechnen zwischen Zahlensystemen. Beim OS-Dev muss man häufig zwischen Dezimal-, Hexadezimal-, Oktal- und Binärsystem umrechnen, um die richtigen Bits zu setzten/löschen. Eine gute und kurze Anleitung dazu gibt es z.B. hier. Nachdem du verstanden hast wie es funktioniert und es mehrmals auf Papier geübt hast, kannst du natürlich auch z.B. den Windowstaschenrechner im "wissenschaftlichen Modus" zum Umrechnen benutzen. Ab Windows 7 gibt es einen "Programmierer"-Modus, der das Umrechnen noch einfacher macht, indem man sogar einzelne Bits an- und abschalten kann.
    Bitweise Operatoren. Man sollte wissen, wie man einzelne Bits innerhalb einer Variable löscht und setzt. Der Artikel Bitweise Operatoren bietet hier das nötige Basiswissen.

Das Problem ist nicht, dass man nicht gewillt ist, Anfänger zu helfen, das Problem ist, dass bscreator schon seit einer gefühlten Ewigkeit immer wieder Anfängerfragen stellt und ihm immer wieder (neben der puren Hilfestellung) gesagt wird: Lerne die Basics. Da darf man dann schon hier und da ein wenig forscher ihn darauf hinweisen, dass er diese Basics _endlich_ lernen sollte.

scnr.
$_="krJhruaesrltre c a cnp,ohet";$_.=$1,print$2while s/(..)(.)//;
Nutze die Macht, nutze Perl ;-)

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 12. December 2011, 12:37 »
Guck einfach mal einfach auf bscreators Post-Counter. Dann erübrigt sich manch langes Zitat.

Relbmessa

  • Beiträge: 73
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 12. December 2011, 12:53 »
Da werde ich wohl mit leben müsse !!

Relbmessa

bscreator

  • Gast
Gespeichert
« Antwort #18 am: 12. December 2011, 13:35 »
Assemblerbücher hab ich schon (2 Stück), da sind allerdings nur Beispiele für Windows-Programme erklärt, wo die Interrupts bei 0x21 schon vorbelegt sind. Und alle anderen Assemblerbücher, die es zu kaufen gibt gehen nur in dieselbe Richtung. Zwar interessant, aber alle für die OS-Programmierung mit Assembler kaum zu gebrauchen, da ständig der INT 0x21 aus Windows bzw. DOS-Zeiten verwendet wird.
Zitat
Programmiererfahrung! Wenn du noch nie ein Programm geschrieben hast, bist du hier ziemlich sicher falsch.
Programmiererfahrung mit Hochsprachen (C,C++, Objective C) hab ich genug, aber Assembler und OS-DEV ist eben, zumindest für mich, was anderes.

Zitat
OK,
danke für den Beitrag, aber der hat meine Frage zu 0% beantwortet
Sorry erik.vikinger, den Artikel von mir wollt ich noch umschreiben, denn da war ich ein bisl hart zu dir. Habs dann aber leider vergessen. Was ich schreiben wollt war, dass ich, wie oben erwähnt, Assembler-Bücher hab, aber die behandeln, wie alle anderen ASS-Bücher auch, nur Windows und DOS-Beispiele.
Erfahrung mit dem Computer und wie er aufgebaut ist hab ich genug.

Wahrscheinlich liegt der Fehler darin, dass ich häufig 2 verschiedene Assembler verwende. Daher kanns mal sein, dass ich das ein oder andere verwechsle.

Gruss,
bsc
« Letzte Änderung: 12. December 2011, 13:48 von bscreator »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 12. December 2011, 14:19 »
Lern erstmal Assembler ohne OS-Dev. Bei dir hapert es nämlich nicht am OS-Dev-bezogenen Teil, sondern schon bei den Grundlagen, die du schon können musst, um ein ganz normales Programm zu schreiben.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen