Mixing ASM and BASIC/de

From MCS Wiki AVR
< Mixing ASM and BASIC(Difference between revisions)
Jump to: navigation, search
(Umformung)
 
(127 intermediate revisions by one user not shown)
Line 1: Line 1:
BASIC und Assembler mischen
 
  
BASCOM gestattet das mischen von BASIC mit Assembler-Code, was in den Fällen nützlich sein kann, in denen sie vollen Einfluss auf den generierten Code nehmen wollen.
+
== '''BASIC und Assembler mischen''' ==
 +
 
 +
  Dieses Kapitel darf nicht als Unterrichtung in Assemblerprogammierung verstanden werden.
 +
  Wenn Sie ein spezielles Thema zur Verwendung  von Assembler in BASCOM vermissen, teilen Sie uns das per Email mit.
 +
 
 +
 
 +
BASCOM gestattet das mischen von BASIC mit Assembler-Code, was in den Fällen nützlich sein kann, in denen Sie vollen Einfluss auf den generierten Code nehmen wollen.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Nahezu alle Assembler-Mnemonics werden von Compiler direkt unterstütz. Die Ausnahmen sind SWAP, CALL und OUT. Das sind reservierte BASIC-Befehle und haben Vorrang gegenüber Assembler-Mnemonics.
+
Nahezu alle Assembler-Mnemonics werden vom Compiler direkt unterstütz. Die Ausnahmen sind SWAP, CALL und OUT. Das sind reservierte BASIC-Befehle und haben Vorrang gegenüber Assembler-Mnemonics.
  
Um diese Mnemonics verwenden zu können werden ihnen ein Ausrufezeichen (!) vorangestellt.
+
Um diese Mnemonics verwenden zu können wird ihnen ein Ausrufezeichen (!) vorangestellt.
  
 
&nbsp;
 
&nbsp;
Line 13: Line 18:
 
[[File:Notice.jpg|notice]]Es wird empfohlen immer das<span style="font-weight: bold;">&nbsp;!&nbsp;</span>oder einen $ASM … $End ASM –Block zu verwenden.
 
[[File:Notice.jpg|notice]]Es wird empfohlen immer das<span style="font-weight: bold;">&nbsp;!&nbsp;</span>oder einen $ASM … $End ASM –Block zu verwenden.
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 +
  
 
Beispiel&nbsp;:
 
Beispiel&nbsp;:
Line 18: Line 24:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Dim a As Byte At &H60 'A is stored at location &H60
+
    Dim a As Byte At &H60 'A is stored at location &H60
 +
    Ldi R27 , $00 &nbsp; 'Load R27 with MSB of address
 +
    Ldi R26 , $60 &nbsp; 'Load R26 with LSB of address
 +
    Ld R1, X &nbsp; 'load memory location $60 into R1
 +
    <span style="font-weight: bold;">!</span>SWAP R1 &nbsp; 'swap nibbles
  
Ldi R27 , $00 &nbsp; 'Load R27 with MSB of address
+
<span style="font-family: Arial;">&nbsp;</span>
  
Ldi R26 , $60 &nbsp; 'Load R26 with LSB of address
+
Wie Sie sehen, wurde dem Mnemonik SWAP ein Ausrufezeichen&nbsp;<span style="font-weight: bold;">!</span>&nbsp; vorangestellt.
 
+
Ld R1, X &nbsp; 'load memory location $60 into R1
+
 
+
<span style="font-weight: bold;">!</span>SWAP R1 &nbsp; 'swap nibbles
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Wie sie sehen, wurde dem Menemonik SWAP ein Ausrufezeichen.&nbsp;<span style="font-weight: bold;">!</span>&nbsp; vorangestellt.
+
Eine andere Option ist die Verwendung eines einschließenden $ASM/ $END ASM - Blocks:
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Another option is to use the assembler block directives:
+
    <span style="font-weight: bold;">$ASM</span>
 +
    LDI R27 , $00 &nbsp; 'Load R27 with MSB of address
 +
    LDI R26 , $60 &nbsp; 'Load R26 with LSB of address
 +
    LDI R1  , X &nbsp; &nbsp;'load memory location $60 into R1
 +
    SWAP R1 &nbsp; 'swap nibbles
 +
    <span style="font-weight: bold;">$END ASM</span>
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
<span style="font-weight: bold;">$ASM</span>
+
== '''Assembler-Hilfsfunktion''' ==
  
Ldi R27 , $00 &nbsp; 'Load R27 with MSB of address
 
  
Ldi R26 , $60 &nbsp; 'Load R26 with LSB of address
+
Eine spezielle Assembler-Hilfsfunktion unterstützt das Laden von Adressen in die Register X oder Z. 
 +
Das Y-Register sollte nicht verwendet werden da dieses bereits als Zeiger auf den Software-Stack verwendet wird.
  
Ld R1, X &nbsp; &nbsp;'load memory location $60 into R1
+
<span style="font-family: Arial;">&nbsp;</span>
  
SWAP R1 &nbsp; 'swap nibbles
+
  Dim A As Byte &nbsp;'reserve space
 
+
  LOADADR a, X &nbsp;'load address of variable named A into register pair X
