Forum: Compiler & IDEs Teensy 40 von C erzeugter ARM Assemblercode


von Martin O. (ossi-2)


Lesenswert?

Ich will verstehen welcher ARM Assemblercode vom Compiler erzeugt wird.
Das folgende Testprogramm
1
void setup() {
2
  Serial.begin(9600);
3
  delay(1000) ;  
4
  Serial.print("Hello teensy40armDisasm5\n"); 
5
  kStop=0 ;
6
  while(1){
7
    a=a+0x1234 ;
8
    b=a+0x5678 ;
9
    xstop() ;
10
    }
11
  Serial.print("end setup....\n"); 
12
  }
erzeugt den unten angegebenen ARM-Thumb Assemblercode. Ich habe zwei 
Fragen (für mich ist ARM Assembler noch ganz neu.):
Wozu dienen die vielen mit .short erzeugten Konstanten im Code?
Warum wird der code für
1
    .....
2
   a=a+0x1234 ;
3
   b=a+0x5678 ;
4
   ....
anscheinend zweimal erzeugt?
1
void setup() {
2
      b4:  b508        push  {r3, lr}
3
  Serial.begin(9600);
4
  delay(1000) ;  
5
      b6:  f44f 707a   mov.w  r0, #1000  ; 0x3e8
6
      ba:  4c0c        ldr  r4, [pc, #48]  ; (ec <setup+0x38>)
7
      bc:  f000 f838   bl  130 <delay>
8
        virtual int read() { return usb_serial_getchar(); }
9
        virtual int peek() { return usb_serial_peekchar(); }
10
        virtual void flush() { usb_serial_flush_output(); }  // TODO: actually wait for data to leave USB...
11
        virtual void clear(void) { usb_serial_flush_input(); }
12
        virtual size_t write(uint8_t c) { return usb_serial_putchar(c); }
13
        virtual size_t write(const uint8_t *buffer, size_t size) { return usb_serial_write(buffer, size); }
14
      c0:  480b2119   .word  0x480b2119
15
      c4:  f000 ffbe   bl  1044 <usb_serial_write>
16
      c8:  4b0b4d0a   .word  0x4b0b4d0a
17
  Serial.print("Hello teensy40armDisasm5\n"); 
18
  kStop=0 ;
19
      cc:  2200        movs  r2, #0
20
      ce:  601a        .short  0x601a
21
  while(1){
22
    a=a+0x1234 ;
23
      d0:  6821        ldr  r1, [r4, #0]
24
      d2:  f241        .short  0xf241
25
      d4:  2234        movs  r2, #52  ; 0x34
26
    b=a+0x5678 ;
27
      d6:  f245        .short  0xf245
28
      d8:  6378        str  r0, [r7, #52]  ; 0x34
29
  Serial.begin(9600);
30
  delay(1000) ;  
31
  Serial.print("Hello teensy40armDisasm5\n"); 
32
  kStop=0 ;
33
  while(1){
34
    a=a+0x1234 ;
35
      da:  440a        .short  0x440a
36
      dc:  6022        str  r2, [r4, #0]
37
    b=a+0x5678 ;
38
      de:  6822        .short  0x6822
39
      e0:  4413        add  r3, r2
40
      e2:  602b        .short  0x602b
41
    xstop() ;
42
      e4:  f7ff ffca   bl  7c <xstop()>
43
      e8:  bf00e7f2   .word  0xbf00e7f2
44
      ec:  0ddc        lsrs  r4, r3, #23
45
      ee:  2000        .short  0x2000
46
      f0:  0014        movs  r4, r2
47
      f2:  2000        movs  r0, #0
48
      f4:  20000de0   .word  0x20000de0
49
      f8:  0de4        lsrs  r4, r4, #23
50
      fa:  2000        movs  r0, #0
51
52
000000fc <loop>:
53
  if(kStop>3){ 
54
    while(1){} ;
55
    }
56
  }
57
    
58
void loop(){
59
      fc:  bf004770   .word  0xbf004770

von Taiga Wutzzz (Gast)


Lesenswert?

Seit wann gucken sich C--Stuemper Assemblercode an.
Der ist denen nach eigenem Bekunden doch egal.

Solang es blinkt.

von . . (Gast)


Lesenswert?

Taiga Wutzzz wie wir ihn lieben.

Aber zum Thema: der "Assemblercode" passt nicht so recht zum 
Programmcode. Irgendwas vom Programmcode wird uns verheimlicht ;)

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Martin O. schrieb:
> kStop=0 ;
>     a=a+0x1234 ;
>     b=a+0x5678 ;
>     xstop() ;

Das ist alles weder definiert noch initialisiert.
Das kann der Compiler garnicht übersetzen und sollte einiges an Fehlern 
und Warnungen rausgeben.
Und wenn du die Optimierung vernünftig eingeschaltet hättest würde der 
Compiler das sowieso einfach entsorgen weil die Variablen für nichts 
verwendet werden.
Schreib erstmal vernünftigen C-Code...

von 2^5 (Gast)


Lesenswert?

Zeig mal das ganze Programm!

von Taiga Wutzzz (Gast)


Lesenswert?

> Zeig mal das ganze Programm!

Blos nicht!

von Martin O. (ossi-2)


Lesenswert?

Das ganze Programm sieht so aus:
1
volatile int a,b,c ;
2
volatile int kStop ;
3
 
4
void setup() {
5
  Serial.begin(9600);
6
  delay(1000) ;  
7
  Serial.print("Hello teensy40armDisasm5\n"); 
8
  kStop=0 ;
9
  while(1){
10
    a=a+0x1234 ;
11
    b=a+0x5678 ;
12
    xstop() ;
13
    }
14
  Serial.print("end setup....\n"); 
15
  }
16
17
void xstop(){
18
  Serial.printf("a=%08XH b=%08XH\n",a,b) ;
19
  kStop++ ;
20
  if(kStop>3){ 
21
    while(1){} ;
22
    }
23
  }
24
    
25
void loop(){
26
  }
Es gibt keine Fehler oder Warnungen beim compilieren. Es funktioniert 
auch einwandfrei.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Dann solltest du mal alle Warnungen einschalten.

Oliver

von Bernd K. (prof7bit)


Lesenswert?

Oliver S. schrieb:
> Dann solltest du mal alle Warnungen einschalten.

Ich seh jetzt auf den ersten Blick nichts wo ne Warnung kommen sollte. 
Was meinst Du?

Das einzige was mir auffällt ist daß die Klammern grauenvoll und 
irreführend falsch eingerückt sind, aber das ist dem Compiler egal.

von . . (Gast)


Lesenswert?

Naja, der Compiler (oder die Toolchain) bemühte sich, den Anforderungen 
gerecht zu werden.

Will sagen, dass sie nicht mal selbst erzeugten Code korrekt in 
Assembler ausgeben kann, daher die .sort und .word mitten im Code.

Was ist das für ein Compiler (und welche Version)?

von Oliver S. (oliverso)


Lesenswert?

Bernd K. schrieb:
> Ich seh jetzt auf den ersten Blick nichts wo ne Warnung kommen sollte.
> Was meinst Du?

Irgend W. schrieb:
> Das ist alles weder definiert noch initialisiert.

Definiert schon, initialisiert nicht.

Oliver

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Oliver S. schrieb:
> Definiert schon, initialisiert nicht.

Doch,schon.
Die non-local Variablen a,b,c werden - sofern nicht anders angeben - 
zero-initialized.

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

Ist der falsche Diassembler. Ist kein ARMv4Thumb sondern ARMv7Thumb.

Da wird schnell aus:
"216841f2342245f278630a442260226813442b60"

6821      LDR  R1, [R4]
f241 2234 MOVW  R2, #0x1234
f245 6378 MOVW  R3, #0x5678
440a      ADD  R2, R1
6022      STR  R2, [R4]
6822      LDR  R2, [R4]
4413      ADD  R3, R2
602b      STR  R3, [R5]

und nicht:
      d0:  6821        ldr  r1, [r4, #0]
      d2:  f241        .short  0xf241
      d4:  2234        movs  r2, #52  ; 0x34
      d6:  f245        .short  0xf245
      d8:  6378        str  r0, [r7, #52]  ; 0x34
      da:  440a        .short  0x440a
      dc:  6022        str  r2, [r4, #0]
      de:  6822        .short  0x6822
      e0:  4413        add  r3, r2
      e2:  602b        .short  0x602b

Beim ARMv4 war Thumb noch optional, beim Cortex-M7 ist es das einzige 
Opcode-Format und deswegen wurde es um einige 2x16Bit Breite Befehle 
erweitert. Der ARMv4-Diassembler wird da einiges undefiniertes Vorfinden 
und nur den short (16-bit) hinschreiben.

: Bearbeitet durch User
von . . (Gast)


Lesenswert?

Dennis H. schrieb:
> Ist der falsche Diassembler. Ist kein ARMv4Thumb sondern ARMv7Thumb.

Wurde ja schon angefragt, was für Programme verwendet wurden.
Der TO schweigt dazu. Zeitverschwendung.

von Martin O. (ossi-2)


Lesenswert?

An Dennis H. (den einzigen der Hilfreiches gepostet hat)
Besten Dank, ich habe inzwischen rausgefunden das die neuste objdump 
Routine anscheinend richtig arbeitet. Vermutlich war die alte objdump 
Routine nur für ARMv4Thumb richtig, wie Du bemerkt hast.

von Markus F. (mfro)


Lesenswert?

Martin O. schrieb:
> An Dennis H. (den einzigen der Hilfreiches gepostet hat)
> Besten Dank, ich habe inzwischen rausgefunden das die neuste objdump
> Routine anscheinend richtig arbeitet. Vermutlich war die alte objdump
> Routine nur für ARMv4Thumb richtig, wie Du bemerkt hast.

Bei binutils, die Code für unterschiedliche Prozessoren einer Familie 
erzeugen können, muss man objdump (mit --architecture) u.U. mitgeben, 
für welche Variante disassembliert werden soll (das ist dem .elf-File 
nicht notwendigerweise zu entnehmen).

Wahrscheinlich hat dein neueres objdump nur andere Defaults.

: Bearbeitet durch User
von . . (Gast)


Lesenswert?

Martin O. schrieb:
> An Dennis H. (den einzigen der Hilfreiches gepostet hat)
> Besten Dank, ich habe inzwischen rausgefunden das die neuste objdump
> Routine anscheinend richtig arbeitet. Vermutlich war die alte objdump
> Routine nur für ARMv4Thumb richtig, wie Du bemerkt hast.

Wieder was gelernt: Man darf nicht die alte objdump benutzen.
Es muss die neueste sein.

von S. R. (svenska)


Lesenswert?

.. schrieb:
> Wieder was gelernt: Man darf nicht die alte objdump benutzen.
> Es muss die neueste sein.

Falsch: Es muss die richtige (passende) sein.

von . . (Gast)


Lesenswert?

S. R. schrieb:
> .. schrieb:
>> Wieder was gelernt: Man darf nicht die alte objdump benutzen.
>> Es muss die neueste sein.
>
> Falsch: Es muss die richtige (passende) sein.

Neinneinnein!
Nach dem ich ja schon die Version der Tools angefragt habe, und dieser 
Beitrag, wie der anderer Leute, vom TO als nicht hilfreich bezeichnet 
wurde, dazu keinerlei Infos vom TO kamen, und als Endlösung dann, das 
"alte" müsste gegen das "neusten" objdump ersetzt werden, wuss das 
prezise und zwingend richtig sein! ;)

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.