Forum: Mikrocontroller und Digitale Elektronik Erster eigener Assembler Code zu kompliziert gelöst?


von max20 (Gast)


Lesenswert?

Hallo,
viele Wege führen ja bekanntlich nach Rom, aber irgendwie kommt mir das 
Programm welches ich geschrieben habe zu kompliziert für ein solche 
einfache Sache vor.

Kann mir jemand einen Tipp geben, wie ich das ganze vereinfachen kann?

PB0, PB1, PB3 als Eingänge
PB2, PB4 als Ausgänge

Programm als Erklärung:
PB0 = high, dann Bit von PB3 zu BP2 und PB1 zu PB4
PB0 = low, dann Bit von PB3 zu PB4
1
.include "tn13adef.inc"
2
.device AtTiny13A
3
4
  ldi r16,(1<<PB0)|(1<<PB1)|(1<<PB3)  ;Eingang PB3 mit internen PullUp
5
  ldi r17,(0<<DDB4)|(0<<DDB4)      ;Ausgang PB4 auf LOW
6
  out PORTB,r16
7
  out DDRB, r17
8
9
Anfang:
10
11
sbis PINB, 0      ;überspringt den nächsten Befehl wenn Bit high
12
rjmp Off
13
14
sbic PINB, 0      ;überspringt den nächsten Befehl wenn Bit low
15
rjmp On
16
17
Off:
18
  ;PB3 -> PB4
19
  sbic PINB, 3    ;überspringt den nächsten Befehl wenn Bit low
20
  sbi PORTB, 4    ;setzt Bit
21
  sbis PINB, 3    ;überspringt den nächsten Befehl wenn Bit high
22
  cbi PORTB, 4    ;löscht Bit
23
24
  ;Schleife verlassen
25
  sbic PINB, 0    ;überspringt den nächsten Befehl wenn Bit low
26
  rjmp On
27
28
rjmp Off
29
30
31
On:
32
  ;PB3 -> PB2
33
  sbic PINB, 3    ;überspringt den nächsten Befehl wenn Bit low
34
  sbi PORTB, 2    ;setzt Bit
35
  sbis PINB, 3    ;überspringt den nächsten Befehl wenn Bit high
36
  cbi PORTB, 2    ;löscht bis
37
38
  ;PB1 -> PB4
39
  sbic PINB, 1    ;überspringt den nächsten Befehl wenn Bit low
40
  sbi PORTB, 4    ;setzt Bit
41
  sbis PINB, 1    ;überspringt den nächsten Befehl wenn Bit high
42
  cbi PORTB, 4    ;löscht Bit
43
44
  ;Schleife verlassen
45
  sbis PINB, 0    ;überspringt den nächsten Befehl wenn Bit high
46
  rjmp Off
47
rjmp On
48
49
50
rjmp Anfang

: Bearbeitet durch User
von Jasch (Gast)


Lesenswert?

max20 schrieb:
> Hallo,
> viele Wege führen ja bekanntlich nach Rom, aber irgendwie kommt mir das
> Programm welches ich geschrieben habe zu kompliziert für ein solche
> einfache Sache vor.
>
> Kann mir jemand einen Tipp geben, wie ich das ganze vereinfachen kann?

Einfach scharf nachdenken was genau passiert...

> PB0, PB1, PB3 als Eingänge
> PB2, PB4 als Ausgänge
>
> Programm als Erklärung:
> PB0 = high, dann Bit von PB3 zu BP2 und PB1 zu PB4
> PB0 = low, dann Bit von PB3 zu PB4
>
> [code]
> .include "tn13adef.inc"
> .device AtTiny13A
>
>   ldi r16,(1<<PB0)|(1<<PB1)|(1<<PB3)  ;Eingang PB3 mit internen PullUp
>   ldi r17,(0<<DDB4)|(0<<DDB4)      ;Ausgang PB4 auf LOW
>   out PORTB,r16
>   out DDRB, r17
>
> Anfang:
>
> sbis PINB, 0      ;überspringt den nächsten Befehl wenn Bit high
> rjmp Off