<span style="font-weight: bold;">$END ASM</span>
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
A special assembler helper function is provided to load the address into the register X or Z. Y can may not be used because it is used as the soft stack pointer.
+
Nachfolgender Code hat den gleichen Effekt &nbsp;:
 +
  LDI R26 , $60 'for example&nbsp;!
 +
  LDI R27, $00 'for example&nbsp;!
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
Dim A As Byte &nbsp;'reserve space
 
 
LOADADR a, X &nbsp;'load address of variable named A into register pair X
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
This has the same effect as&nbsp;:
+
== '''Von Bascom verwendete Register''' ==
  
Ldi R26 , $60 'for example&nbsp;!
 
  
Ldi R27, $00 'for example&nbsp;!
 
  
<span style="font-family: Arial;">&nbsp;</span>
+
R4 und R5  werden als Zeiger auf den Stack-Frame oder zur temporären Datensicherung verwendet.
 +
  
<span style="font-family: Arial;">&nbsp;</span>
+
R6 dient zur Speicherung von Bit-Variablen:
  
Some registers are used by BASCOM
+
-  bit 0 = Flag für Integer/Word Umwandlungen
  
R4 and R5 are used to point to the stack frame or the temp data storage
+
-  bit 1 = Temporärer Bit-Speicher beim Tauschen von Bits
  
R6 is used to store some bit variables:
+
bit 2 = Fehler-Bit (ERR - Variable)
  
R6 bit 0 = flag for integer/word conversion
+
bit 3 = Anzeigen/Nicht Anzeigen - Flag bei dem INPUT-Befehl
  
R6 bit 1 = temp bit space used for swapping bits
 
  
R6 bit 2 = error bit (ERR variable)
+
R8 und R9 dienen als Datenzeiger für den READ-Befehl.
 
+
R6 bit 3 = show/noshow flag when using INPUT statement
+
 
+
R8 and R9 are used as a data pointer for the READ statement.
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
All other registers are used depending on the used statements.
+
Alle anderen Register werden Befehlsabhängig verwendet
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
To Load the address of a variable you must enclose them in brackets.
+
== '''Laden von Variablen-Adressen''' ==
  
Dim B As Bit
+
Um die Adresse einer Variable zu laden, muß dessen Name in geschwungenen Klammern eingeschlossen sein.
 
+
    Dim B As Bit
Lds R16, {B} 'will replace {B} with the address of variable B
+
    LDS R16, {B} '{B} wird durch die Adresse der Variablen B ersetzt.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
Line 104: Line 106:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
To refer to the bit number you must precede the variable name by BIT.
+
Um auf ein Bit zu verweisen, muss der Variablen der Ausdruck BIT. vorangestellt sein.
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Sbrs R16 , BIT.B &nbsp;'notice the point!
+
    SBRS R16 , BIT.B &nbsp;'Beachten sie den Punkt!
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
Da B das erste dimensionierte Bit ist, erhält B die Bitnummer 0.
Since this was the first dimensioned bit the bit number is 0. Bits are stored in bytes and the first dimensioned bit goes in the LS (least significant) bit.
+
Bits werden zu Bytes zusammengefasst gespeichert. Das erste dimensionierte Bit geht in das niederwertigste Bit ein, usw.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
<span style="font-family: Arial;">&nbsp;</span>
+
== '''Laden von Label-Adressen''' ==
 
+
To load an address of a label you must use&nbsp;:
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
LDI ZL, Low(lbl * 1)
+
Um die Adresse eines Labels zu laden, schreiben sie&nbsp;:
 
+
LDI ZH , High(lbl * 1)
+
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Where ZL = R30 and may be R24, R26, R28 or R30
+
LDI ZL, Low(lbl * 1)
 +
LDI ZH , High(lbl * 1)
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
And ZH = R31 and may be R25, R27, R29 or R31.
+
wobei  ZL  auch R30, R24, R26, R28 oder R30, und ZH gleichermaßen R31, R25, R27, R29 oder R31 sein kann.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
These are so called register pairs that form a pointer.
+
Das sind sogenannte Registerpaare mit denen  Zeiger gebildet werden können.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
Line 142: Line 139:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
When you want to use the LPM instruction to retrieve data you must multiply the address with 2 since the AVR object code consist of words.
+
Wenn Sie mit einer LPM – Instruktion (LOAD-PROGRAMM_MEMORY) Daten aus dem Programmspeicher laden wollen, muss die Adresse mit 2 multipliziert werden,
 +
da der Programmspeicher wortorganisiert ist (16Bit).
 +
  
LDI ZL, Low(lbl * 2)
+
LDI ZL, Low(lbl * 2)
 +
LDI ZH , High(lbl * 2)
 +
LPM&nbsp;; get data into R0
 +
....
 +
Lbl:
 +
.....
  
LDI ZH , High(lbl * 2)
+
== '''Einige wichtige Punkte''' ==
 
+
LPM&nbsp;; get data into R0
+
 
+
Lbl:
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
Line 156: Line 156:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Atmel mnemonics must be used to program in assembly.
+
Um in Assembler zu programmieren müssen Atmel Mnemonics verwendet werden.
 
+
In den Datenblättern der jeweiligen Mikrocontroller die Sie unter www.atmel.com herunterladen können, finden sie den entsprechenden Befehlsvorrat.
You can download the pdf from www.atmel.com that shows how the different mnemonics are used.
+
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Some points of attention&nbsp;:
 
  
*All instructions that use a constant as a parameter only work on the upper 16 registers (r16-r31)
+
*Alle Befehle die eine Konstanten verwenden, arbeiten ausschließlich mit den oberen 16 Registern R16 bis R31.
  
