Forum: Mikrocontroller und Digitale Elektronik Assembler variablen, var+x


von Peter93 (Gast)


Lesenswert?

Guten Abend,
ich habe eine kurze Frage:

wenn ich eine Varbiale habe:
var dw 0,0FFFh,0FFh

mov ax,var dann steht im ax ja 0h
mov ax,var+2 dann steht im ax 0FFh

was passiert aber, wenn ich schreibe:

mov ax,var+4 ? var+4 ist ja nicht mehr definiert

Danke für eure Antworten

von Heinz V. (heinz_v)


Lesenswert?

Peter93 schrieb:
> wenn ich eine Varbiale habe:
> var dw 0,0FFFh,0FFh
>
> mov ax,var dann steht im ax ja 0h
> mov ax,var+2 dann steht im ax 0FFh
>
> was passiert aber, wenn ich schreibe:
>
> mov ax,var+4 ? var+4 ist ja nicht mehr definiert
Du lädst praktisch einen Zufallswert in AX
wenn 'var' sich am Ende deines Programms befindet gibt es möglicherweise 
unter Windows eine memory_page_read_exception denn dein Programm 
versucht (lesend) auf eine Speicherseite zuzugreifen für die es nicht 
zugelassen ist.

von c-hater (Gast)


Lesenswert?

Peter93 schrieb:

> mov ax,var dann steht im ax ja 0h

Ja.

> mov ax,var+2 dann steht im ax 0FFh

Nö.

> was passiert aber, wenn ich schreibe:
>
> mov ax,var+4 ? var+4 ist ja nicht mehr definiert

Doch, ist es.

von Peter93 (Gast)


Lesenswert?

c-hater schrieb:
>> mov ax,var+2 dann steht im ax 0FFh
>
> Nö.
>
>> was passiert aber, wenn ich schreibe:
>>
>> mov ax,var+4 ? var+4 ist ja nicht mehr definiert
>
> Doch, ist es.

wie ist es denn richtig?

von Heinz V. (heinz_v)


Lesenswert?

klar mit var+2 landest Du beim nächsten Word nicht beim Übernächsten.
LODSW, STOSW, SCASW inkrementieren (E)SI und (E)DX um 2, aber die 2 in 
den Pseudoopcodes wird vom Assembler als 2 = +zwei Bites 'weiter' 
interpretiert.

von c-hater (Gast)


Lesenswert?

Peter93 schrieb:

> wie ist es denn richtig?

Lies' einfach die verfickte "instruction set reference" von Intel. Die 
erklärt ausführlich und in jedem Detail, was jede einzelne Instruktion 
tut...

Verwirrung kann höchstens noch durch abweichende Notationen anderer 
Assembler (im Vergleich zu Intels eigenem) auftreten.

Je näher an C die Dinger sind, desto abstruser wird deren Notation, bis 
sie dann mit C selber (als de-facto-Macroassembler) endgültig die 
ultimative Verwirrung gestiftet wird...

von Peter93 (Gast)


Lesenswert?

also ist es so richtig: var dw 0,0FFFh,0FFh

var 0 = 0
var+2=0FFFh
var+4=0FFh

?

von Heinz V. (heinz_v)


Lesenswert?

Peter93 schrieb:
>>> mov ax,var+2 dann steht im ax 0FFh

Die Addresse var+2 wird bei z.B. MASM oder A86/A386 während des 
Assemblierens berechnet, sie wird nicht von der CPU zur Programmlaufzeit 
berechnet.

von Heinz V. (heinz_v)


Lesenswert?

Peter93 schrieb:
> var dw 0,0FFFh,0FFh

00 00 0f ff 00 ff
0. 1. 2. 3. 4. 5.  Byte

0000 0fff 00ff
0.   1.   2.       Word

von c-hater (Gast)


Lesenswert?

Heinz V. schrieb:

> Die Addresse var+2 wird bei z.B. MASM oder A86/A386 während des
> Assemblierens berechnet, sie wird nicht von der CPU zur Programmlaufzeit
> berechnet.

