Minibetriebssystem - Hilfe !!!

Natureshadow
Hi Leute,

habe angefangen ein kleines Betriebssystem in Assembler zu schreiben. Bis jetzt lief eigentlich alles ziemlich glatt, habe bis jetzt ja auch nur ein bisschen Text ausgegeben ... Aber jetzt habe ich eine Überprüfung auf die Verfügbarkeit des CPUID-Befehls implementiert, und plötzlich kommt von jedem String, den ich ausgeben will, nur noch der erste Buchstabe auf dem Bildschirm an. Mein Code sieht so aus:

start:
mov si,krnloadedmsg
call putstr
mov si,strcrlf
call putstr
mov si, goingcheckcpuid
call putstr
jmp checkcpuid

krnloadedmsg db "kernel loaded.",13,10,0
waitkeymsg db "Press any key to continue ...",0
hangmsg db "The system will be halted immediately!",0
strcrlf db 13,10,0
goingcheckcpuid db "Checking for availability of CPUID ... ",0
avaliablecpuid db "available, guessing for Pentium-CPU",13,10,0
unavaliablecpuid db "unavailable, guessing for Non-Pentium-CPU",13,10,0

checkcpuid:
.386
pushfd
popeax
mov ebx, eax
xor eax, 0020000h
push eax
popfd
pushfd
pop eax
xor eax, ebx
jnz cpuidavaliable

.8086
mov si, unavaliablecpuid
call putstr
call bootonaftercpuid

cpuidavaliable:
mov si, avaliablecpuid
call putstr
call bootonaftercpuid

bootonaftercpuid:
mov si, hangmsg
call putstr

; Mit dieser Funktion geben wir einen String aus
putstr:
lodsb
or al,al
jz short putstrd
mov ah,0x0E
mov bx,0x0007
int 0x10
jmp putstr
putstrd:
retn

Die Ausgabe funktioniert normal, bis nach der Ausführung der Überprüfung. Dann kommt wie gesagt nur noch das a von available an ...

Kann mir da jemand helfen?
NASA
Ich vermute mal, dass Du Dir durch die CPUID-Abfrage das Direction-Flag zerschossen hast und der lodsb bei putstr jetzt rückwärts läuft. Entweder sicherst Du Dir das Flagregister vor dem CPU-Check mit einem pushfd auf dem Stapel und holst es danach mit popfd wieder zurück (dann hast Du alle Flags wieder), oder Du setzt vor dem lodsb mittels cld das direction-Flag zurück.
Hunter
@ Natureshadow

In meinem Buch steht, man muss Bit 21 toggeln.
Du toggelst Bit 17 - liegts vll daran?

code:
1:
xor eax, 0020000h


Ansonsten konnt ich das von NASA nicht bestätigen, da das Direction Flag auf Platz 2 (kann auch falsch sein, aber auf jeden Fall in den unteren 16 Bit) liegt. Das Bit was du toggelst steht für die VM.

Daher kommt dann wahrsch. auch nicht mehr die hangmsg, die ja sonst auch mit dem 1. Buchstaben erscheinen müsste.
NASA
Da fehlt eh ne Null, mglw. hinter der 2, dann würds stimmen. Füllt der Assembler linksbündig auf?
Das DF liegt tatsächlich in den unteren 16 Bit. Wenn die allerdings durch den falschen Befehl verhunzt werden, würde das die Misere erklären...
Hunter
@ NASA

Das hab ich doch geschrieben, dass dort Bit 17 statt 21 getoggelt wird und dann gabs noch einen Auszug aus seinem Code.

Und wenn ich das Problem richtig verstanden habe, wird nur ein "a" ausgegeben. Wäre es nur das D-Flag, würde ja - durch die Sprungmarke: bootonaftercpuid - noch der erste Buchstabe der hangmsg ausgegeben.

Wenn man aber ohne Vorbereitung die VM einschaltet, ist klar das der Prozessor da keine Lust drauf hat ;-)

Und damit er gleich C&P machen kann:
code:
1:
0x200000 bzw. 200000b
NASA
> Das hab ich doch geschrieben, dass dort Bit 17 statt 21 getoggelt wird und dann gabs noch einen Auszug aus seinem Code.

Normalerweise schreibt man 32-Bit Werte aber mit 8 (!) Hexadezimalstellen,und nicht wie im Code mit 7
Die Frage ist: Was macht der Assembler daraus?

> Und wenn ich das Problem richtig verstanden habe, wird nur ein "a" ausgegeben. Wäre es nur das D-Flag, würde ja - durch die Sprungmarke: bootonaftercpuid - noch der erste Buchstabe der hangmsg ausgegeben.

Das habe ich anders verstanden:
> und plötzlich kommt von jedem String, den ich ausgeben will, nur noch der erste Buchstabe auf dem Bildschirm an.

Und damit er gleich C&P machen kann:
code:
0x200000
Ob das der Assembler versteht?
bzw. 200000b
Das dürfte falsch sein. Binary ist das jedenfalls nicht.
Hunter
@ NASA

