&-operator funktioniert unter nasm nicht!?
-
Hi Leute,
ich bin noch ein asm-anfänger und arbeite mit nasm, jedoch funktioniert dort der &-Operator für die Substitution von Namen nicht.
Folgendes Codebeispiel:
org 100h segment .data Zaehler db 0 m0 db 'Message 1',10,13,'$' m1 db 'Message 2',10,13,'$' m2 db 'Message 3',10,13,'$' m3 db 'Message 4',10,13,'$' segment .text mov ecx, 4 ;Counter auf 4 setzen Schleife: lea dx, [m&Zaehler] ;String laden mov ah, 9 ;Funktion zum ausgeben eines Strings int 21h loop Schleife ;wenn ecx nicht 0, dann springe zu Schleife ende: mov ah, 4Ch ;beendet das int 21h ;Programm ends
Dort gibt nasm folgenden Fehler aus: '&' operator may only be applied to scalar values
Was genau bedeutet das und wie kann ich den Code entsprechend zum laufen bekommen?
Bin für jede Hilfe dankbar.
-
Hi.
Tja, Assembler ist eben keine Hochsprache. Hier wird das was du schreibst direkt umgesetzt (so sollte es IMHO zumindest sein - deshalb ist MASM auch boese :D). Deshalb kann die Substitution von Variablennamen mit anderen Variablen (die ja schliesslich zur Laufzeit veraendert werden koennen) nicht funktionieren.
In deinem Fall, wo die Texte alle gleich lang sind, waere es IMHO am einfachsten, vor der Schleife das Offset des ersten Textes zB. in di zu laden, in der Schleife dann zuerst di nach dx zu kopieren und anschliessend die Laenge eines Strings auf di zu addieren.
Falls die Strings unterschiedlich lang sind, ist es vielleicht am einfachsten, ein Array anzulegen, das die Offsets der Texte beinhaltet. Du koenntest dann vor der Schleife das Offset des Arrays zB. in si schreiben und in der Schleife dann ueber si das Offset des Strings aus dem Array nach dx kopieren und anschliessend si um 2 erhoehen (um das naechste Element des Arrays auszuwaehlen - ich gehe von 16Bit-Offsets im Array aus).
So, und um dich jetzt noch vollkommen zu verwirren:
DOS-Programme beinhalten ueblicherweise 16Bit-Code. Die loop-instruktion wird also nur cx beeinflussen und nicht ecx.
lea nur fuer das Laden eines einfachen Offsets zu missbrauchen, so wie du das in deinem Code tust, ist ineffizient. Deshalb uebersetzen die meisten Assembler sowas schon von selbst als "mov reg, offset".
Waere also vielleicht sinnvoller, wenn du das schon von selbst "richtig" schreibst.
Fuer den NASM muesstest du also statt "lea dx, [m0]" -> "mov dx, m0" schreiben.
-
Hi Nobuo T,
danke für die Antwort, ich werde das mal so versuchen umzusetzen.
Ich hatte mir das schon fast gedacht, dass das eigentlich nicht normal so funktioniert, das sich durch die Substitution der Variablennamen mit anderen Variablen während der Laufzeit verändern kann, oder so ähnlich.
Danke auch für den Hinweis mit 'lea'.
-
So, ich habs jetzt endlich fertiggestellt. Hatte wenig Zeit in letzter Zeit um mich darum zu kümmern.
Die beste und wohl einfachste Lösung für mich bestand jetzt darin, dass ich die Anfangsadressen der Strings in umgekehrter Reihenfolge auf den Stack ablege und dann in der Schleife nach und nach wieder vom Stack hole, eigentlich ganz simpel.Hier der Code dazu:
org 100h segment .data Zaehler db 0 m0 db 'Message 1',10,13,'$' m1 db 'Message 2',10,13,'$' m2 db 'Message 3',10,13,'$' m3 db 'Message 4',10,13,'$' segment .text mov cx, 4 ;Counter auf 4 setzen push WORD m3 push WORD m2 push WORD m1 push WORD m0 Schleife: pop dx ;String vom Stack laden mov ah, 9 ;Funktion zum ausgeben eines Strings int 21h loop Schleife ;wenn cx nicht 0, dann springe zu Schleife ende: mov ah, 4Ch ;beendet das int 21h ;Programm ends