Moin
Da Cystasy mich gebeten hat, mache ich einen Thread zu dem Thema auf.
Ich arbeite mit dem Programm µVision von Keil und der benutze Experimentiercomputer hat den LPC 2194 Microcontroller der Firma NXP (früher mal Phillips).
Der Prozessor basiert auf der ARM-7 Architektur.
Die Aufgabenstellung ist wie folgt:
Im Datenspeicher steht ein beliebig langer, alphanumerischer String. Als Endzeichen wie "\0" (=0x00) verwendet. Schreiben Sie in Unterprogramm "strDigits", das sämtliche Sonderzeichen und alle Klein- und Großbuchstaben des Strings herausfiltert. Dabei werden auch die Anzahl der gelöschten Zeichen und die Anzahl der Ziffern gezählt. Nach Aufruf des Unterprogramms stehen nur noch die Ziffern im String. Beim Aufruf und nach Beendigung des Unterprogramms steht im Register R0 die Adresse des ersten Zeichens des Strings. Im Register R1 wird die Anzahl der gelöschten Zeichen und in Register R2 die Anzahl der Ziffern zurückgegeben.
Beispiel:
vorher: "Hello WORLD_5ÄöÖüÜ-0123456789",0x00
nachher: 50123456789",0x00
R1: 20 bzw. 0x14
R2: 11 bzw. 0xB
Nun zu meiner Herangehensweise.
Als erstes muss der komplette String in den Datenspeicher geschrieben werden. Da der String beliebig lang sein darf, muss jedes byte einzeln gelesen werden. Es ist schließlich möglich, dass der String länger als 32 byte ist und somit größer wie ein Register.
Nach dem laden des Strings in den Datenspeicher, hole ich mir jedes Zeichen einzeln wieder aus dem Speicher und prüfe ob es das end byte (0x00) ist.
Sollte das nicht der fall sein lasse ich das byte durch eine schleife laufen, die selbiges mit byteweise mit einem String "0123456789" vergleicht. Sollte es eine Übereinstimmung geben, wird diese in einem Register gespeichert und die Anzahl der Ziffern erhöht. Wenn nicht wird die Anzahl der gelöschten Zeichen erhöht.
Anschließend wird dieser Prozess so lange durchlaufen, bis der gesamte String geprüft wurde.
Zwischenzeitlich hatte ich versucht zu prüfen ob das aktuelle byte im Bereich 30-39 der ASCII Tabelle ist, was bedeuten würde es wäre eine Zahl. Nur leider hat das patu nicht klappen wollen. Evtl habt ihr da noch eine Idee.
Wenn man sich das nun durchliest ist das echt simpel und wenn man sich dann eins zu eins daran hält bekommt man das Problem auch recht schnell gelöst.
Das einzige Problem was nun noch entsteht ist die Kenntnis der Keywords.
Ich hab hier mal meine Lösung für euch.
Code:
;********************************************************************;* Daten-Bereich *
;********************************************************************
AREA Daten, DATA, READWRITE
deleted SPACE 0
anzahlZiffern SPACE 0
endString
;********************************************************************
;* Programm-Bereich *
;********************************************************************
AREA Programm, CODE, READONLY
ARM
Reset_Handler MSR CPSR_c, #0x10 ; User Mode aktivieren
;********************************************************************
;* Hier das eigene Programm einf�gen *
;********************************************************************
BL strDigits
ENDE B ENDE
strDigits
LDR R0,=Wert ; Adresse des Werts laden
LDR R1,=deleted
LDR R2,=anzahlZiffern
LDR R9,=endString
MOV R10,R9
load LDRB R3,[R0],#1 ; l�dt erstes zeichen
STRB R3,[R9],#1 ; speichert erstes zeichen im speicher
CMP R3,#0x00 ; vergleicht ob zeichen terminierungszeichen ist
BNE load ; wenn nicht repeat
MOVEQ R0,R10 ;wenn ja speicher addresse in r0
BEQ check ;und starte �berpr�fung des strings
check LDRB R5,[R0],#1 ;hole erstes zeichen aus speicher
CMP R5,#0x00 ;vergleiche auf terminierung
BEQ ENDE ;wenn ja programm ende
LDRNE R4,=Ziffern ;wen nicht speichere die adresse von ziffern in r4
BNE loop ;und springe zu loop
loop
LDRB R6,[R4],#1 ;hole ziffern aus speicher
CMP R6,#0x00 ;�berpr�fung auf terminierungszeichen
ADDEQ R1,R1,#1 ;wenn ja(keine ziffer gefunden) erh�he r1
BEQ check ;und fahre mit n�chstem zeichen fort
CMP R5,R6 ;vergleiche zeichen mit ziffer
STRBEQ R6,[R9],#1 ;wen gleich schreibe zeichen in r9
ADDEQ R2,R2,#1 ;und erh�he r2
BNE loop ;wen nicht gleich springe zur�ck zu loop
BEQ check ;wen gleich hole n�chstes zeichen aus datenspeicher
;******************************************************************
;* Ende des eigenen Programms *
;******************************************************************
endlos B endlos
;********************************************************************
;* Konstanten im CODE-Bereich *
;********************************************************************
Wert DCB "Hello WORLD _5�����-0123456789",0x00
Ziffern DCB "0123456789",0x00
;********************************************************************
;* Ende der Programm-Quelle *
;********************************************************************
END
Falls ihr Verbesserungsvorschläge habt, immer her damit