Genauso ist es.

Im Prinzip ist es immer die gleiche Instruktion, nämlich "lade 
16Bit-Register mit dem Inhalt zweier aufeinander folgender Bytes im 
Speicher, beginnend mit Adresse XYZ". Und XYZ wird halt schon zur 
Assemblierzeit vom Assembler berechnet, weil der schon alles darüber 
weiss: Basisadresse (also "var") und Offset, also das, was nach dem 
"var+" steht.

Die Addressierungsart (man nennt sie "direkt") und die Unterstützung zu 
deren Verwendung mit Entwurfszeit-Offsets findet man praktisch in fast 
jedem Assembler fast jeder Architektur. Nur ganz früher(tm), als 
Assembler mangels genug Speicher zur Assemblierzeit noch nicht selber 
mathematische Ausdrücke interpretieren und berechnen konnten, da musste 
man selbst Hand anlegen und tatsächlich jede Speicheradresse selbst 
ausrechnen. Ging aber irgendwie auch damit, funktionierende Programme zu 
schreiben...

von (prx) A. K. (prx)


Lesenswert?

Heinz V. schrieb:
>> var dw 0,0FFFh,0FFh
>
> 00 00 0f ff 00 ff
> 0. 1. 2. 3. 4. 5.  Byte

Nö. So nicht.

00 00 ff 0f ff 00

: Bearbeitet durch User
von Peter93 (Gast)


Lesenswert?

okay ich denke ich habe es Verstanden! Kannst du mir zur Kontrolle 
sagen, ob dies richtig ist:

var dw 0, 0FFFh, 0FFh, 255, 377o
       0    1      2     3    4   Word

00 00 , 0F FF , 00 FF , 00  FF , 00 FF
0  1    2   3    4  5   6   7    8   9   Byte

also wäre bei  mov ax, var+7  00FF im ax register?

von Heinz V. (heinz_v)


Lesenswert?

ja stimmt little Endian <> big Endian

von Peter93 (Gast)


Lesenswert?

Heinz V. schrieb:
> ja stimmt little Endian <> big Endian

somit also auch in dem anderen Beispiel: FF00h

von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
> Die Addressierungsart (man nennt sie "direkt") und die Unterstützung zu
> deren Verwendung mit Entwurfszeit-Offsets findet man praktisch in fast
> jedem Assembler fast jeder Architektur.

Nö. Bei RISC Architekturen mit fester Befehlslänge findet man eine 
direkte Adressierung üblicherweise nicht.

Nicht einmal alle Architekturen mit variabler Befehlslänge unterstützen 
eine direkte Datenadressierung - IBMs Mainframes nicht, aber 
beispielsweise auch nicht die 8-Bitter 1802 und SC/MP.

: Bearbeitet durch User
von Peter93 (Gast)


Lesenswert?

Ich habe noch eine kurze Frage, für die ich nicht extra einen Thread 
aufmachen möchte!
add ax, 6[cx]

Wofür steht diese 6 und was macht sie genau?

von c-hater (Gast)


Lesenswert?

A. K. schrieb:

> Nö. Bei RISC Architekturen mit fester Befehlslänge findet man eine
> direkte Adressierung üblicherweise nicht.

Oops...

AVR8 ist RISC, jedenfalls nach Aussage von Atmel. Gibt es dort direkte 
Adressierung? Natürlich. "lds" und "sts".

Allerdings ist es nicht "reines" RISC nach deiner Definition (die ganz 
offensichtlich irgendwie von der aller anderen doch etwas abweicht). 
Nicht jedes Befehlswort hat beim AVR8 die gleiche Länge.

Aber wir brauche uns da auch überhaupt nicht drüber zu streiten. Ich 
habe natürlich in weiser Voraussicht überall ein "fast" in meine 
Aussagen eingebaut. Ich bin ja nicht blöd.