So LDI R15,12 WILL NOT WORK
+
!LDI R15, 12     funktioniert also nicht.     
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
Line 172: Line 169:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
*The instruction SBR register, K
+
*Der Befehl    SBR reg , K
 
+
will work with K from 0-255. So you can set multiple bits!
+
  
 +
K kann ein Wert von 0 bis 255 sein. So können mehrere Bits gleichzeitig gesetzt werden.
 +
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
The instruction SBI port, K will work with K from 0-7 and will set only ONE bit in a IO-port register.
+
Mit dem Befehl SBI port , K   hingegen kann immer nur ein Bit setzen, da K nur 0 bis 7 sein kann.
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
The same applies to the CBR and CBI instructions.
+
Das Gleiche gilt für die Befehle CBR und CBI.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
Line 188: Line 184:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
You can use constants too:
+
Sie können für K ebenfalls symbolische Konstante verwenden:
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
.equ myval = (10+2)/4
+
  .equ myval = (10+2)/4
 
+
  ldi R24,myval+2 '5
ldi r24,myval+2 '5
+
  ldi R24,asc("A")+1&nbsp;; load with 66
 
+
ldi r24,asc("A")+1&nbsp;; load with 66
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
Line 202: Line 196:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Or in BASIC with CONST&nbsp;:
+
Oder in BASIC mit CONST&nbsp;:
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
CONST Myval = (10+2) / 4
+
  CONST Myval = (10+2) / 4
 
+
  LDI R24, myval
Ldi r24,myval
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
Line 214: Line 207:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
How to make your own libraries and call them from BASIC?
+
== '''Bibliotheken (.lib) erstellen''' ==
  
The files for this sample can be found as libdemo.bas in the SAMPLES dir and as mylib.lib in the LIB dir.
+
Wie erstellt man eine eigene Bibliothek und verwendet diese mit BASIC?
  
<span style="font-family: Arial;">&nbsp;</span>
+
Die Dateien zu diesem Beispiel finden sie im BASCOM-Installationsverzeichnis unter \SAMPLES\libdemo.bas und unter \LIB\mylib.lib.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
First determine the used parameters and their type.
 
 
Also consider if they are passed by reference or by value
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
<span style="font-family: Arial;">&nbsp;</span>
+
Zu Beginn bestimmen Sie die zu verwendenden Parameter und ihre Datentypen.
  
For example the sub test has two parameters:
+
Überlegen Sie außerdem ob die Parameter Byref oder Byval übergeben werden sollen.
  
x which is passed by value (copy of the variable)
 
  
y which is passed by reference(address of the variable)
+
- "ByRev" : Die Adresse der übergebenen Variable wird an eine Prozedur übergeben. So wird der Inhalt der Variable direkt bearbeitet.
  
 +
- "ByVal" : Eine Kopie des Parameterinhaltes wird übergeben. Der Inhalt der übergebenen Quellvariable bleibt unangetastet.
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
In both cases the address of the variable is put on the soft stack which is indexed by the Y pointer.
+
Beispiel:
  
<span style="font-family: Arial;">&nbsp;</span>
+
Eine Subroutine namens "test" erwartet zwei Parameter:
  
<span style="font-family: Arial;">&nbsp;</span>
+
  x die byval übergeben wird (eine Kopie. Kopien werden temporär in den Stack-Fame-Bereich geschrieben)
 
+
  y die byref übergeben wird (die Adresse der Variablen)
The first parameter (or a copy) is put on the soft stack first
+
 
+
To refer to the address you must use:
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
ldd r26 , y + 0
 
 
ldd r27 , y + 1
 
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
This loads the address into pointer X
+
In beiden Fällen wird die Adresse der Variablen auf den SoftStack gebracht, welcher mit dem Y-Zeiger verwaltet wird.
 
+
The second parameter will also be put on the soft stack so&nbsp;:
+
 
+
The reference for the x variable will be changed&nbsp;:
+
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
To refer to the address of x you must use:
+
Der erste Parameter x (genauer: die Adresse seiner Kopie) wird dem Soft-Stack auferlegt.
 
+
ldd r26 , y + 2
+
 
+
ldd r27 , y + 3
+
  
 +
An diese Adresse gelangen sie durch:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
LDD R26 , Y + 0
 +
LDD R27 , Y + 1
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 +
Die Adresse steht nun im Registerpaar X (R26,R27) oder im X-Zeiger. 
  
 +
Da ein zweiter Parameter, oder besser dessen Adresse ebenfalls auf dem Soft-Stack gebracht werden soll,
 +
ändert sich jedoch die Verschiebegröße auf den Y-Zeiger um an die Adresse von x zu gelangen&nbsp;:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
To refer to the last parameter y you must use
 
 
ldd r26 , y + 0
 
 
ldd r27 , y + 1
 
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
Write the sub routine as you are used too but include the name within brackets []
+
x wird dadurch also so refenziert:
 
+
LDD R26 , Y + 2
 +
LDD R27 , Y + 3
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
[test]
 
 
test:
 
 
ldd r26,y+2&nbsp;; load address of x
 
 
ldd r27,y+3
 
 
ld r24,x&nbsp;; get value into r24
 
 
inc r24&nbsp;; value + 1
 
 
st x,r24&nbsp;; put back
 
 
ldd r26,y+0&nbsp;; address of y
 
 
ldd r27,y+1
 
 
st x,r24&nbsp;; store
 
 
ret&nbsp;; ready
 
 
[end]
 
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
<span style="font-family: Arial;">&nbsp;</span>
+
Ein zuletzt übergebenen Paramter (hier y) wird stets so refernziert:
 +
