PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Asuro in Assembler (2)



Ronny10
09.03.2007, 09:38
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:



#include <avr/io.h>

int main(void)
{

return(0);
}


erzeugt der Compiler folgendes Assembler-List-File:



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():


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)