Zitat:
Die Ausgabe funktioniert normal, bis nach der Ausführung der Überprüfung. Dann kommt wie gesagt nur noch das a von available an ...


Ich hab das so interpretiert, dass das der auschlaggebende Satz ist, sonst würde dann ja zum Schluss "aT" dastehen.

Aber das soll er uns mal selbst Schildern.

Mit dem 200000b hast du natürlich recht :-) Da war das b schneller als das h.

Zitat:
Normalerweise schreibt man 32-Bit Werte aber mit 8 (!) Hexadezimalstellen,und nicht wie im Code mit 7


Das "Gesetz" ist mir noch nie aufgefallen. Sollte sich doch eine Routine daran halten, Werte nur mit 8 Stellen zu akzeptieren, würde ich diese kaputte Software gegen eine funktionierende Tauschen.

Aber ein vernünftiger Assembler, bzw. dessen StrToInt Routine geht - wie man das im Dezi- & Hexadezimalsystem macht, von rechts nach links durch.

Zitat:
0x200000
Ob das der Assembler versteht?


Der NASM sollte tuts und da er nicht schrieb, welchen er verwendet, hab ich einfach mal beide Schreibweisen angegeben. (Obwohl, das .386 sieht wohl nach TASM od. MASM Syntax aus.)
NASA
Bei der erneuten Code-Durchsicht hab ich gesehen, dass es der Assembler anscheinend kann. Demnach sollte es funzen.

> Das "Gesetz" ist mir noch nie aufgefallen. Sollte sich doch eine Routine daran halten, Werte nur mit 8 Stellen zu akzeptieren, würde ich diese kaputte Software gegen eine funktionierende Tauschen.

Darum gehts nicht. Es geht um die Lesbarkeit des Codes. Bei vielen Assemblern ist das links/rechtbündige Auffüllen typabhängig (Hex / Char). Das führt dann beim flüchtigen Drüberlesen immer zu erstaunlichen geistigen Fehlleistungen. Darum werden bei uns im Betrieb die Konstanten immer ausgeschrieben. Ist halt eine gewisse Konvention, an die sich bei uns jeder hält. Man merkt dann auch gleich (wie hier), wenn jemand eine Stelle zu wenig eingegeben hat...
Hunter
@ NASA

Gut, ist vielleicht nicht ganz unpraktisch. Aber ich stell mir das dann bei 64bit bissl langdauernd vor.

Ausser natürlich, ihr sagt, dass es nur bis zum nächsten Byte bzw. Word, sonst würde das hier auch net hinhauen, gemacht wird.

Edit: Aber eigentlich hätte er den Fehler mit einem Debugger recht fix bemerken können. Zumindest sollte der Code ja unter DOS lauffähig sein, ist ja nix spezielles drin.
NASA
Debugger - gutes Stichwort.
Normalerweise kann man damit ja auch recht einfach single-step tracen. Dann sollte man eigentlich am schnellsten merken wo es hakt. Zumal man sich ja nach jedem Befehl die Registerinhalte anschauen kann.

> Aber ich stell mir das dann bei 64bit bissl langdauernd vor.
64 Bit haben wir eher selten, meistens 32 und 16. Und jede Menge BCD.
Hunter
@ NASA

BCD? Programmiert ihr Mikrokontroller bzw. Zeug was in diese Kategorie fällt?
NASA
> BCD? Programmiert ihr Mikrokontroller bzw. Zeug was in diese Kategorie fällt

Nö - ganz im Gegenteil. Sehr großer Rechner mit IBM /370-Assembler
Hunter
@ NASA

Uih, wie alt ist denn?

Von: http://www.beagle-ears.com/lars/engineer...bm360.htm#gener

Zitat:
In the summer of 1970, IBM announced a family of machines with an enhanced instruction set, called System/370.


Aber mich wundert seid dem Studium nichts mehr. Ein Mitstudent hat bei einem Freund im Keller ne PDP11 stehn und versucht die wieder in Schuss zu bringen.
NASA
> Uih, wie alt ist denn?

Ziemlich aktuell:
http://www-1.ibm.com/servers/de/eserver/.../feature040704/

Da kannst Du wenn Du willst sogar Linux drauf laufen lassen.

Wir haben ein etwas älteres Modell mit 1 GB Hauptspeicher und afaik ca. 250 GB Raid5-Festplatten mit Fibrechannel. Dazu noch diverse Peripherie wie Magnetbandkassetten und Schnelldrucker.

Bei einer historisch gewachsenen EDV-Struktur ist es ganz natürlich, dass man von Seiten IBM Bewährtes nicht einfach in die Tonne kickt, sondern gezielt weiterentwickelt, auch im Sinne der zahlenden Kunden.
Und viele Unternehmen haben mittlerweile auch gemerkt, dass die C/S-Lösungen oftmals weder besser noch billiger sind als ein gut konfigurierter Host. Von Verfügbarkeit und Sicherheit auch im Hinblick auf Internetanwendungen will ich garnicht reden. Wenn Du einmal gezielt in Baumärkten und Kaufhäusern auf die installierte EDV achtest, wirst Du feststellen, dass zwar meist PCs Verwendung finden (wie bei uns auch), dort aber fast immer noch eine Hostanbindung als Emulation läuft.