LDD r26 , Y + 0
 +
LDD r27 , Y + 1
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
To write a function goes the same way.
 
 
A function returns a result so a function has one additional parameter.
 
 
It is generated automatic and it has the name of the function.
 
 
This way you can assign the result to the function name
 
  
 +
Schreiben Sie eine gewöhnliche Subprozedur, zusätzlich jedoch mit dem Namen der Prozedur in eckigen Klammern, wie im folgendem
 +
Beispiel gezeigt.
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
For example:
 
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
  [test]
Declare Function Test(byval x as byte , y as byte) as byte
+
    test:
 
+
    LDD R26,X+2&nbsp;; load address of x
A virtual variable will be created with the name of the function in this case test.
+
    LDD R27,Y+3
 
+
    LD  R24,x&nbsp;; get value into r24
It will be pushed on the soft stack with the Y-pointer.
+
    INC R24&nbsp;; value + 1
 +
    ST X,R24&nbsp;; put back
 +
    LDD R26,Y+0&nbsp;; address of y
 +
    LDD R27,Y+1
 +
    ST X,R24&nbsp;; store
 +
    RET&nbsp;; ready
 +
  [end]
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
To reference to the result or name of the function (test) the address will be:
 
 
y + 0 and y + 1
 
 
The first variable x will bring that to y + 2 and y + 3
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
And the third variable will cause that 3 parameters are saved on the soft stack
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
To reference to test you must use&nbsp;:
+
Um eine Funktion zu erstellen wird genauso verfahren.
 
+
ldd r26 , y + 4
+
 
+
ldd r27 , y + 5
+
  
 +
Der Unterschied: eine Funktion gibt ein Ergebnis zurück, womit ein weiterer Parameter entsteht.
 +
Dieser Rückgabeparameter wird automatisch generiert und trägt den Namen der Funktion.
 +
Auf diese Weise kann das Ergebnis dem Funktionsnamen zugeordnet werden.
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
 +
Ein Beispiel:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
Declare Function Test(byval x as byte , y as byte) as byte
To reference variable x
+
Eine virtuelle Variable namens Test wird erzeugt und auf den Soft-Stack mit Hilfe des Y-Zeigers gebracht.
 
+
ldd r26 , y + 2
+
 
+
ldd r27 , y + 3
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
And to reference variable y
+
Das Ergebnis der Funktion (test) würde an dieser Stelle so referenziert:
 +
LDD R26 , Y + 0
 +
LDD R27 , Y + 1
  
<span style="font-family: Arial;">&nbsp;</span>
+
Durch den bei der Funktion übergebenen Parameter x jedoch, ändert sich die Verschiebegröße auf y und damit der Zugriff auf test zu
 
+
Y + 2 und Y + 3,
ldd r26 , y + 0
+
 
+
ldd r27 , y + 1
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
und nachdem die  Adresse des dritten Parameters y auf den Soft-Stack geschrieben wird, ändert sich der Verweis ebenfalls wieder:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
LDD R26 , Y + 4
When you use exit sub or exit function you also need to provide an additional label. It starts with sub_ and must be completed with the function / sub routine name. In our example:
+
LDD R27 , Y + 5
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
sub_test:
 
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
 +
Schlussendlich wird auf die Adresse von x im Soft-Stack so verwiesen,
 +
  LDD r26 , Y + 2
 +
  LDD r27 , Y + 3
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
= <span class="f_Header">LOCALS</span> =
+
und auf y so.
 
+
When you use local variables thing become more complicated.
+
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
  LDD R26 , Y + 0
Each local variable address will be put on the soft stack too
+
  LDD R27 , Y + 1
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
When you use 1 local variable its address will become
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
ldd r26, y+0
+
Für '''Exit Sub''' oder '''Exit Function''' muss außerdem ein zusätliches Label angegeben werden das mit sub_ beginnt und mit dem Namen der Funktion oder der Routine endet.
 
+
Dem oben aufgeführten Beispiel entsprechend also:
ldd r27 , y + 1
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
All other parameters must be increased with 2 so the reference to y variable changes from
+
  sub_test:
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
ldd r26 , y + 0 to ldd r26 , y + 2
 
 
ldd r27 , y + 1 to ldd r27 , y + 3
 
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
And of course also for the other variables.
+
= <span class="f_Header">LOCALS</span> =
  
 +
Wenn Sie mit lokalen Variablen arbeitet, wird es etwas komplizierter.
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
 +
Jede Adresse einer lokalen Variable wird auch auf den Soft-Stack geschrieben.
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
When you have more local variables just add 2 for each.
+
Verwenden Sie nur eine lokale Variable, liegt dessen Adresse an
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
  LDD R26, Y + 0
Finally you save the file as a .lib file
+
  LDD R27, Y + 1
 
+
Use the library manager to compile it into the lbx format.
+
 
+
The declare sub / function must be in the program where you use the sub / function.
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 +
Die Referenzierung auf alle weiteren Parameter erhöht sich dadurch um 2, sodass sich der Zugiff auf die Adresse des Parameter y ändert.
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
The following is a copy of the libdemo.bas file&nbsp;:
+
LDD R26 , Y + 0  nach  LDD R26 , Y + 2
 +
