Schleifen und Switch-Case



  • Guden, mir ist noch ne Frage bezüglich Schleifen gekommen :D. Ich habe mich im Internet mal umgesehen, wie man sowas realisieren könnte und ich bin auf folgenden Code gestoßen:

    XOR EAX, EAX
      MOV ECX, 100 
      @Schleife: INC EAX 
                 LOOP @Schleife
    

    Zunächst wird das Register EAX geleert. DAnach wird in das Register ECX die Zahl 100 kopiert.

    Nun Wird EAX inkrementiert und anschließend wieder zum Punkt "schleife" gesprungen. Dies wird solange gemacht, bis ECX 0 ist.

    Warum wird ECX dekrementiert bzw. warum hört die Schleife genau dann auf, wenn 100 Schritte vorbei sind. Nachdem EAX um 1 erhöht wurde, wird doch kein Dekrementierungsbefehl aufgerufen, sondern gleich wieder inkrementiert.

    Außerdem habe ich versucht, eine Switch - Case Abfrage zu implementieren.

    CMP X, 1
      JE @first
      CMP X, 2
      JE @second
      CMP X, 3
      JE @third
      JMP @default // Springe zu @end wenn nichts zutrifft
    
      @first: DB 'Die Zahl ist 1.'
      @second: DB 'Die Zahl ist 2'
      @third: DB 'Die Zahl ist 3'
      @default: DB 'Die Zahl ist nicht 1;2;3.', 0
    
      RET
    

    Nun sei X == 2. Warum wird nicht "Die Zahl ist 2" ausgegeben, sondern ein Laufzeitfehler?

    Vielen Dank
    lg, freakC+++



  • freakC++ schrieb:

    Warum wird ECX dekrementiert bzw. warum hört die Schleife genau dann auf, wenn 100 Schritte vorbei sind. Nachdem EAX um 1 erhöht wurde, wird doch kein Dekrementierungsbefehl aufgerufen, sondern gleich wieder inkrementiert.

    Das Dekrementieren von ECX ist Teil des LOOP-Befehls, was du mit anderen Registern (hier EAX) machst, hat darauf keinen Einfluss. Und die Schleife führt genau 100 Runden aus, weil du am Anfang den Wert 100 in ECX untergebracht hast.

    (vielleicht solltest du mal etwas mehr zu den verwendeten Befehlen lesen als nur ihre Bezeichnung ;))

    Edit:

    freakC++ schrieb:

    Außerdem habe ich versucht, eine Switch - Case Abfrage zu implementieren.
    [...]
    Nun sei X == 2. Warum wird nicht "Die Zahl ist 2" ausgegeben, sondern ein Laufzeitfehler?

    Es macht ja auch wenig Sinn, ein String-Literal auszuführen 😉 Du solltest eher die Adresse deiner Literale als Parameter an eine Ausgabe-Funktion übergeben.

    PS: Eventuell solltest du dich erst einmal mit einer höheren Programmiersprache beschäftigen 😉



  • CStoll schrieb:

    (vielleicht solltest du mal etwas mehr zu den verwendeten Befehlen lesen als nur ihre Bezeichnung ;))

    Ich treibe mich auf dieser Seite rum: http://www.i8086.de/

    Da habe ich keine entsprechenden Infos gefunden.

    CStoll schrieb:

    Es macht ja auch wenig Sinn, ein String-Literal auszuführen 😉 Du solltest eher die Adresse deiner Literale als Parameter an eine Ausgabe-Funktion übergeben.

    Das stimmt. Ich glaube nicht, dass ich das Grundprinzip des Programmierens nicht vertanden habe, sondern eher, dass ich fast keine Ahnung von Assembler, den Befehlen und der Syntax habe.
    Du sagst, ich solle die Adresse der Literale an die Ausgabefunktion übergeben. Das macht Sinn, aber ich weiß nicht, was die Ausgabefunktion in Assembler ist und weiß auch nicht, wie ich hier an die Adresse komme. Da ich nicht möchte, dass ihr mir das vorsagt, hoffe ich eher auf eine Seite, wo die Funktionen vorgestellt werden. Über Goolge habe ich mit "Ausgabefunktion" nicht allzu viel gefunden. Hast Du einen Tipp für mich?

    Vielen Dank dir



  • freakC++ schrieb:

    CStoll schrieb:

    (vielleicht solltest du mal etwas mehr zu den verwendeten Befehlen lesen als nur ihre Bezeichnung ;))

    Ich treibe mich auf dieser Seite rum: http://www.i8086.de/

    Da habe ich keine entsprechenden Infos gefunden.

    Gründlicher lesen 😃
    http://www.i8086.de/asm/8086-88-asm-loop.html

    Mit dem LOOP-Befehl wird veranlasst, dass zunächst das CX-Register um eins dekrementiert (heruntergezählt) wird. Falls es dann noch nicht den Wert Null besitzt, wird die Bearbeitung des Programms an der Marke <Sprungziel> fortgesetzt, ansonsten der nächste Befehl hinter dem LOOP-Kommando ausgeführt.

    (wobei die Referenz für den 8086 wohl ein wenig veraltet sein dürfte 😃 der Prozessor ist ja genauso alt wie ich 😮 )

    CStoll schrieb:

    Es macht ja auch wenig Sinn, ein String-Literal auszuführen 😉 Du solltest eher die Adresse deiner Literale als Parameter an eine Ausgabe-Funktion übergeben.

    Das stimmt. Ich glaube nicht, dass ich das Grundprinzip des Programmierens nicht vertanden habe, sondern eher, dass ich fast keine Ahnung von Assembler, den Befehlen und der Syntax habe.

    Da mußt du vermutlich irgendeine Library einbinden oder selber eine Funktion dafür schreiben und per CALL aufrufen.


Anmelden zum Antworten