Kellern und anzeigen



  • guten tag,

    hab ma ne assembler frage

    ich möchte 4 werte kellern, im keller um einen wert erhöhen und ausgeben, kriege aber nen ziemlich für mich unverständigen fehler

    .MODEL SMALL
    .STACK 100h
    .CODE
    START:
          MOV AH,1h    ; Speichert Wert in AH
          MOV BH,120h  ; Speichert Wert in BH
          MOV CX,2312h ; Speichert Wert in CX
          MOV DX,0h    ; Speichert Wert in DX
    
          PUSH AH ; Kellert AX
          PUSH BH ; Kellert BX
          PUSH CX ; Kellert CX
          PUSH DX ; Kellert DX
    
          INC AH ; Erhöht AH um 1
          INC BH ; Erhöht BH um 1
          DEC CX ; Vermindert CX um 1
          DEC DX ; Vermindert DX um 1  
    
          //MOV SI,SP ; Umspeichern des Stackointers
          //MOV CX,SS:[SI+2] ; Liest vorletztes Kellerwort
    
          POP AH ; Kellert AH aus
          POP BH ; Kellert BH aus
          POP CX ; Kellert CX aus
          POP DX ; Kellert DX aus
    
          MOV AH,4Ch
          INT 21h
    END START
    

    Wäre um jeden tip dankbar, tschau



  • Hi.

    Allgemein:
    Wenn du von einem Fehler sprichst, waere es meistens hilfreich, wenn du diesen auch genauer erklaeren koenntest - ggf. die Fehlermeldung zitieren.

    In deinem Code stecken 4Fehler, die den selben Ursprung haben:
    push/pop arbeiten nur mit 16/32Bit breiten Operanden - push ah/bh oder pop ah/bh funktioniert also nicht.

    Dass dein Code weder irgendwelche Zahlen auf dem Bildschirm ausgibt, noch die auf dem Stack geparkten Werte veraendert, hast du vermutlich auch schon selbst bemerkt.

    BTW: Sind "Keller" und "kellern" bzw. "auskellern" nun neue allgemein anerkannte Begriffe im Zusammenhang mit og. Stackoperationen, oder habe ich nun irgendwas verpasst? 🙄



  • danke für die antwort.

    wie du richtg vermutest hast ist der fehler bei den AH und BH Registern, nur ich weiss nicht wie ich das aendern soll, bin noch ziemlich unerfahren in assembler und kellern etc. hat uns unser lehrer so beigebracht damals. das steckt nun drinne 😉


  • Mod

    der begriff des 'kellerns' ist eigentlich recht alt, er stammt noch aus zeiten, in denen nicht alles und jedes mit anglizismen ausgedrückt werden musste - was auch interessante wortnutzungen zur folge hatte (frag aber nicht, wieso es nicht naheliegend stapeln genannt wurde - ich tippe mal, das es daran liegt, das stacks i.a. nach unten wachsen...) 🙂

    @honeytonkey:
    du bist vermutlich auf etwas in diesem stile aus:

    .model small
    .stack 100h
    .code
    start:
          mov    ah, 1
          mov    bx, 120h
          mov    cx, 2312h
          xor    dx, dx
    
          push   ax
          push   bx
          push   cx
          push   dx
          mov    bp, sp
    
          inc    byte ptr [bp+7]  ; ah - [bp] nutzt den stack
          inc    word ptr [bp+4]  ; bx
          dec    word ptr [bp+2]  ; cx
          dec    word ptr [bp]    ; dx
    
          pop    dx               ; in umgekehrter reihenfolge
          pop    cx               ; wenn du etwas stapelst, kannst du
          pop    bx               ; auch nur von oben wegnehmen
          pop    ax
    
          mov    ah, 4ch
          int    21h
    
    end start
    

    insofern waren noch mehr fehler drin: falsche reihenfolge beim pop - und 120h passt nicht in bh



  • das klappt auch noch nich so wie es sollte, aber danke trotzdem.

    kriege da bei den beiden decrements error.

    für weitere hilfe jederzeit dankbar, tschau 🙂



  • Was für errors kann man da bekommen?



  • C:\Temp\cpptrain\tempsrc.exe wurde nicht erzeugt und nicht gestartet!
    Assembling:
    TEMPSRC.ASM: Error Line 19 : DEC WORD PTR [BP]^
    Unerlaubtes Indexregister.

    Diesen Error bekomme ich 😞


  • Mod

    was ist denn das für ein unbrauchbarer assembler? wenn [bp] nicht geht, wohl aber der rest, versuchs doch mal mit [bp+0] (es ist schon klar, dass bp nur zusammen mit einem anderen indexregister - SI oder DI - und/oder displacement verwendet werden kann, jeder vernünftige assembler fügt aber +0 automatisch hinzu)



  • Ah, alles klar, und wie geb ich das nun aus?

    Dachte mit dem

    lea dx
    int 21h

    lea cx
    int 21h

    etc.

    aber so gehts auch noch nich, muss mich wohl nich ziemlich damit befassen, danke soweit schonmal!


  • Mod

    kommt drauf an, was genau du ausgeben willst, wenn du registerinhalte ausgeben willst, brauchst du zunächst eine funktion, die dessen inhalt in eine geeignete zeichenkette umwandelt, um lesbar zu sein, hier mal eine möglichkeit:

    AX2stdout  proc    near           ; gibt ax als 4stelligen hexstring aus
               push    ax
               push    dx
               push    cx
               mov     cx, ax
               shr     ax, 12         ; (AH&0xf)>>4
               add     al, 0          ; clear AF
               mov     dl, 30h        ; = '0'
               aaa                    ; adjust: if ( AL > 9 ) AL = AL + 6 (und AH=1)
               add     dl, al         ; DL='0'...'9', 'A'...'F'
               mov     ah, 02h
               int     21h            ; erstes zeichen
               mov     al, ch
               and     al, 0fh
               add     al, 0
               mov     dl, 30h
               aaa
               add     dl, al
               int     21h
               mov     al, cl
               shr     al, 4
               add     al, 0
               mov     dl, 30h
               add     dl, al
               int     21h
               mov     al, cl
               and     al, 0fh
               add     al, 0
               mov     dl, 30h
               aaa
               add     dl, al
               int     21h
               pop     cx
               pop     dx
               pop     ax
               ret
    AX2stdout  endp
    

    ungetestet, hab ich mir grad aus den fingern gesogen, man kann es sicher besser machen - das ganze einfach mit call AX2stdout aufrufen, damit hast du erstmal eine möglichkeit, überhaupt werte auszugeben - es in dein programm einzubauen überlass ich dir 😉

    lea benötigt zwei operanden; eigentlich ist es - bis auf ein paar ausnahmen - kein sonderlich nützlicher befehl. er hat die form
    lea reg, [mem]
    wobei nicht auf den speicher zugegriffen wird, lediglich die effektive adresse, auf die mem verweist wird berechnet und dann reg zugewiesen. allerdings ist er deutlich langsamer als add oder mov. folglich ist bei statischen variablen ein mov reg, offset var
    immer schneller als
    lea reg, var
    interessanter ist lea daher nur bei komplexer adressierung, aufgrund der beschränkten adressierungsmöglichkeiten im 16bit modus dort allerdings seltener. der wesentliche semantische unterschied zu add ist, das ziel und quelle nicht identisch sein müssen (und man bis zu drei werte - zwei register und eine konstante addieren kann), ausserdem werden keine flags beeinflusst.
    im 32bit modus kann man es u.a. zum schnellen multiplizieren mit 3,5 und 9 verwenden.


Anmelden zum Antworten