LDD R27 , Y + 1  nach  LDD R27 , Y + 3
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
'define the used library
 
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
$lib "mylib.lib"
+
Wenn mehr als eine lokale Variable verwendet werden, muss für jede Weitere 2 hinzuaddiert werden.
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
'also define the used routines
+
Am Ende muss die Datei mit der Endung .lib abgespeichert werden.
 +
Mit dem Lib-Mangager kann die neue Bibliothek in das lbx-Format kompiliert werden.
  
 +
Die jeweilige Declare Sub/Function Aweisung muss, um die Funktion oder Subroutine verwenden zu können, im Programmcode eingefügt werden.
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
$external Test
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
 +
Das folgende Programmbeispiel ist eine Kopie aus der Datei libdemo.bas&nbsp;:
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
'this is needed so the parameters will be placed correct on the stack
 
 
Declare Sub Test(byval X As Byte , Y As Byte)
 
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
 +
  $lib "mylib.lib"                              'define the used library<span style="font-family: Arial;">&nbsp;</span>
 +
  &nbsp;
 +
  $external Test                                'also define the used routines
 +
  &nbsp;
 +
  Declare Sub Test(byval X As Byte , Y As Byte) 'this is needed so the parameters will be placed correct on the stack
 +
  &nbsp;
 +
  Dim Z As Byte                                'reserve some space
 +
  &nbsp;
 +
  Call Test(1 , Z)                              'call our own sub routine
 +
  &nbsp;
 +
  'z will be 2 in the used example
 +
End
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
'reserve some space
+
Wenn Sie in ihrer Bibliothek Ports verwenden wollen, müssen Sie für deren Adressen symbolische Konstanten anlegen.
 
+
Beispiel:
Dim Z As Byte
+
  .equ EEDR=$1d
 +
  In R24, EEDR
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
So erkennt der Library-Manager Port-Adressen beim Kompilieren.
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
Alternativ können Sie dem Mnemonic ein * voranstellen. So wird diese Zeile beim Komilieren der Lib nicht mit übersetzt. Die Umsetzung der Adresse des Registers würde dann erst zur Laufzeit geschehen. 
'call our own sub routine
+
 
+
Call Test(1 , Z)
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
'z will be 2 in the used example
 
 
End
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
When you use ports in your library you must use .equ to specify the address:
 
 
.equ EEDR=$1d
 
 
In R24, EEDR
 
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
This way the library manager knows the address of the port during compile time.
+
= <span class="f_Header">Umformung</span> =
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
Ab Version 1.11.7.5 werden einige Mnemonics bei Bedarf anders umgesetzt, also umgeformt.
As an alternative precede the mnemonic with a * so the code will not be compiled into the lib. The address of the register will be resolved at run time in that case.
+
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
This chapter is not intended to teach you ASM programming. But when you find a topic is missing to interface BASCOM with ASM send me an email.
+
Beispielsweise funktioniert SBIC nur mit normalen Port-Registern.<span style="font-family: Arial;">&nbsp;</span>
 
+
Der Hintergrund ist, daß die Adresse nicht größer als 5 Bit sein darf, da bereits 3 Bits schon für die Pin-Nummer 0-7 benötigt werden.
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
SBIC arbeitet nur mit den unteren 32 IO-Registern der Adressen 0-31.
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
SBIC funktioniert auf älteren AVR-Modellen problemlos.<span style="font-family: Arial;">&nbsp;</span>Bei der Anwendung des Befehls auf neuere Modelle, bei denen die Portadressen höher sein können, z.B. beim ATMega128 - PortG, versagt dieser Befehl.
= <span class="f_Header">Translation</span> =
+
 
+
In version 1.11.7.5 of the compiler some mnemonics are translated when there is a need for.
+
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
For example, SBIC will work only on normal PORT registers. This because the address may not be greater then 5 bits as 3 bits are used for the pin number(0-7).
 
 
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
Es wird, wo immer die Bits eines IO-Register manipuliert werden sollen, ein Arbeitsregister R[0-31] benötigt.
SBIC worked well in the old AVR chips(AT90Sxxxx) but in the Mega128 where PORTG is on a high address, it will not work.
+
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 +
Beispiel&nbsp;:
  
You always needs a normal register when you want to manipulate the bits of an external register.
+
LDS R23,  PORTG&nbsp;; get value of PORTG register
 +
SBR R23,  128&nbsp;; set bit 7
 +
STS PORTG, R23
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
For example&nbsp;:
+
Mneminics die vom Compiler umgeformt werden,sind&nbsp;: IN, OUT, SBIC, SBIS, SBI and CBI.&nbsp;  
 
+
LDS r23, PORTG&nbsp;; get value of PORTG register
+
 
+
SBR r23,128&nbsp;; set bit 7
+
 
+
STS PORTG, R23
+
 
+
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
 
+
Der Compiler verwendet dafür immer das Register R23. Achten Sie darauf, daß dieses Register in solch einem Fall nicht zeitgleich für etwas anderes verwendet wird.
The mnemonics that are translated by the compiler are&nbsp;: IN, OUT, SBIC, SBIS, SBI and CBI.
+
  
 
<span style="font-family: Arial;">&nbsp;</span>
 
<span style="font-family: Arial;">&nbsp;</span>
  
