PrettyOS um Rechner erweitern



  • so, ich bin jetzt soweit, dass überprüft wird, ob eax = 0 ist (nach deiner anleitung)
    ich weiss aber auch nicht, durch welche basis es geteilt werden soll

    schleife:
    
                                    cmp eax,0
                                    jne ungleich
                    gleich:
                                    jmp weiter
                    ungleich:
                                    ; eax durch basis teilen; doch welche basis?
                                    jmp schleife
                    weiter:         jmp ende_schleife
    
            loop schleife
            ende_schleife:
            ; hier sollte es weitergehen
    

    und dann komm ich nicht ganz klar mit der anleitung.
    ich soll ax, ax:dx oder eax:adx (eins der drei wird automatisch ausgewählt) durch den divisor teilen
    aber durch welchen divisor?



  • Kannst du den Thread nochmal verlinken?

    Ok, dir ist aber schon so weit ueberhaupt klar, was du dort weshalb auf 0 pruefst?
    Dividieren tust du dann natuerlich durch die Basis des Zahlensystems, in dem du deine Zahl in den String schreiben willst. Das Dezimalsystem hat die Basis 10, hexadezimal die Basis 16, Binaer die Basis 2, usw. Ein System erkennbar? 😉

    Deine Schleife ist uebrigens noch ziemlich verbesserungsfaehig:
    eax pruefst du sinnvollerweise erst nach der Division am Ende der Schreife.
    Wozu soll der doppelte Sprung ueber "weiter" gut sein?
    Wozu das "loop schleife"? Weist du ueberhaupt, was der loop-Befehl tut?

    lmb schrieb:

    und dann komm ich nicht ganz klar mit der anleitung.

    Bin um aufklaerung und Verbesserung bemueht, dann taugt der Text vielleicht auch irgendwann mal fuer die FAQ. 🙂

    lmb schrieb:

    ich soll ax, ax:dx oder eax:adx (eins der drei wird automatisch ausgewählt) durch den divisor teilen
    aber durch welchen divisor?

    Naja, welche Register als Dividend genommen werden, haengt davon ab, wie breit der Divisor (Operand von div fuer unsigned, bzw. idiv fuer signed) ist. Fuer Division durch 8 brauchst du 16Bit Eingang (ax), fuer 16Bit-Divisor 32Bit Dividend (dx:ax), usw.
    Der Divisor ist die oben erwaehnte Basis.



  • http://www.c-plusplus.net/forum/viewtopic-var-t-is-236735-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-integer.html

    nein ich weiss das nicht.
    das stand nirgends.
    mein integer ist eine stinknormale rationale zahl, also dezimalsystem.
    also ist meine basis 10

    eax pruefst du sinnvollerweise erst nach der Division am Ende der Schreife.

    Ja aber dann kann ich doch nicht vergleichen, oder soll ich 2mal?

    Wozu soll der doppelte Sprung ueber "weiter" gut sein?

    wie meinst du das und wo?

    Wozu das "loop schleife"? Weist du ueberhaupt, was der loop-Befehl tut?

    hab ich übersehen, sorry



  • lmb schrieb:

    nein ich weiss das nicht.
    das stand nirgends.

    Was du auf 0 pruefen sollst, steht doch klar im 2. Beitrag: Den Quotient, und den bekommst du wie der Name schon sagt erst als Ergebnis der Division. 😉
    Warum erschliesst sich dir vielleicht, wenn du darueber nachdenkst, dass das wiederholte Dividieren von 0 immer nur 0 ergeben wird und damit keine weiteren brauchbaren Ziffern deiner Zahl. Also eine nahe liegende Abbruchbedingung.
    Ka, wie man das sonst klarer formulieren sollte...

    Hm, vielleicht wird an einem kleinen Beispiel deutlicher, wie diese Schleife mit der Division funktionieren soll:

    Nehmen wir an, du hast die Zahl 123. Um die nun als String darstellen zu koennen, musst du irgendwie nacheinander an die einzelnen Ziffern herankommen.
    123 kannst du auch schreiben als 3 * 10^0 + 2 * 10^1 + 1 * 10^2 + 0 * 10^3 + ...
    (123 hat hier in dieser dezimalen Darstellung die Basis 10).

    Also was macht man, um die Ziffern zu bekommen? Division mit Rest (Modulo) durch 10!
    1. 123 mod 10 = 3; 123 / 10 = 12; 12 = 0? -> nein: weiter
    2. 12 mod 10 = 2; 12 / 10 = 1; 1 = 0? -> nein: weiter
    3. 1 mod 10 = 1; 1 / 10 = 0; 0 = 0? -> ja: fertig

    Der div-Befehl liefert dir nun wie gesagt sowohl Den Rest als auch den Quotient.

    lmb schrieb:

    mein integer ist eine stinknormale rationale zahl, also dezimalsystem.
    also ist meine basis 10

    Integer stellen nur ganze Zahlen dar, keine rationalen Zahlen.
    Wie du die Zahl darstellst (dezimal, hexadezimal, whatever) hat ansonsten nichts mit dem Zahlensystem zu tun.
    Du koenntest deinen Integer auch als Dualzahl, hex, oktal - eigentlich mit jeder beliebigen Basis darstellen.
    Dezimal 123 von oben ist hexadezimal zB. 7B (= (B = 12) * 16^0 + 7 * 16^1).

    lmb schrieb:

    eax pruefst du sinnvollerweise erst nach der Division am Ende der Schreife.

    Ja aber dann kann ich doch nicht vergleichen, oder soll ich 2mal?

    Weshalb kannst du den Quotient nach der Division nicht mit 0 vergleichen?

    lmb schrieb:

    Wozu soll der doppelte Sprung ueber "weiter" gut sein?

    wie meinst du das und wo?

    jmp weiter    ; z.6
    ;...
                    weiter:         jmp ende_schleife    ; z.10
    

    Erscheint mir wenig sinnvoll. 😃



  • Nobuo T schrieb:

    lmb schrieb:

    nein ich weiss das nicht.
    das stand nirgends.

    Was du auf 0 pruefen sollst, steht doch klar im 2. Beitrag: Den Quotient, und den bekommst du wie der Name schon sagt erst als Ergebnis der Division. 😉

    Was ich auf 0 prüfen soll, ist mir klar, aber:

    Nobuo T schrieb:

    Warum erschliesst sich dir vielleicht, wenn du darueber nachdenkst, dass das wiederholte Dividieren von 0 immer nur 0 ergeben wird und damit keine weiteren brauchbaren Ziffern deiner Zahl. Also eine nahe liegende Abbruchbedingung.
    Ka, wie man das sonst klarer formulieren sollte...

    das hier ist mir erst jetzt klar geworden :D. Naja, vielleicht war ich zu abgelenkt

    Nobuo T schrieb:

    Hm, vielleicht wird an einem kleinen Beispiel deutlicher, wie diese Schleife mit der Division funktionieren soll:

    Nehmen wir an, du hast die Zahl 123. Um die nun als String darstellen zu koennen, musst du irgendwie nacheinander an die einzelnen Ziffern herankommen.
    123 kannst du auch schreiben als 3 * 10^0 + 2 * 10^1 + 1 * 10^2 + 0 * 10^3 + ...
    (123 hat hier in dieser dezimalen Darstellung die Basis 10).

    Also was macht man, um die Ziffern zu bekommen? Division mit Rest (Modulo) durch 10!
    1. 123 mod 10 = 3; 123 / 10 = 12; 12 = 0? -> nein: weiter
    2. 12 mod 10 = 2; 12 / 10 = 1; 1 = 0? -> nein: weiter
    3. 1 mod 10 = 1; 1 / 10 = 0; 0 = 0? -> ja: fertig

    Der div-Befehl liefert dir nun wie gesagt sowohl Den Rest als auch den Quotient.

    genau und zwar wird der Rest in dx und der Quotient in ax gespeichert.

    Nobuo T schrieb:

    Weshalb kannst du den Quotient nach der Division nicht mit 0 vergleichen?

    Naja, es wirt eax auf 0 geprüft, wenn das nicht so ist, springt er zu ungleich, ansonsten geht er weiter zu gleich.
    in gleich wird über ungleich auf weiter gesprungen. in ungleich soll geteilt werden und dann wieder geprüft werden.
    also muss ich theoretisch 2mal prüfen, 1mal am anfang, einmal bei ungleich nach dem dividieren.

    Nobuo T schrieb:

    jmp weiter    ; z.6
    ;...
                    weiter:         jmp ende_schleife    ; z.10
    

    Erscheint mir wenig sinnvoll. 😃

    Da hast du wohl recht 🤡



  • lmb schrieb:

    Naja, es wirt eax auf 0 geprüft, wenn das nicht so ist, springt er zu ungleich, ansonsten geht er weiter zu gleich. in gleich wird über ungleich auf weiter gesprungen. in ungleich soll geteilt werden und dann wieder geprüft werden.
    also muss ich theoretisch 2mal prüfen, 1mal am anfang, einmal bei ungleich nach dem dividieren.

    Vielleicht entfernst du dich besser gedanklich erst nochmal von deiner bisher gebastelten Schleife...
    Es soll nicht eax auf 0 geprueft werden, sondern der Quotient. Der steht nach der Division nur gerade in eax, vor der Division hast du also gar nichts zum Pruefen.
    Eine einzige Ueberpruefung am Ende der Schleife (quasi do{ ... } while() statt while() { }) und mit dieser einen Ueberpruefung auch nur ein bedingter Sprungbefehl, mehr brauchst du im Prinzip nicht, um diese Schleife zu basteln.
    Keine labels "gleich", "ungleich", "weiter" und auch keine tausend jmps.



  • dann meinst du bestimmt sowas hier:

    loop:
      div
      cmp eax,0
      jne loop
      ;hier gehts weiter
    


  • 👍



  • Jaaaaaaaa!
    Danke!
    Jetzt habe ich die ganze Geschichte verstanden!
    Es gibt in Assembler keine Kommazahlen, deswegen wird der Rest in dx gespeichert!
    Und ich speichere die Ziffern nacheinander in einer Variable.
    Diese wird am Ende umgedreht, sonst habe ich statt 123 halt 321.
    Jetzt schnall ich das!
    Danke!
    Und jetzt kann ich auch wieder vernünftig schreiben, habe gerade meinen Gips bis zur Schulter abbekommen!
    Ich versuch mich mal weiter dran.

    EDIT://
    Ich bin nirgendwo fündig geworden.
    Wie kann ich einem String einen weiteren String hintendran (oder besser vornedran) fügen?
    Unter dem Suchwort "String Manipulation" gab es nichts tolles...

    ;int eax in string umwandeln
            loop:
            div 10                                   ;eax/10  (Ergebnis wird in ax, Rest in dx gespeichert)
            cmp eax,0                                ;eax=0?
            jne loop                                 ;wenn eax != 0, gehe zu loop
    
            ;hier gehts weiter
    


  • lmb schrieb:

    Es gibt in Assembler keine Kommazahlen, deswegen wird der Rest in dx gespeichert!

    Nicht ganz. In Assembler kannst du natuerlich auch mit Fliesskommazahlen arbeiten. Die Sache hier ist, dass ein integer wie gesagt nur ganze Zahlen darstellen kann und du hier explizit eine Integer-Division mit Rest durchfuehrst.

    lmb schrieb:

    Wie kann ich einem String einen weiteren String hintendran (oder besser vornedran) fügen?

    Prinzip ist naheliegend: Du besorgst dir einen Pointer auf den Quellstring (bzw. im Prinzip klappt das mit jedem Datum) und einen auf den Zielstring und packst sie in 2 verschiedene Register (zB. esi und edi).
    Dann laedst du mit dem Pointer vom Quellstring (zB. mov al, [esi]), schreibst das zum Pointer beim Ziel (zB. mov [edi], al) und inkrementierst (bzw. dekrementierst) entsprechend die Pointer.
    Es gibt dazu auch noch die speziellen String-Befehle movs(b/w/d).

    Uebrigens akzeptiert div keine Konstante als Operand, sondern nur Register oder Speicheroperanden und es gibt keine Konstellation, bei der du nur eax als Dividend hast, sondern wie gesagt je nach Breite des Operanden (Divisor) entweder ax (8Bit Divisor), dx:ax (16Bit Divisor) oder edx:eax (32Bit Divisor).
    Wenn du eax als Dividend benutzen willst, musst du also darauf achten, dass edx 0 ist.



  • Nobuo T schrieb:

    Nicht ganz. In Assembler kannst du natuerlich auch mit Fliesskommazahlen arbeiten. Die Sache hier ist, dass ein integer wie gesagt nur ganze Zahlen darstellen kann und du hier explizit eine Integer-Division mit Rest durchfuehrst.

    ähh, ja klar. ich meinte natürlich den integer

    Nobuo T schrieb:

    Prinzip ist naheliegend: Du besorgst dir einen Pointer auf den Quellstring (bzw. im Prinzip klappt das mit jedem Datum) und einen auf den Zielstring und packst sie in 2 verschiedene Register (zB. esi und edi).

    OK ... jetzt steh ich wieder aufm Schlauch.
    Pointer = Pointer Register = sp, bp, ip?
    = mov ergebnis, sp?
    mov dx, bp
    mov esi, sp
    mov edi, bp ?

    Nobuo T schrieb:

    Dann laedst du mit dem Pointer vom Quellstring (zB. mov al, [esi]), schreibst das zum Pointer beim Ziel (zB. mov [edi], al) und inkrementierst (bzw. dekrementierst) entsprechend die Pointer.

    hmm, ich glaube ich habe meine hausaufgaben nicht richtig verstanden... 😞

    Nobuo T schrieb:

    Es gibt dazu auch noch die speziellen String-Befehle movs(b/w/d).

    Nixx gefunden bei Google. Was soll das sein?

    Nobuo T schrieb:

    Uebrigens akzeptiert div keine Konstante als Operand, sondern nur Register oder Speicheroperanden und es gibt keine Konstellation, bei der du nur eax als Dividend hast, sondern wie gesagt je nach Breite des Operanden (Divisor) entweder ax (8Bit Divisor), dx:ax (16Bit Divisor) oder edx:eax (32Bit Divisor).
    Wenn du eax als Dividend benutzen willst, musst du also darauf achten, dass edx 0 ist.

    also muss ich das hier machen: (?)

    mov edx, 0
    mov wert, 10
    div wert
    


  • Ist dir ueberhaupt klar, was ein Pointer oder Zeiger und eine Speicheradresse prinzipiell sind?



  • nein.
    nur die speicheradresse ist, wie der name schon sagt, eine speicherort im ram.
    dieser wird zb so angegeben 0x0000
    ich weiss auch nicht, wie man den speicherort bzw die speicheradresse ermittelt oder, was ein interrupt ist.
    ich kenne halt nur einige grundbefehle sowie die logischen programmierkenntnisse (kann man das so sagen?)

    angefangen hab ich mit basic, ich war 11
    mit 12 visual basic, seit rund einem jahr versuche ich mich in webdesign und -programmierung (php und mysql natürlich mit an bord).

    das heisst, ich bin mir mit logischen anwendungen eigentlich vertraut.
    das bit und byte system sowie hexadezimale sachen komman wohl erst in der oberstufe (bin jetzt 8. klasse gesamtschule)
    (nein, ich bin kein checker "Å£†Å WI££ ا p®ØGGE®n übE£§† ØdE®!!!!!!!!!!?????????" 😉 :D)



  • Uh, an deinem 1337-speak musst du aber auch noch arbeiten. 🤡

    Ansonsten macht das die Sache leider um einiges schwieriger. Dir scheinen wirklich die kompletten Grundlagen zu fehlen.
    Ich wuerde dir wirklich raten, erstmal einige Tutorials durchzuarbeiten, da ich fuerchte, dir entsprechende Texte zu verfassen wuerde hier ein wenig den Rahmen sprengen.



  • OK!
    Ich würde gerne auf Erhard's ASM-Tutorial zurückgreifen, aber anscheinend ist das aprupt zu Ende!?
    Könnt ihr mir was gutes Empfehlen?



  • Ich fand eigentlich das Tut von Thomas Peschko ziemlich gut.
    Sollte gerade noch [urlspieltkeinerollemehr] zu finden sein...

    edit:
    Ich sehe gerade, dass der hoster bei aol offline ist. Die unkomplizierteste Methode duerfte sein, sich beim web archive zu bedienen.
    URL ist http://web.archive.org
    Dort dann nach http://members.aol.com/peschko suchen und anschliessend noch mal nach den Links zu den pdfs suchen und herunterladen.



  • Endlich mal ein wirklick gutes Tutorial!
    Bei den anderen die ich so gesehen wird direkt losgeballert mit Code.
    Ich sehe die Welt mit anderen Augen :D!
    (Ich hab's natürlich noch nicht durch)
    Also:
    Register = eine Art "Zwischenspeicher", entweder ist der nächste Schritt der Arbeitsspeicher oder die Verarbeitung in der CPU
    Basis = Anzahl der Ziffern, die im System verwendet können (Dual/Binär: 2, Dezimal: 10, Hexadezimal 16?)



  • nicht richtig?


  • Mod

    Basis = Anzahl der Ziffern, die im System verwendet können (Dual/Binär: 2, Dezimal: 10, Hexadezimal 16?)

    Das ist nicht sauber ausgedrückt. es ist eher die Anzahl unterschiedlicher Informationen, die mit einer "Stelle", die aus n Ziffern gebildet werden kann, ausgedrückt werden können. Binär: 0 oder 1, also zwei mögliche Informationen pro Bit. Beim Dezimalsystem sind es 0...9, also zehn Möglichkeiten. Im Hexadezimalsystem entsprechend 0...F, also 16 Möglichkeiten.
    http://de.wikipedia.org/wiki/Dualsystem



  • Erhard Henkes schrieb:

    Basis = Anzahl der Ziffern, die im System verwendet können (Dual/Binär: 2, Dezimal: 10, Hexadezimal 16?)

    Das ist nicht sauber ausgedrückt. es ist eher die Anzahl unterschiedlicher Informationen, die mit einer "Stelle", die aus n Ziffern gebildet werden kann, ausgedrückt werden können.

    nö, das war schon richtig so. die basis eines zahlensystems bestimmt die anzahl verschiedener ziffern. ein zahlensystem zur basis 2 hat 2 ziffern (0,1) eins zur basis 3 hat 3 ziffern (0,1,2) und allgemein, eins zur basis b hat immer b ziffern (von 0...b-1). demnach gäbs auch ein zahlensystem zur basis 1 mit nur einer ziffer und eins zur basis 0 mit 0 ziffern (beides ist unsinnig, aber mal der vollständigkeit halber).
    🙂


Anmelden zum Antworten