Wer sich für die Programmierung des ASURO in Assembler interessiert, sollte sich mal das List-File, das der C-Compiler GCC aus einem C-Programm erzeugt, ansehen. Dazu müsst ihr im AVRStudio unter [Project] [Configuration Options] [Generate List File] mit einem Häkchen versehen. Dann befindet sich nach dem Compilieren eine Datei *.lss im Project-Ordner [Other Files]. Aus dem C-Programmtext:

Code:
#include <avr/io.h>

int main(void)
{

    return(0);
}
erzeugt der Compiler folgendes Assembler-List-File:
Code:
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000006c  00000000  00000000  00000094  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00800060  0000006c  00000100  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00800060  0000006c  00000100  2**0
                  ALLOC
  3 .noinit       00000000  00800060  00800060  00000100  2**0
                  CONTENTS
  4 .eeprom       00000000  00810000  00810000  00000100  2**0
                  CONTENTS
  5 .stab         0000036c  00000000  00000000  00000100  2**2
                  CONTENTS, READONLY, DEBUGGING
  6 .stabstr      00000084  00000000  00000000  0000046c  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_aranges 00000014  00000000  00000000  000004f0  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_pubnames 0000001b  00000000  00000000  00000504  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_info   00000074  00000000  00000000  0000051f  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_abbrev 00000041  00000000  00000000  00000593  2**0
                  CONTENTS, READONLY, DEBUGGING
 11 .debug_line   00000094  00000000  00000000  000005d4  2**0
                  CONTENTS, READONLY, DEBUGGING
 12 .debug_str    000000a3  00000000  00000000  00000668  2**0
                  CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:

00000000 <__vectors>:
   0:	12 c0       	rjmp	.+36     	; 0x26 <__ctors_end>
   2:	2b c0       	rjmp	.+86     	; 0x5a <__bad_interrupt>
   4:	2a c0       	rjmp	.+84     	; 0x5a <__bad_interrupt>
   6:	29 c0       	rjmp	.+82     	; 0x5a <__bad_interrupt>
   8:	28 c0       	rjmp	.+80     	; 0x5a <__bad_interrupt>
   a:	27 c0       	rjmp	.+78     	; 0x5a <__bad_interrupt>
   c:	26 c0       	rjmp	.+76     	; 0x5a <__bad_interrupt>
   e:	25 c0       	rjmp	.+74     	; 0x5a <__bad_interrupt>
  10:	24 c0       	rjmp	.+72     	; 0x5a <__bad_interrupt>
  12:	23 c0       	rjmp	.+70     	; 0x5a <__bad_interrupt>
  14:	22 c0       	rjmp	.+68     	; 0x5a <__bad_interrupt>
  16:	21 c0       	rjmp	.+66     	; 0x5a <__bad_interrupt>
  18:	20 c0       	rjmp	.+64     	; 0x5a <__bad_interrupt>
  1a:	1f c0       	rjmp	.+62     	; 0x5a <__bad_interrupt>
  1c:	1e c0       	rjmp	.+60     	; 0x5a <__bad_interrupt>
  1e:	1d c0       	rjmp	.+58     	; 0x5a <__bad_interrupt>
  20:	1c c0       	rjmp	.+56     	; 0x5a <__bad_interrupt>
  22:	1b c0       	rjmp	.+54     	; 0x5a <__bad_interrupt>
  24:	1a c0       	rjmp	.+52     	; 0x5a <__bad_interrupt>

00000026 <__ctors_end>:
  26:	11 24       	eor	r1, r1
  28:	1f be       	out	0x3f, r1	; 63
  2a:	cf e5       	ldi	r28, 0x5F	; 95
  2c:	d4 e0       	ldi	r29, 0x04	; 4
  2e:	de bf       	out	0x3e, r29	; 62
  30:	cd bf       	out	0x3d, r28	; 61