The compiler will use register R23 for this. So make sure it is not used.
+
= <span class="f_Header">Spezielle Befehle</span> =
  
<span style="font-family: Arial;">&nbsp;</span>
+
ADR Label &nbsp;; Erzeugt eine Wortadresse einer Programmarke (Label)
 
+
= <span class="f_Header">Special instructions</span> =
+
 
+
ADR Label &nbsp;; will create a word with the address of the label name
+
 
+
ADR2 Label&nbsp;; will create a word with the address of the label name, multiplied by 2 to get the byte address since word addresses are used. This is convenient when loading the Z-pointer to use (E)LPM.
+
 
+
&nbsp;
+
  
.align &nbsp;; This directive will align the code to a 256 byte page so that the address LSB becomes 0. When storing data at an address where the LSB is zero, you can test for an overflow of the MSB only.
+
ADR2 Label&nbsp;; Erzeugt eine Wortadresse einer Programmarke (Label) die mit 2 multipliziert ist um ein Byte zu adressieren.&nbsp;
 +
              So lässt sich das Z-Register bequem zum gebrauch von(E)LPM-Befehlen laden.
  
 +
  .align &nbsp;; Diese Direktive richtet den Programmcode an eine Seitengrenze des Programmspeichers (der in 256 Byte großen Blöcken aufgeteilt ist)so aus,
 +
            daß das niederwertige Byte (LSB) einer Adresse zu 0 wird.
 +
            Wenn Daten an eine bestimmte Adresse geschrieben werden bei dem das LSB = 0 ist, kann ein Überlauf nur durch Prüfung des MSB festgestellt werden. 
 
<br/><br/>{{Languages}}
 
<br/><br/>{{Languages}}
  
 
[[Category:BASCOM Language Fundamentals/de]]
 
[[Category:BASCOM Language Fundamentals/de]]

Latest revision as of 11:07, 5 March 2013

Contents

BASIC und Assembler mischen

 Dieses Kapitel darf nicht als Unterrichtung in Assemblerprogammierung verstanden werden. 
 Wenn Sie ein spezielles Thema zur Verwendung  von Assembler in BASCOM vermissen, teilen Sie uns das per Email mit.


BASCOM gestattet das mischen von BASIC mit Assembler-Code, was in den Fällen nützlich sein kann, in denen Sie vollen Einfluss auf den generierten Code nehmen wollen.

 

Nahezu alle Assembler-Mnemonics werden vom Compiler direkt unterstütz. Die Ausnahmen sind SWAP, CALL und OUT. Das sind reservierte BASIC-Befehle und haben Vorrang gegenüber Assembler-Mnemonics.

Um diese Mnemonics verwenden zu können wird ihnen ein Ausrufezeichen (!) vorangestellt.

 

noticeEs wird empfohlen immer das ! oder einen $ASM … $End ASM –Block zu verwenden.  


Beispiel :

 

   Dim a As Byte At &H60 'A is stored at location &H60
   Ldi R27 , $00   'Load R27 with MSB of address
   Ldi R26 , $60   'Load R26 with LSB of address
   Ld R1, X   'load memory location $60 into R1
   !SWAP R1   'swap nibbles

 

Wie Sie sehen, wurde dem Mnemonik SWAP ein Ausrufezeichen !  vorangestellt.

 

Eine andere Option ist die Verwendung eines einschließenden $ASM/ $END ASM - Blocks:

 

   $ASM
   LDI R27 , $00   'Load R27 with MSB of address
   LDI R26 , $60   'Load R26 with LSB of address
   LDI R1  , X    'load memory location $60 into R1
   SWAP R1   'swap nibbles
   $END ASM

 

Assembler-Hilfsfunktion

Eine spezielle Assembler-Hilfsfunktion unterstützt das Laden von Adressen in die Register X oder Z. Das Y-Register sollte nicht verwendet werden da dieses bereits als Zeiger auf den Software-Stack verwendet wird.

 

 Dim A As Byte  'reserve space
 LOADADR a, X  'load address of variable named A into register pair X

 

Nachfolgender Code hat den gleichen Effekt  :

 LDI R26 , $60 'for example !
 LDI R27, $00 'for example !

 

 

Von Bascom verwendete Register

R4 und R5 werden als Zeiger auf den Stack-Frame oder zur temporären Datensicherung verwendet.


R6 dient zur Speicherung von Bit-Variablen:

- bit 0 = Flag für Integer/Word Umwandlungen

- bit 1 = Temporärer Bit-Speicher beim Tauschen von Bits

- bit 2 = Fehler-Bit (ERR - Variable)

- bit 3 = Anzeigen/Nicht Anzeigen - Flag bei dem INPUT-Befehl


R8 und R9 dienen als Datenzeiger für den READ-Befehl.

 

Alle anderen Register werden Befehlsabhängig verwendet

 

Laden von Variablen-Adressen

Um die Adresse einer Variable zu laden, muß dessen Name in geschwungenen Klammern eingeschlossen sein.

   Dim B As Bit
   LDS R16, {B} '{B} wird durch die Adresse der Variablen B ersetzt. 

 

 

Um auf ein Bit zu verweisen, muss der Variablen der Ausdruck BIT. vorangestellt sein.  

   SBRS R16 , BIT.B  'Beachten sie den Punkt!

  Da B das erste dimensionierte Bit ist, erhält B die Bitnummer 0. Bits werden zu Bytes zusammengefasst gespeichert. Das erste dimensionierte Bit geht in das niederwertigste Bit ein, usw.

 

