www.mikrocontroller.net

Forum: Compiler & IDEs [avr-gcc] Erzwungene Sprungtabelle, wie?


Autor: Markus Stehr (bastetfur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mahlzeit Forum :)

Wie kann ich dem GCC mitteilen das er für ein zusammenhängendes Switch 
Konstrukt eine Sprungtabelle erzeugen soll?

Wenn ich also habe:
switch(foo)
{
  case 0:
    // Code
    break;
  case 1:
    // Code
    break;
  case 2:
    // Code
    break;
  // Weiter von 3 bis...
  case 14:
    // Code
    break;
  case 15:
    // Code
    break;
}

Soll daraus intern im Compiler nicht umbedingt das da werden:
if(foo==1){...code...}
if(foo==2){...code...}
if(foo==3){...code...}
...
if(foo==14){...code...}
if(foo==15){...code...}
Sondern eher:
const int footab[] = {footab_pointer0,footab_pointer1,...,footab_pointer15}; //Geht das so?
goto footab[foo]; // Ja, ich weis, wenn hier was anderes als 0..15 ankommt springt er ins Nirvana.

footab_pointer0:
// Code
goto keinfoo;
footab_pointer1:
// Code
goto keinfoo;
footab_pointer2:
// Code
goto keinfoo;
...
footab_pointer14:
// Code
goto keinfoo;
footab_pointer15:
// Code
keinfoo:

EDIT: Kleine Berichtigung am letzten Beispiel...

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was wird den erzeugt?

Assembler Listing?

Autor: Markus Stehr (bastetfur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das weis ich ja nicht ob der GCC in der Lage ist zu erkennen das hier 
aufeinander folgende Werte abgefragt werden.

Autor: Markus Stehr (bastetfur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist zwar jetzt x86, aber scheinbar schnallt der das:
#include "stdio.h"

void main(void)
{
  char foo;
  
  switch(foo)
  {
    case 0:
      printf("0\n");
      break;
    case 1:
      printf("0\n");
      break;
    case 2:
      printf("0\n");
      break;
    case 3:
      printf("0\n");
      break;
    case 4:
      printf("0\n");
      break;
    case 5:
      printf("0\n");
      break;
  }
  
}
wird zu
  .file  "main.c"
  .section  .rodata
.LC0:
  .string  "0"
  .text
.globl main
  .type  main, @function
main:
.LFB2:
  pushq  %rbp
.LCFI0:
  movq  %rsp, %rbp
.LCFI1:
  subq  $32, %rsp
.LCFI2:
  movsbl  -1(%rbp),%eax
  movl  %eax, -20(%rbp)
  cmpl  $5, -20(%rbp)
  ja  .L10
  mov  -20(%rbp), %eax
  movq  .L9(,%rax,8), %rax
  jmp  *%rax
  .section  .rodata
  .align 8
  .align 4
.L9:
  .quad  .L3
  .quad  .L4
  .quad  .L5
  .quad  .L6
  .quad  .L7
  .quad  .L8
  .text
.L3:
  movl  $.LC0, %edi
  call  puts
  jmp  .L10
.L4:
  movl  $.LC0, %edi
  call  puts
  jmp  .L10
.L5:
  movl  $.LC0, %edi
  call  puts
  jmp  .L10
.L6:
  movl  $.LC0, %edi
  call  puts
  jmp  .L10
.L7:
  movl  $.LC0, %edi
  call  puts
  jmp  .L10
.L8:
  movl  $.LC0, %edi
  call  puts
.L10:
  leave
  ret
.LFE2:
  .size  main, .-main
  .section  .eh_frame,"a",@progbits
.Lframe1:
  .long  .LECIE1-.LSCIE1
.LSCIE1:
  .long  0x0
  .byte  0x1
  .string  "zR"
  .uleb128 0x1
  .sleb128 -8
  .byte  0x10
  .uleb128 0x1
  .byte  0x3
  .byte  0xc
  .uleb128 0x7
  .uleb128 0x8
  .byte  0x90
  .uleb128 0x1
  .align 8
.LECIE1:
.LSFDE1:
  .long  .LEFDE1-.LASFDE1
.LASFDE1:
  .long  .LASFDE1-.Lframe1
  .long  .LFB2
  .long  .LFE2-.LFB2
  .uleb128 0x0
  .byte  0x4
  .long  .LCFI0-.LFB2
  .byte  0xe
  .uleb128 0x10
  .byte  0x86
  .uleb128 0x2
  .byte  0x4
  .long  .LCFI1-.LCFI0
  .byte  0xd
  .uleb128 0x6
  .align 8
.LEFDE1:
  .ident  "GCC: (Ubuntu 4.3.2-1ubuntu12) 4.3.2"
  .section  .note.GNU-stack,"",@progbits

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus Stehr wrote:
> Das weis ich ja nicht ob der GCC in der Lage ist zu erkennen das hier
> aufeinander folgende Werte abgefragt werden.

Normelerweise erkennen Compiler das. Ist ja auch nicht weiter 
Raketentechnik. Klarheit bringt wohl nur das Assemblerlisting.

Autor: Markus Stehr (bastetfur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, er kanns, sogar ohne Optimizer.
Thread kann zu :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.