Die zwei oben weglassen. Hat noch andere Vorteile.

> sbic PINB, 0      ;überspringt den nächsten Befehl wenn Bit low
> rjmp On
>
> Off:
>   ;PB3 -> PB4
>   sbic PINB, 3    ;überspringt den nächsten Befehl wenn Bit low
>   sbi PORTB, 4    ;setzt Bit
>   sbis PINB, 3    ;überspringt den nächsten Befehl wenn Bit high

Den oben weglassen.

>   cbi PORTB, 4    ;löscht Bit
>
>   ;Schleife verlassen
>   sbic PINB, 0    ;überspringt den nächsten Befehl wenn Bit low
>   rjmp On
>
> rjmp Off

Kommt drauf an ob Speicherverbrauch oder Laufzeit wichtiger sind. Wenn 
Laufzeit - so lassen. Wenn Speicherverbrauch - immer zu Anfang springen.

Übrigens, wieso hast Du hier sbic richtig benutzt? ;-)

Weiter unten: wie schon gesagt.

> On:
>   ;PB3 -> PB2
>   sbic PINB, 3    ;überspringt den nächsten Befehl wenn Bit low
>   sbi PORTB, 2    ;setzt Bit
>   sbis PINB, 3    ;überspringt den nächsten Befehl wenn Bit high
>   cbi PORTB, 2    ;löscht bis
>
>   ;PB1 -> PB4
>   sbic PINB, 1    ;überspringt den nächsten Befehl wenn Bit low
>   sbi PORTB, 4    ;setzt Bit
>   sbis PINB, 1    ;überspringt den nächsten Befehl wenn Bit high
>   cbi PORTB, 4    ;löscht Bit
>
>   ;Schleife verlassen
>   sbis PINB, 0    ;überspringt den nächsten Befehl wenn Bit high
>   rjmp Off
> rjmp On
>
>
> rjmp Anfang
> [\code]

Keine Garantie für optimale Optimalität.

von Detlef K. (adenin)


Lesenswert?

1
Anfang:
2
in R16,PORTB
3
in R17,PINB
4
bst R17,PB3
5
sbis R17,PB0
6
rjmp Off
7
8
On:
9
bld R16,PB2
10
bst R17,PB1
11
12
Off:
13
bld R16,PB4
14
out PORTB,R16
15
rjmp Anfang
:P

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

max20 schrieb:

> PB0, PB1, PB3 als Eingänge
> PB2, PB4 als Ausgänge
>
> Programm als Erklärung:
> PB0 = high, dann Bit von PB3 zu BP2 und PB1 zu PB4
> PB0 = low, dann Bit von PB3 zu PB4


Das ist eigentlich schon das Hauptproblem. Bei etwas intelligenterer 
Wahl der Pinbelegung würde sich das Programm von allein massiv 
vereinfachen.

von Peter D. (peda)


Lesenswert?

max20 schrieb:
> viele Wege führen ja bekanntlich nach Rom, aber irgendwie kommt mir das
> Programm welches ich geschrieben habe zu kompliziert für ein solche
> einfache Sache vor.

Das ist schon ganz o.k. so.
In Assembler muß man eben vieles zu Fuß machen.

In C könnte man schreiben:
1
#include "sbit.h"
2
3
int main()
4
{
5
  for(;;){
6
    if( PIN_B0 ){
7
      PORT_B2 = PIN_B3;
8
      PORT_B4 = PIN_B1;
9
    }else{
10
      PORT_B4 = PIN_B3;
11
    }
12
  }
13
}

von Dirk (Gast)


Lesenswert?

Hallo Peter,

mich würde mal interessieren, welchen ASM Code, der Compiler
für diese C-Code Passage produziert.

Gruß

Dirk

von Fred (Gast)


Lesenswert?

Dann übersetz ihn doch einfach.

von Joerg W. (joergwolfram)