Laden von Label-Adressen

 

Um die Adresse eines Labels zu laden, schreiben sie :  

LDI ZL, Low(lbl * 1)
LDI ZH , High(lbl * 1)

 

wobei ZL auch R30, R24, R26, R28 oder R30, und ZH gleichermaßen R31, R25, R27, R29 oder R31 sein kann.

 

Das sind sogenannte Registerpaare mit denen Zeiger gebildet werden können.

 

 

Wenn Sie mit einer LPM – Instruktion (LOAD-PROGRAMM_MEMORY) Daten aus dem Programmspeicher laden wollen, muss die Adresse mit 2 multipliziert werden, da der Programmspeicher wortorganisiert ist (16Bit).


LDI ZL, Low(lbl * 2)
LDI ZH , High(lbl * 2)
LPM ; get data into R0
....
Lbl:
.....

Einige wichtige Punkte

 

 

Um in Assembler zu programmieren müssen Atmel Mnemonics verwendet werden. In den Datenblättern der jeweiligen Mikrocontroller die Sie unter www.atmel.com herunterladen können, finden sie den entsprechenden Befehlsvorrat.  


  • Alle Befehle die eine Konstanten verwenden, arbeiten ausschließlich mit den oberen 16 Registern R16 bis R31.

!LDI R15, 12 funktioniert also nicht.

 

 

  • Der Befehl SBR reg , K

K kann ein Wert von 0 bis 255 sein. So können mehrere Bits gleichzeitig gesetzt werden.

 

Mit dem Befehl SBI port , K hingegen kann immer nur ein Bit setzen, da K nur 0 bis 7 sein kann.  

Das Gleiche gilt für die Befehle CBR und CBI.

 

 

Sie können für K ebenfalls symbolische Konstante verwenden:

 

 .equ myval = (10+2)/4
 ldi R24,myval+2 '5
 ldi R24,asc("A")+1 ; load with 66

 

 

Oder in BASIC mit CONST :

 

 CONST Myval = (10+2) / 4
 LDI R24, myval

 

 

Bibliotheken (.lib) erstellen

Wie erstellt man eine eigene Bibliothek und verwendet diese mit BASIC?

Die Dateien zu diesem Beispiel finden sie im BASCOM-Installationsverzeichnis unter \SAMPLES\libdemo.bas und unter \LIB\mylib.lib.

 

 

Zu Beginn bestimmen Sie die zu verwendenden Parameter und ihre Datentypen.

Überlegen Sie außerdem ob die Parameter Byref oder Byval übergeben werden sollen.


- "ByRev" : Die Adresse der übergebenen Variable wird an eine Prozedur übergeben. So wird der Inhalt der Variable direkt bearbeitet.

- "ByVal" : Eine Kopie des Parameterinhaltes wird übergeben. Der Inhalt der übergebenen Quellvariable bleibt unangetastet.  

 

Beispiel:

Eine Subroutine namens "test" erwartet zwei Parameter:

 x die byval übergeben wird (eine Kopie. Kopien werden temporär in den Stack-Fame-Bereich geschrieben) 
 y die byref übergeben wird (die Adresse der Variablen)

   

In beiden Fällen wird die Adresse der Variablen auf den SoftStack gebracht, welcher mit dem Y-Zeiger verwaltet wird.  

 

Der erste Parameter x (genauer: die Adresse seiner Kopie) wird dem Soft-Stack auferlegt.

An diese Adresse gelangen sie durch:  

LDD R26 , Y + 0
LDD R27 , Y + 1

  Die Adresse steht nun im Registerpaar X (R26,R27) oder im X-Zeiger.

Da ein zweiter Parameter, oder besser dessen Adresse ebenfalls auf dem Soft-Stack gebracht werden soll, ändert sich jedoch die Verschiebegröße auf den Y-Zeiger um an die Adresse von x zu gelangen :    

x wird dadurch also so refenziert:

LDD R26 , Y + 2
LDD R27 , Y + 3

     

Ein zuletzt übergebenen Paramter (hier y) wird stets so refernziert:

LDD r26 , Y + 0
LDD r27 , Y + 1

 


Schreiben Sie eine gewöhnliche Subprozedur, zusätzlich jedoch mit dem Namen der Prozedur in eckigen Klammern, wie im folgendem Beispiel gezeigt.    

 [test]
   test:
    LDD R26,X+2 ; load address of x
    LDD R27,Y+3
    LD  R24,x ; get value into r24
    INC R24 ; value + 1
    ST X,R24 ; put back
    LDD R26,Y+0 ; address of y
    LDD R27,Y+1
    ST X,R24 ; store
   RET ; ready
 [end]

 

 

 

Um eine Funktion zu erstellen wird genauso verfahren.

Der Unterschied: eine Funktion gibt ein Ergebnis zurück, womit ein weiterer Parameter entsteht. Dieser Rückgabeparameter wird automatisch generiert und trägt den Namen der Funktion. Auf diese Weise kann das Ergebnis dem Funktionsnamen zugeordnet werden.  

Ein Beispiel:  

Declare Function Test(byval x as byte , y as byte) as byte

Eine virtuelle Variable namens Test wird erzeugt und auf den Soft-Stack mit Hilfe des Y-Zeigers gebracht.

 

Das Ergebnis der Funktion (test) würde an dieser Stelle so referenziert:

