Hi,
für die Uni sollen wir die bsearch Suche in C nun mit Assembler bauen.
Nun habe ich da folgenden Code erstellt aber meine Keil IDE gibt mir
immer folgende Fehlermeldung aus. Wir arbeiten auf einen CORTEX M4.
Hier mein Code:
1
.section .text
2
.global mybsearch
3
4
;register im stack sichern
5
mybsearch
6
str r4,[sp, #-4]! ;r4 in stack sichern für Adresse der Vergleichsfunktion
7
str r5,[sp, #-4]! ;r5 in stack sichern für Anzahl der Elemente bis zur Mitte
8
str r6,[sp, #-4]! ;r6 in stack sichern für Adresse der Mitte im array
9
str r7,[sp, #-4]! ;r7 in stack sichern für Laenge bis zur Mitte
10
str r8,[sp, #-4]! ;r8 in stack sichern für Arraystartadresse
11
str r9,[sp, #-4]! ;r9 in stack sichern für Suchschluessel
12
str r10,[sp,#-4]! ;r10 in stack sichern für Elementgroesse
13
str r11,[sp,#-4]!
14
str lr,[sp, #-4]! ;lr in stack sichern
15
ldr r4,[sp,#36] ;stack-parameter Nummer5 in r4 schreiben, Adresse der Vergleichsfunktion
16
mov r9,r0 ;suchschluessel in r9 sichern
17
mov r8,r1 ;arraystartadresse in r8 sichern
18
mov r10,r3 ;r3 in r10 sichern
19
mov r11,r2
20
sub r11,r11,#1
21
start ;start der Prozedur
22
mov r11,r11, lsr #1 ;anzahl der Elemente durch 2 teilen
23
cmp r11,#0
24
beq abbruch ;wenn Division durch 2 fehlgeschlagen, Suchelement in Array
25
mul r7,r11,r10 ;anzahlelemente mal Speicherbedarf eines Elements, um Länge zu bekommen
26
27
mov r6,#0
28
add r6,r7,r8 ;arraystartadresse plus Laenge bis zur Mitte um Adresse der Mitte im Array zu erhalten
29
mov r0,r9 ;suchschluessel in als parameter1 fuer compare bereitstellen
30
mov r1,r6 ;adresse der Mitte im Array als Parameter2 fuer Vergleichsfunktion bereitstellen
31
mov lr,pc ;lr sichern
32
bx r4 ;aufruf der Vergleichsfunktionfunktion
33
cmp r0,#0
34
beq gleichheit ;wenn zeroflag==1, springe zu gleichheit
35
bmi kleiner ;wenn negativeflag==1, springe zu kleiner
36
bpl groesser ;sonst springe zu groesser
37
gleichheit
38
mov r0,r6 ;adresse der mitte im array in r0 als rueckgabewert fuer gesamtfunktion setzen
39
b wiederherstellen ;springe zu wiederherstellen
40
kleiner
41
sub r8,r8,r10
42
b start ;springe zu start, um prozedur erneut zu durchlaufen
43
groesser
44
mov r8,r6
45
add r8,r8,r10 ;ersetze arraystartadresse mit mitte des arrays fuer erneuten durchlauf
46
b start ;springe zu start, um prozedur erneut zu durchlaufen
47
abbruch
48
mov r0,#-1 ;schreibe -1 in r0, als rueckgabewert fuer gesamtfunktion, da nix gefunden
Auf den LABEL Bezeichner folgt ein Doppelpunkt bei der Deklaration (gibt
noch Parameter usw. je nach verwendetem Assembler) .
Mein_Label:
rjmp Mein_Label ;
Opcodes, die mit nem Punkt beginnen, sind nur eine Spezialität von Gnu.
Schreib deinen Anfang lieber so ähnlich:
AREA Reset, CODE, READONLY
ENTRY
PRESERVE8 ; 8-Byte aligned Stack
ARM
Ähem.. dies ist ein Anfang für nen ARM7TDMI - anstelle von "ARM" kommt
bei dir die Bezeichnung für deinen Cortex hinein, ich schätze mal sowas
wie "THUMB2" oder so, not falls dort einfach "THUMB" schreiben. Die Art
des "AREA" und ob dort dein "ENTRY" liegt, mußt du auch anpassen.
und nach dem Label kommt hier keine Colon, Beispiel:
Hard_Reset
LDR R0, =PLL_BASE ; Configure and Enable PLL
MOV R1, #0xAA
MOV R2, #0x55
.. usw.
W.S.