Lesenswert?

In punkto Laufzeit wäre folgende Lösung wahrscheinlich fast die 
schnellste ohne zuviel Code zu "verbrauchen":
1
anfang:
2
ldi  XL,0x14
3
out  DDRB,XL
4
ldi  ZH,HIGH(table*2)
5
loop:
6
in   ZL,PINB
7
andi ZL,0x0F
8
lpm  ZL,Z
9
out  PORTB,ZL
10
rjmp loop
11
12
.org 0x100
13
table:
14
        .db 0xeb,0xfb,0xeb,0xfb,0xeb,0xfb,0xeb,0xfb
15
        .db 0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff
Ein Durchlauf braucht dann genau 8 Takte. PB2 bleibt, wenn nicht 
benutzt, auf logisch 0 und die unbenutzten Pins auf logisch 1, was 
aktivierten Pullup bedeutet. Wenn man das "andi ZL,0x0F" weglässt, kommt 
man auf nur 7 Takte, braucht aber eine Tabelle mit 256 Einträgen.

Jörg

von Peter D. (peda)


Lesenswert?

Dirk schrieb:
> welchen ASM Code, der Compiler
> für diese C-Code Passage produziert.

Mit WINAVR 2010:
1
  for(;;){
2
    if( PIN_B0 ){
3
  22:  b0 9b         sbis  0x16, 0  ; 22
4
  24:  0c c0         rjmp  .+24       ; 0x3e <__SP_H__>
5
      PORT_B2 = PIN_B3;
6
  26:  96 b3         in  r25, 0x16  ; 22
7
  28:  96 95         lsr  r25
8
  2a:  94 70         andi  r25, 0x04  ; 4
9
  2c:  88 b3         in  r24, 0x18  ; 24
10
  2e:  8b 7f         andi  r24, 0xFB  ; 251
11
  30:  89 2b         or  r24, r25
12
  32:  88 bb         out  0x18, r24  ; 24
13
      PORT_B4 = PIN_B1;
14
  34:  96 b3         in  r25, 0x16  ; 22
15
  36:  99 0f         add  r25, r25
16
  38:  99 0f         add  r25, r25
17
  3a:  99 0f         add  r25, r25
18
  3c:  02 c0         rjmp  .+4        ; 0x42 <__SREG__+0x3>
19
    }else{
20
      PORT_B4 = PIN_B3;
21
  3e:  96 b3         in  r25, 0x16  ; 22
22
  40:  99 0f         add  r25, r25
23
  42:  90 71         andi  r25, 0x10  ; 16
24
  44:  88 b3         in  r24, 0x18  ; 24
25
  46:  8f 7e         andi  r24, 0xEF  ; 239
26
  48:  89 2b         or  r24, r25
27
  4a:  88 bb         out  0x18, r24  ; 24
28
  4c:  ea cf         rjmp  .-44       ; 0x22 <main>

von Dirk (Gast)


Lesenswert?

@ Peter,

danke.

Wird WIN AVR eigentlich nicht mehr weiterentwickelt?

Welchen Freeware Compiler würdet Ihr momentan für AVR empfehlen?

Danke

Gruß

Dirk

von Karl H. (kbuchegg)


Lesenswert?

Peter Dannegger schrieb:

> Mit WINAVR 2010:

Ehe hier die Assembler-Verfechter aufschlagen.
Die IN/OUT Orgien sind höchst wahrscheinlich den Strukturen geschuldet, 
die sich hinter den Bit-Bezeichnungen verstecken.

Macht man das ganze klasssisch
1
#include "avr/io.h"
2
3
#define ASSIGN_BIT( TO, FROM )   \
4
      if( PINB & (1<<FROM) )       \
5
        PORTB |= ( 1 << TO );      \
6
      else                         \
7
        PORTB &= ~( 1 << TO );
8
9
int main()
10
{
11
  DDRB = ( 1<<PB2) | (1<<PB4);
12
13
  for(;;){
14
    if( PINB & (1<<PB0) ) {
15
      ASSIGN_BIT( PB2, PB3 );
16
      ASSIGN_BIT( PB4, PB1 );
17
    }
18
    else {
19
      ASSIGN_BIT( PB4, PB3 );
20
    }
21
  }
22
}

generiert der AVR-Gcc auch Code, der mittels Bitbefehlen die Logik 
abwickelt
1
00000022 <main>:
2
  22:  84 e1         ldi  r24, 0x14  ; 20
3
  24:  87 bb         out  0x17, r24  ; 23
4
  26:  b0 9b         sbis  0x16, 0  ; 22
5
  28:  08 c0         rjmp  .+16       ; 0x3a <__CCP__+0x6>
6
  2a:  b3 9b         sbis  0x16, 3  ; 22
7
  2c:  02 c0         rjmp  .+4        ; 0x32 <main+0x10>
8
  2e:  c2 9a         sbi  0x18, 2  ; 24
9
  30:  01 c0         rjmp  .+2        ; 0x34 <__CCP__>
10
  32:  c2 98         cbi  0x18, 2  ; 24
11
  34:  b1 9b         sbis  0x16, 1  ; 22
12
  36:  05 c0         rjmp  .+10       ; 0x42 <__SREG__+0x3>
13
  38:  02 c0         rjmp  .+4        ; 0x3e <__SP_H__>
14
  3a:  b3 9b         sbis  0x16, 3  ; 22
15
  3c:  02 c0         rjmp  .+4        ; 0x42 <__SREG__+0x3>
16
  3e:  c4 9a         sbi  0x18, 4  ; 24
17
  40:  f2 cf         rjmp  .-28       ; 0x26 <main+0x4>
18
  42:  c4 98         cbi  0x18, 4  ; 24
19
  44:  f0 cf         rjmp  .-32       ; 0x26 <main+0x4>

PS: was soll eigentlich mit PB2 geschehen, wenn PB0 auf Low ist? Im 
Moment behält der Pin immer den letzten Zustand. Ist das so gewollt?

von c-hater (Gast)


Lesenswert?

Karl Heinz schrieb:

> Ehe hier die Assembler-Verfechter aufschlagen.
> Die IN/OUT Orgien sind höchst wahrscheinlich den Strukturen geschuldet,
> die sich hinter den Bit-Bezeichnungen verstecken.
>
> Macht man das ganze klasssisch
[...]

Solche Optimierungen sollten bei einem guten Compiler eigentlich niemals 
nötig sein.

Wenn ich optimieren will, schreibe ich gleich Assembler, da brauch ich 
nämlich nicht erst darüber rumrätseln, was der Compiler wohl aus diesem 
und jenem Konstrukt gemacht hat und warum er das wohl getan haben mag. 
Ich schreibe vielmehr einfach gleich hin, was die CPU tun soll und bin 
schon fertig. Und ich brauch' dazu nicht mehr als ein paar Seiten 
instruction set reference.

Keine Bücher, die auf vielen hundert Seiten erklären müssen, was die 
Sprache tut, bevor ich mich dem widmen kann, was mich eigentlich 
intessiert: was nämlich die CPU tun soll.

von Karl H. (kbuchegg)


Lesenswert?

c-hater schrieb:
> Karl Heinz schrieb:
>
>> Ehe hier die Assembler-Verfechter aufschlagen.
>> Die IN/OUT Orgien sind höchst wahrscheinlich den Strukturen geschuldet,
>> die sich hinter den Bit-Bezeichnungen verstecken.
>>
>> Macht man das ganze klasssisch
> [...]
>
> Solche Optimierungen sollten bei einem guten Compiler eigentlich niemals
> nötig sein.

Im Prinzip ja.
Nur hat sich anscheinend noch keiner die Mühe gemacht, das ganze für 
Bitfelder in Strukturen durchzuziehen.
Ist auch nicht weiter verwunderlich, denn die klassische Methode 
arbeitet mit den Bitoperationen direkt.
Die Bitfelder in Strukturen für alle Register hätten enorme Vorteile, 
doch leider sind sie in den AVR-Headern nicht durchgezogen. Wären sie 
das, würden auch die ganzen Fehler die durch das Setzen von Bits im 
falschen Register entstehen, gar nicht erst passieren können.


> Keine Bücher, die auf vielen hundert Seiten erklären müssen, was die
> Sprache tut, bevor ich mich dem widmen kann, was mich eigentlich
> intessiert: was nämlich die CPU tun soll.


Ja, schon gut.
Während du noch deine 3000 Zeilen Assembler Code schreibst und dich 
rumärgerst, welches Register wo fälschlich verändert wird bzw. gesichert 
werden muss, bzw. an welcher Stelle wieder mal das Statusregister 
verändert wurde, so dass der bedingte Sprung nicht genommen wird, 
überlasse ich diese Details dem Compiler und geh dafür lieber auf ein 
Bier. Die 5% Laufzeit-Verluste sind es mir wert, wenn ich nicht den 
letzten Rest an Laufzeit rausholen muss. Aber das wirst du heute genauso 
wenig verstehen, wie all die anderen male zuvor.

: Bearbeitet durch User
von Dirk (Gast)


Lesenswert?

ich denke, beide Sprachen absolut Ihre Berechtigung haben.

Bei C gestaltet es sich eben teilweise eben nur so, dass viele 
Programmierer (schlimmer noch bei BASIC)keinen Bezug zur Hardware haben 
und somit Probleme
bei der efizienten Code Generierung haben.

Das 2. Code Beispiel von Karlheinz ist schon richtig, nur!!! ein reiner
C-Programmierer sieht mit Sicherheit Aufgrund der fehlenden ASM 
Kenntnisse
nicht die Notwendigkeit, diesen ebenfalls längeren C-Code zu schreiben.
Assembler Kenntnisse werden C Programmieren auf keinen Fall zum 
Nachteil,
eher anders herum.

Über ASM wird viel geschimpft und verdammt.
Gleichzeitig programmieren wir heute noch in einer Sprache (C), die 
mittlerweile fast 45 Jahre alt ist und aus einer Epoche stammt, in
der die Anforderungen an ein embedded System wie heutzutage, ganz Andere 
waren.

Eigentlich wäre es an der Zeit für eine ganz neue Programmiersprache,
welche vom Syntax nicht mit den heutigen zu tun hat.

Ein Assembler Programm ist so gut und schlecht wie sein Programmierer.

Ein C-Programm ist so gut und schlecht wie sein Programmierer und der 
Programmierer des C-Compilers (also Menschen, welche sich trotzdem mit 
ASM auseinander setzen müssen)

von Peter D. (peda)


Lesenswert?

Karl Heinz schrieb:
> Macht man das ganze klasssisch

Das sind dann gerade mal 4 Befehle (8 Byte) gespart.
Optimieren sollte man erst, wenn es auch einen spürbaren Effekt hat.

von Karl H. (kbuchegg)


Lesenswert?

Dirk schrieb:
> ich denke, beide Sprachen absolut Ihre Berechtigung haben.


Ich denke, das sollte jetzt nicht in einen Flamewar ausarten.
Mir ging es nur darum, der Assembler-über-alles Fraktion insofern den 
Wind aus den Segeln zu nehmen, weil das von PeDa gepostete Beispiel und 
wie es in Object-Code umgesetzt wird, (noch) nicht der Regelfall ist.


> Das 2. Code Beispiel von Karlheinz ist schon richtig, nur!!! ein reiner
> C-Programmierer sieht mit Sicherheit Aufgrund der fehlenden ASM
> Kenntnisse
> nicht die Notwendigkeit, diesen ebenfalls längeren C-Code zu schreiben.

Ein C-Anfänger hätte genau meinen Code geschrieben, eventuell unter 
Verzicht auf das Makro. Peters Lösung ist schon die Komfort-Lösung, die 
aber (noch) nicht über das Tutorial gelehrt wird.
Das war der springende Punkt. Insofern ist die Umsetzung in 
Maschinen-Code mit dem In-maskieren-zurechtschieben-Out Zyklus nicht 
repräsentativ dafür, was ein durchschnittlicher Programmierer erhalten 
würde. PeDa hat eine Komfort-Variante, die absolut ihre Berechtigung 
hat, aber vom Compiler noch nicht so gut unterstützt wird.

von Karl H. (kbuchegg)


Lesenswert?

Peter Dannegger schrieb:
> Karl Heinz schrieb:
>> Macht man das ganze klasssisch
>
> Das sind dann gerade mal 4 Befehle (8 Byte) gespart.
> Optimieren sollte man erst, wenn es auch einen spürbaren Effekt hat.

Darum gings mir auch gar nicht.
Als ich deinen Maschinencode Output gesehen habe
1
  2c:  88 b3         in  r24, 0x18  ; 24
2
  2e:  8b 7f         andi  r24, 0xFB  ; 251
3
  30:  89 2b         or  r24, r25
4
  32:  88 bb         out  0x18, r24  ; 24

da sah ich vor meinem geistigen Auge schon c-hater, der zu einer 
erneuten Tirade angesetzt hat, wie ineffizient das nicht gegenüber einer 
Assembler-Lösung wäre. Und dem wollte ich zuvor kommen, indem klar 
gestellt wird, dass eine 'normale' Lösung, so wie sie jeder Anfänger 
aufgrund des Tutorials schreiben würde, in die Bitoperationen-Lösung 
mündet.

von Florian T. (florian_t)


Lesenswert?

Dirk schrieb:
> Eigentlich wäre es an der Zeit für eine ganz neue Programmiersprache,
> welche vom Syntax nicht mit den heutigen zu tun hat.

Gibt es doch schon. Netduino. Programmiert wird in C# mit dem .net micro 
framework. Schöner geht es doch schon fast nicht mehr. Oder?

von TriHexagon (Gast)


Lesenswert?

Nur das C# für PC Anwendungen designed wurde und nicht für Embedded 
Systeme, das ist ja nur ein Versuch es dafür hinzubiegen. Zudem das auch 
schon nicht mehr auf 8-Bitter läuft, sondern auf 32-Bit ARM Maschinen 
mit ein paar hundert MHz.

von max20 (Gast)


Lesenswert?

Danke für die vielen Tipps! Das der Zustand von PB2 nicht exakt 
definiert ist, sobald von On zu Off Status gewechselt wird war ein 
Fehler von mir, sollte wieder auf low beim Wechsel.

Die Lösung in C ist natürlich eine feine Sache, aber ich wollte nach dem 
was ich im AVR-Tutorial über Assembler verstanden habe mal die Sache in 
Assembler lösen.

Die Vorschläge von Joerg Wolfram und Detlef Kunz kann ich leider nicht 
exakt nachvollziehen und machen auch im AVR-Studio nicht das was ich mir 
vorgestellt habe. Vielleicht lag das auch an den wenigen Vorgaben die 
ich gemacht habe. Ich werde mal am Wochenende testen ob alles läuft.


Danke für das Feedback!

von Jasch (Gast)


Lesenswert?

Jasch schrieb:
> max20 schrieb:
>> Off:
>>   ;PB3 -> PB4
>>   sbic PINB, 3    ;überspringt den nächsten Befehl wenn Bit low
>>   sbi PORTB, 4    ;setzt Bit
>>   sbis PINB, 3    ;überspringt den nächsten Befehl wenn Bit high
>
> Den oben weglassen.

Das war natürlich falsch, sozusagen "goto fail" Version 2.0. Wie 
peinlich...

Was hatte ich noch geschrieben: scharf nachdenken was genau passiert. 
;-)

von Detlef K. (adenin)


Lesenswert?

max20 schrieb:

> Die Vorschläge von Joerg Wolfram und Detlef Kunz kann ich leider nicht
> exakt nachvollziehen und machen auch im AVR-Studio nicht das was ich mir
> vorgestellt habe.

Ups, kleiner Fehler.
1
Anfang:
2
in R16,PORTB
3
in R17,PINB
4
bst R17,PB3
5
sbrs R17,PB0 //muss hier natürlich sbrs anstatt sbis sein ;)
6
rjmp Off
7
8
On:
9
bld R16,PB2
10
bst R17,PB1
11
12
Off:
13
bld R16,PB4
14
out PORTB,R16
15
rjmp Anfang

müsste aber jetzt genau dies machen:
1
PB0 = high, dann Bit von PB3 zu BP2 und PB1 zu PB4
2
PB0 = low, dann Bit von PB3 zu PB4
OK, ich habs nicht durch den Simulator gejagt. ;)

