warum schreibt der C-Compiler diese Codeteile?

OP #2573951
Lesenswert?

Nabend.

Ich habe mir mal Interessehalber bei einem Programm den Code angeschaut 
und so einige Stellen gefunden bei denen ich mir unsicher bin oder nicht 
verstehe was diese bezwecken sollen:

-Sehe ich das richtig das er hier dauerhaft den Befehl "sei" ausführt?:
1
sei();
2
  c4:  78 94         sei
3
  c6:  ff cf         rjmp  .-2        ; 0xc6 <main+0x58>
1
int main() {
2
   sei();
3
   while(1) {
4
   };
5
}


- Warum wird hier ein eor auf das gleiche Register durchgeführt?
- Warum Multipliziert er hier mit einem Wert obwohl R19 nur 0 sein kann?
- Warum addiert er hier r0, wird dieses nicht für den Wert 0x00 
verwendet?
- Hier macht er schonwieder ein XOR mit den gleichen Registern.

[avrasm]
PORTB= (PORTC&0b11111100) | (Zahl[aktSeg/2][Nummer]&0b00000011);
  c8:  45 b3         in  r20, 0x15  ; 21
  ca:  20 91 e4 00   lds  r18, 0x00E4
> ce:  99 27         eor  r25, r25
  d0:  87 fd         sbrc  r24, 7
  d2:  90 95         com  r25
  d4:  26 95         lsr  r18
- d6:  30 e0         ldi  r19, 0x00  ; 0
  d8:  a0 e6         ldi  r26, 0x60  ; 96
  da:  b0 e0         ldi  r27, 0x00  ; 0
  dc:  6c e1         ldi  r22, 0x1C  ; 28
  de:  70 e0         ldi  r23, 0x00  ; 0
  e0:  26 9f         mul  r18, r22
  e2:  f0 01         movw  r30, r0
  e4:  27 9f         mul  r18, r23
  e6:  f0 0d         add  r31, r0
> e8:  36 9f         mul  r19, r22
> ea:  f0 0d         add  r31, r0
> ec:  11 24         eor  r1, r1
  ee:  e8 0f         add  r30, r24
  f0:  f9 1f         adc  r31, r25
  f2:  ea 0f         add  r30, r26
  f4:  fb 1f         adc  r31, r27
  f6:  20 81         ld  r18, Z
  f8:  23 70         andi  r18, 0x03  ; 3
  fa:  4c 7f         andi  r20, 0xFC  ; 252
  fc:  24 2b         or  r18, r20
  fe:  28 bb         out  0x18, r18  ; 24
/avrasm]
1
void Ziffer(int8_t Nummer) {
2
     PORTB= (PORTC&0b11111100) | (Zahl[aktSeg/2][Nummer]&0b00000011);
3
     PORTD= (PORTD&0b00000011) | (Zahl[aktSeg/2][Nummer]&0b11111100);
4
}

Ich nutze AVRStudio v4.18 mit der Optimierungsoption Qs.
Gast #2573968
Lesenswert?

>- Warum wird hier ein eor auf das gleiche Register durchgeführt?
Das ist eine von vier Möglichkeiten, ein Register auf 0 zu setzen. Warum 
er dazu eor nimmt, weiß ich nicht. Vielleicht kann das als Einziges auf 
alle Register angewendet werden.

>- Warum addiert er hier r0, wird dieses nicht für den Wert 0x00
>verwendet?
Du hast den Assemblercode. Guck nach, was drin steht.
#2573969
Lesenswert?

Michael D. schrieb:

> -Sehe ich das richtig das er hier dauerhaft den Befehl "sei" ausführt?:

Der PC steht nach der Decodierung des rjmp auf dem nachfolgenden Befehl. 
rjmp ist 2 Bytes lang. rjmp .-2 springt also immer wieder auf sich 
selbst.

>
> - Warum wird hier ein eor auf das gleiche Register durchgeführt?
x^x=0 -> opcodemäßig die kürzeste Art, 0 in ein Register zu laden.

> - Warum Multipliziert er hier mit einem Wert obwohl R19 nur 0 sein kann?
weil Du den gcc verwendest und der nicht für 8 Bit Prozessoren 
entwickelt wurde, und weil gemäß C-Standard Array-Indizes vom Typ int 
sind.
> - Warum addiert er hier r0, wird dieses nicht für den Wert 0x00
> verwendet?
nein, r0 ist ein ganz normales Register, wie die anderen 31 auch.
> - Hier macht er schonwieder ein XOR mit den gleichen Registern.
Siehe oben.

PS: eventuell ist es effizienter, wenn Du auf dem zweidimensionalen 
Array ein eindimensionales machst und/oder die erste Dimension eine 
Zweierpotenz ist. Letzteres erspart die Multiplikation.
Gast #2573976
Lesenswert?

Hi

>Hier macht er schonwieder ein XOR mit den gleichen Registern.

Wie schon gesagt setzt er das Register auf 0. In Assembler gibt es dafür 
noch den Befehl 'clr rxy'. Der Op-Code ist aber identisch mit 'eor 
rxy,rxy'. Deshalb übersetzt der Disassembler das mit eor.

MfG Spess

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren