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
-
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
-
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 21hlea cx
int 21hetc.
aber so gehts auch noch nich, muss mich wohl nich ziemlich damit befassen, danke soweit schonmal!
-
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.