: Bearbeitet durch User
von Joerg W. (joergwolfram)


Lesenswert?

Ja, da ist mir auch ein Fehler bei der Erstellung der Tabelle 
unterlaufen. Normalerweise lasse ich solche Tabellen automatisch 
erstellen, aber da sollte es halt schnell gehen...

1
        .db 0xeb,0xeb,0xeb,0xfb,0xeb,0xeb,0xeb,0xfb
2
        .db 0xfb,0xef,0xfb,0xff,0xfb,0xef,0xfb,0xff


Das verwendete Perl-Script sieht folgendermaßen aus, vielleicht kann es 
ja jemand gebrauchen:
1
#!/usr/bin/perl
2
3
$entries=16;
4
5
#######################################################################
6
# create data
7
#######################################################################
8
for($i=0;$i<$entries;$i++)
9
{
10
  $value=0xeb;
11
  if(($i & 1) == 1)
12
  {
13
    if(($i & 8) == 8)
14
    {
15
      $value += 0x04;
16
    }
17
    if(($i & 2) == 2)
18
    {
19
      $value += 0x10;
20
    }
21
  }
22
  else
23
  {
24
    if(($i & 8) == 8)
25
    {
26
      $value += 0x10;
27
    }
28
  }
29
  $scell[$i]=$value%256;
30
}
31
32
#######################################################################
33
# write table
34
#######################################################################
35
open (WTAB, ">table.inc");
36
  for($i=0;$i<($entries / 8);$i++)