Aber natürlich: wenn man sich die Relevanz von Systemen ohne direkte 
Adressierung anschaut (die jemals erreichte oder gar erst die heutige), 
dann ist meine Aussage doch mehr als berechtigt. Findest du nicht auch?

von c-hater (Gast)


Lesenswert?

c-hater schrieb:

> Aber natürlich: wenn man sich die Relevanz von Systemen ohne direkte
> Adressierung anschaut (die jemals erreichte oder gar erst die heutige),
> dann ist meine Aussage doch mehr als berechtigt. Findest du nicht auch?

Nachsatz:

Natürlich seien hier die System einbezogen, die tatsächlich keine echte 
direkte Addressierung kennen, sondern ausschließlich direkte 
Adressierung mit Offset. Mit Offset 0 ist das ja dann auch nur direkte 
Adressierung.

Aber klar: hier tut sich dann wieder das Minenfeld der 
Pseudoinstruktionen auf...

von Heinz V. (heinz_v)


Lesenswert?

Peter93 schrieb:
> add ax, 6[cx]
>
> Wofür steht diese 6 und was macht sie genau?

steht da wirklich 6 oder steht da b?

von Peter93 (Gast)


Lesenswert?

Da steht wirklich eine 6, kenne das normal nur mit feld[si+bx] , deshalb 
wundere ich mich gerade

von c-hater (Gast)


Lesenswert?

Peter93 schrieb:

> Ich habe noch eine kurze Frage, für die ich nicht extra einen Thread
> aufmachen möchte!
> add ax, 6[cx]
>
> Wofür steht diese 6 und was macht sie genau?

Ach wieder bloß ein Adressoffset. Hier allerdings der Offset einer 
indirekten Adressierung.

Also: Adresse ist der Inhalt von cx, dann wird nochmal 6 draufgezählt, 
um die tatsächlich anzusprechende Speicheradresse zu ermitteln.

Lies' endlich diese verfickte instruction set reference!

von Heinz V. (heinz_v)


Lesenswert?

c-hater schrieb:
> Also: Adresse ist der Inhalt von cx, dann wird nochmal 6 draufgezählt,
> um die tatsächlich anzusprechende Speicheradresse zu ermitteln.

wäre das denn identisch mit add ax, [cx+6]?

von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
> Allerdings ist es nicht "reines" RISC nach deiner Definition (die ganz
> offensichtlich irgendwie von der aller anderen doch etwas abweicht).

ARM hat in allen 3 Varianten (klassisch, Thumb, 64bit) keine direkte 
Adressierung. PowerPC nicht, MIPS nicht, Alpha nicht, 88000 nicht, 29000 
nicht, ...

Mir fällt als RISC mit direkter Adressierung nur AVR ein.

> Aber natürlich: wenn man sich die Relevanz von Systemen ohne direkte
> Adressierung anschaut (die jemals erreichte oder gar erst die heutige),
> dann ist meine Aussage doch mehr als berechtigt. Findest du nicht auch?

Nö, finde ich nicht. Auch weil in der Programmierung jenseits kleiner 
Mikrocontroller die Häufigkeit direkter Adressierung von Daten weitaus 
geringer ist als Adressierung relativ zu einem Register. Statisch 
adressierte Skalare sind weit seltener als relativ adressierte Daten 
aller Art.

Ok, wer Programmiersprachen jenseits Assembler hasst, der hasst 
natürlich auch solche Programmiertechnik und legt grossen Wert auf 
direkte Adressierung. ;-)

PS: Bei 64-Bit x86 wurde die direkte Adressierung durch PC-relative 
Adressierung effektiv abgelöst, auch wenn es die direkte Adressierung 
noch gibt.

PPS: Auch 8051 kann nur sehr wenig Daten direkt adressieren.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
> Lies' endlich diese verfickte instruction set reference!

Das sind bei x86 Stand 2015 rund 2000 Seiten. Plus weiterer 1600 Seiten, 
wenn man nicht nur Anwendungen programmiert. ;-)

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.