Hallo! ich hoffe ich bin im richtigen Thread! Ich möchte folgendes Codefragment in Assembler realisieren (8051 - Code) if(zahl >= 1000 ) buffer[1] = (zahl/1000) %10 + 0x30; Also ich möchte eine x belibeige Integerzahl in einen String umwandeln und ihn am einem Grafigdisplay ausgeben das ganze möchte ich in Assembler realisieren so das auch von C aufgerufen werden kann. Die Übergabe einer Dezimalzahl in C nach Assembler erfolgt über die Register R7 bis R2. Allerdings fehlt mir der Ansatz wie man in Assembler sowas löst. Z.B. wird die Zahl 4030 in R6 und R7 abgelegt und das auch noch in Hex. Und hier fangen die probleme schon an. Ich hoffe das jemand ne Idee oder einen Ansatz hat. Vielen Dank im vorraus. Mfg Klaus
Warum denn bloß Assembler unter C ? Wenn Du unter C eine Assemblerfunktion aufrufen willst, dann mußt Du wissen, welcher Compiler, welche Version, welches Speichermodell, welche Optimierung. Daher ist Assembler unter C nur der absolute Notnagel, nicht portabel und fehleranfällig. Man muß sich in jedem Fall sehr gut mit dem jeweiligen Compiler auskennen. Peter
Hallo Peter! Nun ich Arbeite momentan mit Ride von Raisonance und ich möchte es rein intresse halber so ne routine schreiben weil in der Demoversion die Function itoa nicht zu verfügung steht. Um die Programmen laufen zulassen benutze ich von Atmel den AT89C51ED2, Speichermodell ist momentan auf small eingestellt. Soweit laufen die Programme in Mischform. Das Ziel ist ein Displaymodul zuschreiben ganz in Assembler mit allen nötigen Funktionen die ich dann auch aus C aufrufen kann. Dazu gehört eben auch Zahlen. In C Funzt die sache schon nur hätte ich gerne es in Assembler MFG Klaus
Also man kann eine Zahl nicht "umwandeln". Es gibt halt bytes auf Assembler Ebenee, wichtig ist wie du das interpretierst. In C ist es z.B. so, das ein String aus einer folge von Characters besteht, abgeschlossen durch einen \0 (NULL) Character. Du nimmst also jezt deine Zahl, teilst sie: 4 0 3 0 dann wandeslt du sie in die ASCII COdes um 52, 48, 52, 48 udn hängst noch ne 0 drann also schreisbt du an die Adresse wo der String steht: 52 48 52 48 0 und fertig ist der String :)
@Läubi Vielen Dank für deine Unterstützung dein Vorschlag habe ich schon in C gelöst siehe Codfragment. Vielmehr Interresiert mich wie das in Assembler realisiert wird. Die X-belibige Zahl z.B. 4030 wird auf der Assmblerebene in R7,R6 abgelegt. R6 = 0F und R7 = BE ergibt logischerweise = 0FBE Das Problem besteht jetzt darin die Zahl in beiden Registern zuteilen nach dem Schema Codfragment in C siehe Oben. Ich weiss jetzt nich wie man es anstellt die Werte die in R6 und R7 abgelegt sind richtig zuteilen. Für jeden Tipp bin ich dankbar MFG Klaus
Die Frage ist immer noch, was soll das bringen, außer daß der Code fehleranfälliger, schlechter wartbar und erweiterbar ist ? Ich habe früher mal mit Assembler angefangen, hier findest Du was: http://home.tiscali.de/peterd/appl/soft/arithmet/index.htm Die Funktion ADIVR10 ist das, was Du brauchst. Wie Du sie aber in Deinen C-Compiler einbindest, ist Dein Problem. Peter
@Peter Nun! was wirds mir bringen,mmmh ich hoffe mehr verständnis. Ich bin ja kein Profi hab nur Grundwissen in Assembler und C und damit die sache nicht ganz einschläft möchte ich noch etwas an Programmiertechnik lernen. Trotzdem Danke schön MFG Klaus
Also... das war wie das in assembler funktioniert. Der compiler legt das in zwei registern ab weil ein register nur 8bit speicher kann (0...255) die zahl aber größer ist. deswegen werden zwei regsiter zusammen gneommen. Das prinzip ist aber das gleiche du teilst durch 10 natuerlich dann 16bit operation auf zwei register. dann vom Orginal abziehen und schon hast du das ergebniss fuer die lezte stelle, und immer so weiter bis du alle Zahlen hast. diese dna nach dem mir beschriebene verfahren speicher und dann sollte das klappen.
Aber dabei mal die Codetabelle des Displays anschauen! Bei ASCII ist sinnigerweise die "0" auf 48dez also 30hex oder 110000bin man muss also nur etwas schieben. Damit wird auch das BCD-Format noch verständlicher. Das spart nicht nur Platz, das ist auch einfach durch schieben zu verarbeiten.
1 | void inttoasc(signed int Val, unsigned char *s) |
2 | {
|
3 | |
4 | unsigned char temp; |
5 | unsigned char i=0; |
6 | |
7 | if (Val & 0b1000000000000000) //Signed |
8 | Bit ? |
9 | {
|
10 | s[i] = '-'; |
11 | //-Zeichen ausgeben
|
12 | Val = Val ^ 0b1111111111111100; //Alles |
13 | invertieren (Bit 0 und 1 ist IMMER LOW und muss ignoriert werden) |
14 | Val += 1; |
15 | //Korrekterweise 1 addieren
|
16 | |
17 | } else |
18 | {
|
19 | s[i] = ' '; //kein |
20 | Signed, dann Leerstelle ausgeben |
21 | }
|
22 | |
23 | |
24 | temp = Val/1000; //temp2 = |
25 | 1000er Stelle |
26 | Val = Val%1000; //Val = |
27 | Rest von 1000er Division |
28 | s[++i] = temp+48; //+48 für |
29 | ASCII Umwandlung |
30 | |
31 | temp = Val/100; //temp2 = |
32 | 100er Stelle |
33 | Val = Val%100; //Val = |
34 | Rest von 100er Division |
35 | s[++i] = temp+48; //+48 für |
36 | ASCII Umwandlung |
37 | |
38 | temp = Val/10; //temp2 = |
39 | 10er Stelle |
40 | Val = Val%10; //Val = |
41 | Rest von 10er Division |
42 | s[++i] = temp+48; //+48 für |
43 | ASCII Umwandlung |
44 | |
45 | s[++i] = Val+48; //Nur noch |
46 | Rest ausgeben und +48 für ASCII Umwandlung |
47 | |
48 | s[++i] = '\0'; //String |
49 | Ende
|
die negativ routine stimmt nur halb, und i brauch man natürlich nicht dimensionieren.
Hallo! Vielen Dank vorerst für die vielen Tipps und Anregungen. Ich werde mal das eine oder andere ausprobieren. Werde dann Echo geben wenns Funzt. Nochmal Dank an Alle! MFG Klaus
Hallo! ich hab mal hier was zusammen gebastelt das Funzt für mein problem. Ich hoffe es lacht sich keiner kaputt aber zumindest kann ich damit bis 4095 DEZ in ASCII-Umwandeln und Direkt zum Display senden. Der Aufruf zum senden an Display fehlt hier (ist Absicht). Hier habe ich immer den Rest der division im Stack abgelegt. Zur Erinnerung: Ausgang war z.B. die Zahl 4030 dez in C und sollte in Assembler übergeben werden in die Register R6 und R7 dort steht die Zahl natürlich in Hex --> 0FBE h = 4030 dez . $NOMOD51 $include(c51rd2.inc) org 00h ljmp Teilen org 4000h ;Der hier beschriebene Ablauf gilt für einen Durchlauf ;Der Rest der Division im Register B wird im Stack abgelegt und wird Später ;weiter verarbeitet. ; Teilen: MOV R6,#0Fh ; 0FBEh = 4030 dez in die Register R6 u. R7 laden MOV R7,#0BEh ;R6 u. R7 bilden den Dividenden LOOP: mov B,#10 ;Divisor ist 10 mov A,R6 ;Inhalt von R6 in Akku laden div AB ;Teile A / B ( hier 0F / A = 1 Rest 5) mov R0,A ;Das Ergebnis in Register 0 ablegen mov A,R7 ;Lade R7 in Akku ( hier BE) anl A,#0F0h ;Lösche das unteres nibble orl A,B ;Verodere Akku mit Bilfsakku B (Ergebnis = B5) swap A ;vertausche Akkuinhalt (Ergebnis = 5B) neuer Dividend mov B,#10 ;Divisor ist 10 div AB ;Teile A / B ( hier 5B / A = 9 Rest 1) swap A ;vertausche Akkuinhalt (Ergebnis = 90) mov R1,A ;Das Ergebnis in Register 1 ablegen mov A,R7 ;Lade R7 in Akku ( hier BE) swap A ;vertausche Akkuinhalt (Ergebnis = EB) anl A,#0F0h ;Lösche das unteres nibble orl A,B ;Verodere Akku mit Bilfsakku B (Ergebnis = E1) swap A ;vertausche Akkuinhalt (Ergebnis = 1E) mov B,#10 ;Divisor ist 10 div AB ;Teile A / B ( hier 1E / A = 3 Rest 0) orl A,R1 ;Verodere Akku mit Bilfsakku B (Ergebnis = 93) mov R1,A ;Das Ergebnis in Register 1 ablegen mov a,R0 ;Neuer Dividend in Register 6 u. 7 ablegen mov R6,A mov A,R1 mov R7,A push B ;Rest der divison im Stack ablegen cjne R7,#0,LOOP ;Widerhole bis Register 7 null ist pop B ;Stelle den Letzten Rest der Division ;wieder her. ( hier 4) mov A,#48 ;Lade den ASCII- Code für 0 (hier 30h) orl A,B ;wird nun ASCII = 4 (hier 34h) pop B ;Stelle den Letzten Rest der Division ;wieder her. ( hier 0) mov A,#48 ;Lade den ASCII- Code für 0 (hier 30h) orl A,B ;Aus 0 wird nun ASCII = 0 (hier 30h) pop B ;Stelle den Letzten Rest der Division ;wieder her. ( hier 3) mov A,#48 ;Lade den ASCII- Code für 0 (hier 30h) orl A,B ;Aus 3 wird nun ASCII = 3 (hier 33h) POP B sjmp LOOP ret END Wenn jemand etwas besseres in Assembler einfällt darf er es hier ruhig Posten. MfG Klaus
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.