37
  {
38
    print WTAB "        .db "; 
39
    for($j=0;$j<8;$j++)
40
    {
41
      $y=$scell[$i*8+$j];
42
      if ($y<1) {printf WTAB "0x00"} 
43
      else {printf WTAB "%#2.2x",$y};
44
      if ($j<7) {print WTAB ","}
45
      else {print WTAB "\n"};
46
    }
47
  }
48
close(WTAB);


Jörg

von Karl H. (kbuchegg)


Lesenswert?

c-hater schrieb:

> Keine Bücher, die auf vielen hundert Seiten erklären müssen, was die
> Sprache tut, bevor ich mich dem widmen kann, was mich eigentlich
> intessiert: was nämlich die CPU tun soll.

Dann interessiere dich mal dafür.
Hier
Beitrag "AVR Simulator Data or unknown opcode"
kannst du dich beim Helfen austoben soviel du willst.
Aber interessanterweise glänzt du in den Assembler-Threads dann auch 
meistens durch Abwesenheit.

: Bearbeitet durch User
von Vn N. (wefwef_s)


Lesenswert?

Dirk schrieb:
> Das 2. Code Beispiel von Karlheinz ist schon richtig, nur!!! ein reiner
> C-Programmierer sieht mit Sicherheit Aufgrund der fehlenden ASM
> Kenntnisse
> nicht die Notwendigkeit, diesen ebenfalls längeren C-Code zu schreiben.

Im Gegenteil, die Variante von Karl Heinz ist sogar eher die bvorzugte.

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
Noch kein Account? Hier anmelden.