LDD R26 , Y + 0
LDD R27 , Y + 1

Durch den bei der Funktion übergebenen Parameter x jedoch, ändert sich die Verschiebegröße auf y und damit der Zugriff auf test zu

Y + 2 und Y + 3,

  und nachdem die Adresse des dritten Parameters y auf den Soft-Stack geschrieben wird, ändert sich der Verweis ebenfalls wieder:  

LDD R26 , Y + 4
LDD R27 , Y + 5

   

Schlussendlich wird auf die Adresse von x im Soft-Stack so verwiesen,

 LDD r26 , Y + 2
 LDD r27 , Y + 3

 

und auf y so.  

 LDD R26 , Y + 0
 LDD R27 , Y + 1

 

 

Für Exit Sub oder Exit Function muss außerdem ein zusätliches Label angegeben werden das mit sub_ beginnt und mit dem Namen der Funktion oder der Routine endet. Dem oben aufgeführten Beispiel entsprechend also:

 

 sub_test:

   

LOCALS

Wenn Sie mit lokalen Variablen arbeitet, wird es etwas komplizierter.  

Jede Adresse einer lokalen Variable wird auch auf den Soft-Stack geschrieben.  

Verwenden Sie nur eine lokale Variable, liegt dessen Adresse an  

 LDD R26, Y + 0
 LDD R27, Y + 1

  Die Referenzierung auf alle weiteren Parameter erhöht sich dadurch um 2, sodass sich der Zugiff auf die Adresse des Parameter y ändert.

 

LDD R26 , Y + 0   nach   LDD R26 , Y + 2
LDD R27 , Y + 1   nach   LDD R27 , Y + 3

     

Wenn mehr als eine lokale Variable verwendet werden, muss für jede Weitere 2 hinzuaddiert werden.  

Am Ende muss die Datei mit der Endung .lib abgespeichert werden. Mit dem Lib-Mangager kann die neue Bibliothek in das lbx-Format kompiliert werden.

Die jeweilige Declare Sub/Function Aweisung muss, um die Funktion oder Subroutine verwenden zu können, im Programmcode eingefügt werden.  

 

Das folgende Programmbeispiel ist eine Kopie aus der Datei libdemo.bas :    

 $lib "mylib.lib"                              'define the used library 
  
 $external Test                                'also define the used routines
  
 Declare Sub Test(byval X As Byte , Y As Byte) 'this is needed so the parameters will be placed correct on the stack
  
 Dim Z As Byte                                 'reserve some space
  
 Call Test(1 , Z)                              'call our own sub routine
  
 'z will be 2 in the used example
End

 

Wenn Sie in ihrer Bibliothek Ports verwenden wollen, müssen Sie für deren Adressen symbolische Konstanten anlegen. Beispiel:

 .equ EEDR=$1d
 In R24, EEDR

  So erkennt der Library-Manager Port-Adressen beim Kompilieren.   Alternativ können Sie dem Mnemonic ein * voranstellen. So wird diese Zeile beim Komilieren der Lib nicht mit übersetzt. Die Umsetzung der Adresse des Registers würde dann erst zur Laufzeit geschehen.

 


 

 

Umformung

  Ab Version 1.11.7.5 werden einige Mnemonics bei Bedarf anders umgesetzt, also umgeformt.  

Beispielsweise funktioniert SBIC nur mit normalen Port-Registern.  Der Hintergrund ist, daß die Adresse nicht größer als 5 Bit sein darf, da bereits 3 Bits schon für die Pin-Nummer 0-7 benötigt werden.   SBIC arbeitet nur mit den unteren 32 IO-Registern der Adressen 0-31.   SBIC funktioniert auf älteren AVR-Modellen problemlos. Bei der Anwendung des Befehls auf neuere Modelle, bei denen die Portadressen höher sein können, z.B. beim ATMega128 - PortG, versagt dieser Befehl.     Es wird, wo immer die Bits eines IO-Register manipuliert werden sollen, ein Arbeitsregister R[0-31] benötigt.   Beispiel :

LDS R23,   PORTG ; get value of PORTG register
SBR R23,   128 ; set bit 7
STS PORTG, R23

 

Mneminics die vom Compiler umgeformt werden,sind : IN, OUT, SBIC, SBIS, SBI and CBI.    Der Compiler verwendet dafür immer das Register R23. Achten Sie darauf, daß dieses Register in solch einem Fall nicht zeitgleich für etwas anderes verwendet wird.

 

Spezielle Befehle

ADR Label  ; Erzeugt eine Wortadresse einer Programmarke (Label)
ADR2 Label ; Erzeugt eine Wortadresse einer Programmarke (Label) die mit 2 multipliziert ist um ein Byte zu adressieren.  
             So lässt sich das Z-Register bequem zum gebrauch von(E)LPM-Befehlen laden.
 .align  ; Diese Direktive richtet den Programmcode an eine Seitengrenze des Programmspeichers (der in 256 Byte großen Blöcken aufgeteilt ist)so aus,
           daß das niederwertige Byte (LSB) einer Adresse zu 0 wird.
           Wenn Daten an eine bestimmte Adresse geschrieben werden bei dem das LSB = 0 ist, kann ein Überlauf nur durch Prüfung des MSB festgestellt werden.  


Languages   English Deutsch  
Personal tools
Namespaces
Variants
Actions
Navigation
In other languages
Language