Wert in Variable abspeichern



  • Hallo versuche gerade den Wert von zahl in der Variable zahl2 zu speichern.
    Aber der PC piept nur und gibt komische Zeichen auf der Konsole aus was ist an meinem Quelltext falsch ?

    .MODEL SMALL 
    .STACK 100h 
    .DATA 
    
    	zahl DW 2
    	zahl2 DW (?)
    
    .CODE
    START:
    
    	mov ax,@data
    	mov ds,ax
    
    	mov ax , zahl
    	mov zahl2 , ax
    
    	mov dx,offset zahl2
    
    	mov ah,9h
    	int 21h
    
    	mov ah,4ch
    	int 21h
    
    END START
    


  • 1)Mach die Klammern um das Fragezeichen weg.
    2)9h des int 21h gibt alles ab der Anfangsadresse des adressierten Speicherbereiches Byte-Weise und ASCII kodiert aus, bis das $-Zeichen kommt.
    Bei dir also: ASCII-Zeichen mit dem Stellenwert 2. (Das hast du ja reingeladen.)
    Und alles andere, was sich dahinter noch im Speicher befinden mag.



  • Die Klammern um das Fragezeichen hab ich nun entfernt aber es Piept noch immer und gibt Komische Zeichen aus -.-

    Ich denke mal mov ah,9h ist falsch aber welchen Ausgabe Befehl soll ich verwenden.

    Ich kenne bisher nur mov ah,9h



  • tasm schrieb:

    Die Klammern um das Fragezeichen hab ich nun entfernt aber es Piept noch immer und gibt Komische Zeichen aus -.-

    Das bewirkt auch genau nichts, die Klammern waren an der Stelle einfach nur fehl am Platz.

    tasm schrieb:

    Ich denke mal mov ah,9h ist falsch aber welchen Ausgabe Befehl soll ich verwenden.

    Ich kenne bisher nur mov ah,9h

    "mov ah, 9h" ist kein "Ausgabe Befehl". Das macht nichts anderes als den konstanten Wert 9h in das Register ah zu schieben. Dadurch bekommst du aber noch lange nichts auf den Bildschirm gezaubert. Mach dir vielleicht erstmal die Grundlagen von Programmierung in Assembler klar, zB. was Register sind und die grundlegendsten Befehle wie mov, cmp, add, jmp (und konditionierte Varianten).

    Unabhaengig davon kannst du mit der Funktion 09h des int 21h nicht einfach so Integer-Zahlen ausgeben. Diese Funktion kann, wie "selbst ist der mann" im 2. Punkt beschreibt, nichts anderes als einen mit "$" terminierten ASCII-String ausgeben. Und du wirst es sicher ahnen: Dein "Wert in Variable" ist kein $-terminierter ASCII-String.



  • In meinem Buch stand:

    mov variable1,variable ; so gehts nicht
    mov ax,variable2 ; mit einem umweg ...
    mov variable1,ax ; ...dann doch

    Daher dachte ich das man das einfach so machen könnte.

    Also muss ich erst mal irgendwie meine Zahl Konvertieren nehme ich mal an ...



  • Ach ja das ganze hab ich aus dem Buch:

    Assembler Grundlagen der Programmierung 2. Auflage

    von Joachim Rhode, Marcus Rohming

    Aber von Konvertierungen hab ich da leider nichts gefunden 😞



  • tasm schrieb:

    In meinem Buch stand:

    Stimmt auch. Nach dem Prinzip kannst du "Variablen" kopieren.
    Die Ausgabe auf dem Bildschirm ist aber ein ganz anderes Thema.

    tasm schrieb:

    Also muss ich erst mal irgendwie meine Zahl Konvertieren nehme ich mal an ...

    Wenn du nur eine Funktion hast, die ausschliesslich Strings ausgeben kann, musst du deine Integer-Zahl wohl in einen String konvertieren, bevor du sie ausgeben kannst - richtig.

    tasm schrieb:

    Aber von Konvertierungen hab ich da leider nichts gefunden

    Hat auch nicht wirklich etwas mit Assembler zu tun. Von daher vielleicht didaktisch nicht ganz so schoen, aber durchaus nachvollziehbar.

    Was die Konvertierung angeht, habe ich zuletzt in diesem Thema drueber erzaehlt. Bitte dort nachlesen und falls Fragen offen bleiben besser auch dort stellen.



  • Ok ich werds mir mal morgen durchlesen.

    Kennt vielleicht irgendwer ein Buch wo auch solche Sachen wie Konvertieren genau erklärt werden ?

    Weil von C++ da kenn ich das dass auch solche Sachen immer erklärt werden.



  • Wie schon gesagt: Wie du integer in Strings konvertierst ist ein ziemlich abstraktes Problem und hat nicht das Geringste mit Assembler zu tun.
    Assembler beinhaltet nun mal nicht wie die meisten Hochsprachen fertige Loesungen fuer solche Aufgaben.

    Seit jeher wird Assembler unter anderem deshalb auch nicht als Anfaengersprache angesehen. Da geht man idR. davon aus, es mit fortgeschritteneren Programmierern zu tun zu haben, die schon einige Erfahrung im Loesen von Problemen haben.
    So konzentrieren sich Buecher fuer Assembler-Einsteiger eben idR. auch nur auf die Vermittlung der grundlegenden Konzepte der Asm-Programmierung, statt abstrakte Programm-skizzen darzulegen oder all zu aufgeblasener (und dadurch auch potentiell verwirrende) Beispielcodes zu bringen.
    Sowas waeren wenn ueberhaupt eher fortgeschrittene Themen.

    Assembler unterscheidet sich eben doch recht deutlich von Hochsprachen. Du arbeitest direkt mit der CPU und die ist im Gegensatz zu dem, was du in abstrakten Hochsprachen kunstvoll basteln kannst eben doch recht primitiv.
    Wenn du in Assembler programmierst, wirst du noch oefter in Situationen geraten, die dir in Hochsprachen mit netten Funktionen und Libraries fuer jeden kleinen Mist vielleicht bisher gar nicht als im Grunde komplexe Probleme aufgefallen sind.
    Das ist vielleicht frustrierend, wenn man schnell tolle Ergebnisse sehen will, aber daran musst du dich bei Assembler eben gewoehnen. 🙂



  • ..



  • do
      {
        tenth = value / 10;
        *p++ = (char)(value - 10 * tenth + '0');
        value = tenth;
      }
      while (value != 0);
    

    hm... Ob das wohl von einem guten Compiler wirklich in sinnvoll optimierten Assembler-Code umgesetzt wird?

    Warum nicht einfach

    do
    {
      *p++ = (char)(value % 10) + '0';
      value /= 10;
    } while (value);
    

    ? 🙂



  • Ich hab nochmal genauer in meinem Buch geschaut und anscheind das gefunden was ich gesucht habe nur wenn ich es Assembliere funktioniert es nicht -.-

    So war der Quelltext auf der CD von dem Buch:

    .MODEL Small   ;EXE Datei
             .286           ;wegen pusha u. popa s.u.!
             .STACK 100h    
             .DATA        
    Puffer1  DB 6 DUP (?)   ;Puffer für das Resultat
             .CODE         
             mov  ax,@data  ;DS initialisieren
             mov  ds,ax
             mov  ax,1234   ;Diese Zahl ausgeben
             call Ausgabe   ;Proz. aufrufen
             mov  ah,4Ch    
             int  21h       ;Programm beenden!
    
    Ausgabe  PROC NEAR      ;Ausgabeprozedur
             pusha          ;Register sichern
             xor  cx,cx     ;CX=0=Zeichenzähler
             mov  di,OFFSET Puffer1+6  ;DI an Pufferende
             mov  bx,10     ;Nachher durch 10 dividieren
    
    Loop1:   xor  dx,dx     ;DX=0
             div  bx        ;AX/10, Rest in DX bzw. DL
             add  dl,30h    ;DL nach ASCII
             dec  di        ;DI-1
             mov  [di],dl   ;ASCII Ziffer in Puffer
             inc  cx        ;CX+1
             cmp  ax,0      ;Ist AX=0 ?
             jne  Loop1     ;Springe wenn nein
    
             mov  ah,40h    ;Funktionsnummer
             mov  bx,1      ;Handle-Nummer
             mov  dx,di     ;DS:DX auf String!
             int  21h       ;ASCII-Zahl ausgeben!
             popa           ;Register wiederherstellen
             ret            ;und zurück!
    Ausgabe  ENDP           ;Ende Prozedur
             END            ;Ende Programm
    

    Der Assembler sagt mir immer Fatal No Entrypoint und ich bekomme so einfach keine EXE Datei 😞

    Die Fertige EXE die mit dabei war die funktioniert nur wenn ich das selber Assemblieren will dann geht es nicht.

    So habe ich es auch schon versucht:

    Aber das funktionierte genau sowenig selbe Meldung.

    Was ist daran falsch an dem Quelltext?

    [code]
             .MODEL Small   ;EXE Datei
             .286           ;wegen pusha u. popa s.u.!
             .STACK 100h    
             .DATA        
    Puffer1  DB 6 DUP (?)   ;Puffer für das Resultat
             .CODE  
    start:       
             mov  ax,@data  ;DS initialisieren
             mov  ds,ax
             mov  ax,1234   ;Diese Zahl ausgeben
             call Ausgabe   ;Proz. aufrufen
             mov  ah,4Ch    
             int  21h       ;Programm beenden!
    
    Ausgabe  PROC NEAR      ;Ausgabeprozedur
             pusha          ;Register sichern
             xor  cx,cx     ;CX=0=Zeichenzähler
             mov  di,OFFSET Puffer1+6  ;DI an Pufferende
             mov  bx,10     ;Nachher durch 10 dividieren
    
    Loop1:   xor  dx,dx     ;DX=0
             div  bx        ;AX/10, Rest in DX bzw. DL
             add  dl,30h    ;DL nach ASCII
             dec  di        ;DI-1
             mov  [di],dl   ;ASCII Ziffer in Puffer
             inc  cx        ;CX+1
             cmp  ax,0      ;Ist AX=0 ?
             jne  Loop1     ;Springe wenn nein
    
             mov  ah,40h    ;Funktionsnummer
             mov  bx,1      ;Handle-Nummer
             mov  dx,di     ;DS:DX auf String!
             int  21h       ;ASCII-Zahl ausgeben!
             popa           ;Register wiederherstellen
             ret            ;und zurück!
    Ausgabe  ENDP           ;Ende Prozedur
    
             END start           ;Ende Programm
    


  • @Nobuo T: deine Idee wurde in PrettyOS bereits inkorporiert. Am i2hex musste ich auch noch etwas flicken. 😉



  • Weiss den keiner was an dem Quelltext da aus dem Buch falsch ist ? 😞

    btw das c-plusplus.net/forum hier steht sogar in dem Buch drin :>



  • TASM 4.1 frisst den Code (2. Version von hier ab Zeile 2 direkt in test.asm gepastet) ohne Murren (einfach "tasm test.asm"). Gelinkt, laeuft.
    Wie genau assemblierst und linkst du den Code also?



  • Funktioniert jetzt auch bei mir ka was ich da falsch gemacht habe.


Anmelden zum Antworten