00000032 <__do_copy_data>:
  32:	10 e0       	ldi	r17, 0x00	; 0
  34:	a0 e6       	ldi	r26, 0x60	; 96
  36:	b0 e0       	ldi	r27, 0x00	; 0
  38:	ec e6       	ldi	r30, 0x6C	; 108
  3a:	f0 e0       	ldi	r31, 0x00	; 0
  3c:	02 c0       	rjmp	.+4      	; 0x42 <.do_copy_data_start>

0000003e <.do_copy_data_loop>:
  3e:	05 90       	lpm	r0, Z+
  40:	0d 92       	st	X+, r0

00000042 <.do_copy_data_start>:
  42:	a0 36       	cpi	r26, 0x60	; 96
  44:	b1 07       	cpc	r27, r17
  46:	d9 f7       	brne	.-10     	; 0x3e <.do_copy_data_loop>

00000048 <__do_clear_bss>:
  48:	10 e0       	ldi	r17, 0x00	; 0
  4a:	a0 e6       	ldi	r26, 0x60	; 96
  4c:	b0 e0       	ldi	r27, 0x00	; 0
  4e:	01 c0       	rjmp	.+2      	; 0x52 <.do_clear_bss_start>

00000050 <.do_clear_bss_loop>:
  50:	1d 92       	st	X+, r1

00000052 <.do_clear_bss_start>:
  52:	a0 36       	cpi	r26, 0x60	; 96
  54:	b1 07       	cpc	r27, r17
  56:	e1 f7       	brne	.-8      	; 0x50 <.do_clear_bss_loop>
  58:	01 c0       	rjmp	.+2      	; 0x5c <main>

0000005a <__bad_interrupt>:
  5a:	d2 cf       	rjmp	.-92     	; 0x0 <__vectors>

0000005c <main>:

#include <avr/io.h>

int main(void)
{
  5c:	cf e5       	ldi	r28, 0x5F	; 95
  5e:	d4 e0       	ldi	r29, 0x04	; 4
  60:	de bf       	out	0x3e, r29	; 62
  62:	cd bf       	out	0x3d, r28	; 61



	return(0);
}
  64:	80 e0       	ldi	r24, 0x00	; 0
  66:	90 e0       	ldi	r25, 0x00	; 0
  68:	00 c0       	rjmp	.+0      	; 0x6a <_exit>

0000006a <_exit>:
  6a:	ff cf       	rjmp	.-2      	; 0x6a <_exit>
Für so ein kleines C-Programm, das nur aus der Funktion main() besteht, ist das vom Compiler erzeugte Programm doch recht umfangreich! Der Compiler fügt eurem C-Programm ein kleines "Vorprogramm" hinzu, in dem z.B. die Konstanten aus dem Programm ( das ist z.B. eine Konstante: unsigned char *str_pointer = "Das ist eine Konstante"; ) die sich im Flash-ROM befinden, in das RAM kopiert werden, da der Mikroprozessor nur über spezielle Befehle wie z.B. LPM auf Daten die sich im ROM befinden zugreifen kann. Zusätzlich werden auch die nicht verwendeten Interrupt-Vektoren initialisiert und auf die Funktion <__bad_interrupt>: umgeleitet. In den ersten vier Zeilen in main():
Code:
  5c:	cf e5       	ldi	r28, 0x5F	; 95
  5e:	d4 e0       	ldi	r29, 0x04	; 4
  60:	de bf       	out	0x3e, r29	; 62
  62:	cd bf       	out	0x3d, r28	; 61
wird der Stackpointer initialisiert.

Also, eine recht interessante Geschichte, die eigentlich jeder ASURO-Programmierer kennen und verstehen sollte. Jetzt bin ich natürlich davon ausgegangen, dass ihr eure Programme mit AVRStudio und GCC erstellt. Oder gibt es immer noch Leute, die sich mit make und PN rumquälen? LINUX-Anwender müssen das wohl, da es AVRStudio nur als Windows-Version gibt, oder?.

Peter (Ronny10)