Ist schon eine andere Welt wie 8086-Assembler...
BTW Der OP scheint sich irgendwie ausgeklinkt zu haben, schade, ich wüsste doch gerne, wer recht hatte ;-)
Hunter
@ NASA

Jo, was ich so von anderen Architekturen gehört habe, soll dort der Assemblercode logischer aufgebaut sein und man hat mehr Allzweck-Register... dummerweise hat sich x86 bis jetzt aber im Homebereich durchgesetzt.

Aber bei 1GB Hauptspeicher würde ich nicht zwangsläufig Assembler nehmen. Zumindest aus Gründen der Sicherheit würde ich wohl eher auf eine Sprache zurückgreifen, die den Code etwas besser kontrolliert - bspw. C.

Zitat:
BTW Der OP scheint sich irgendwie ausgeklinkt zu haben, schade, ich wüsste doch gerne, wer recht hatte ;-)


Wenn dich das wirklich interessiert, dann werd ich mir mal ne DOS Bootdisk basteln und das testen ;-)
NASA
> Zumindest aus Gründen der Sicherheit würde ich wohl eher auf eine Sprache zurückgreifen, die den Code etwas besser kontrolliert - bspw. C.

Das war jetzt aber Spass, oder?
Die exzessive Nutzung von Pointern ist mir zu abstrus. Und irgendwie hab ich den Eindruck, dass die massiven BufferOfferflows auch etwas mit der Programmiersprache zu tun haben.
Beim Thema Sicherheit gings mir aber nicht primär um die Programmierung, sondern um das zugrundeliegende Betriebssystem.

> Aber bei 1GB Hauptspeicher würde ich nicht zwangsläufig Assembler nehmen.
Naja, bei 250 Usern mit 600-800 Sessions, die sich den 1 GB Speicher teilen siehts etwas anders aus. Außerdem rutscht ein schönes Stück auch schon für BS drauf. Und neben den Online-Applikationen laufen auch noch Stapeljobs. Im übrigen gibts analog der Auslagerungsdatei in Windows auch Virtual Storage. Aber der ist halt langsamer.
Mein größtes Programm hatte bisher so knapp 16k Code und 8k Daten (assembliert). Ich schätze mal, dass in C das ganze etwas größer/langsamer wäre.

Mit Registern arbeiten wir weniger, die meisten Befehle sind 2-Adressbefehle (Speicher-Speicher).
Theoretisch gibts 15 Allzweck-Regs, davon sind einige durchs BS belegt, und für das Programm und die Daten brauchst du alle 4k ein Register zur Adressierung. Da bleibt i.d.R. nicht mehr viel über.

>
Wenn dich das wirklich interessiert, dann werd ich mir mal ne DOS Bootdisk basteln und das testen ;-)
Ich bin ehrlich gesagt zu faul dazu - ich hab ja schließlich Urlaub :-)
Hunter
@ NASA

Zitat:
Das war jetzt aber Spass, oder?
Die exzessive Nutzung von Pointern ist mir zu abstrus.


Nein, das war durchaus kein Spass. Da ich deinen Anwendungszweck nicht kenne, bin ich von normaler Anwendungssoftware ausgegangen, die keine Systeminterna nutzt und somit sogar fast ohne Pointer auskommen würde.

Ich persönlich bin übrigens ein Freund von Pointern ;-) Und falls da mal was nicht nach meinen Vorstellungen klappt, kann ich mir ja im Disassemblat anschauen, warum nicht.

Zitat:
Und irgendwie hab ich den Eindruck, dass die massiven BufferOfferflows auch etwas mit der Programmiersprache zu tun haben.


Jain. Wenn man eine Sprache kennt, weiss man, ob sie Möglichkeiten bietet, Buffer Overflows von vornherein auszuschliessen.

Bsp: Stringkopierung. In C gibt es strcpy und strncpy. Wer faul ist, nimmt strcpy. Wer auf Sicherheit zielt, strncpy.

Genauso ist es in Asm. Entweder ich parse nur bis bspw. eine Null kommt (bei einem Null-Terminiertem-String) oder ich kopiere nur eine maximale Anzahl Zeichen falls keine Null vorkommt.

Wie gross dann das Zeichenarray ist, muss man sowohl in Asm als auch in C wissen - sonst produziert man bei beiden Mist.

Zitat:
Mein größtes Programm hatte bisher so knapp 16k Code und 8k Daten (assembliert). Ich schätze mal, dass in C das ganze etwas größer/langsamer wäre.


Es wär etwas grösser, es wäre vielleicht - wenn man oft benötigte Routinen wie vll. memcpy nicht in Assembler schreibt - spürbar langsamer und es wär vielleicht noch portabel, falls man irgendwann mal auf eine andere Architektur wechseln würde.

Zitat:
Ich bin ehrlich gesagt zu faul dazu - ich hab ja schließlich Urlaub :-)


Ich hab Semesterferien ;-)