2014-03-05 5 views
8

Beim Zugriff auf Strukturfelder habe ich manuell Offsets zu Adressen hinzugefügt, um Zugriff auf die Felder zu erhalten. Dies ist ziemlich mühsam, schwer zu lesen und ein Maintenance-Kopfschmerz.Wie C-Strukturen in ARM-Assembly auf eine wartbare und lesbare Weise wiederverwendet werden?

Gibt es eine bessere Möglichkeit, auf C-Struct-Felder zuzugreifen?

Zum Beispiel, ich denke an eine Syntax wie folgt:

example.h: typedef struct { int a; int b; } MyStruct;

example.s: ldr r1, [r2, #MyStruct.b] // r2 contains an address to a MyStruct

+0

Gut geschriebene Versammlung ist, ja. –

+1

@Claris Lesbarkeit ist nicht binär. Sicherlich ist ein Assemblercode besser lesbar als andere. – delnan

+0

Viel besser: Schreiben Sie C, verwenden Sie z.B. Inline-Assembly von GCC zum Einbetten von Assembly-Snippets. ARM wird nicht ewig dauern ... – vonbrand

Antwort

5

Es gibt wirklich keine saubere und tragbare Art und Weise. Die meisten Projekte, die ich gesehen habe, haben einen Build-Schritt, der eine Header-Datei mit Struktur-Offsets generiert. Es geht ein wenig so etwas wie dieses:

1) eine C-Datei erstellen, die Ihre Offsets

#include "mystruct.h" 

#define DECLARE(SYM,VAL) \ 
__asm("__AS_DEFINE__ " SYM "\t%0" : : "n" ((unsigned long)(VAL))) 

void foo(void) 
{ 
    // mystruct.h 
    DECLARE("MYSTRUCT_B", offsetof(struct mystruct, b)); 
} 

2) mit dem Flag kompilieren, die Datei definiert Assembly zu generieren (-S auf Clang oder GCC).

__AS_DEFINE__ MYSTRUCT_B #4 

3) Verwenden Sie einige Shell-Tricks zu drehen, diese in eine Header-Datei für die Assembly-Code: Dies wird eine Baugruppendatei mit einem Bündel von definierten Linien wie zu schaffen.

grep '__AS_DEFINE__' offsets.s | sed 's/#//g' | sed 's/__AS_DEFINE__/#define/g' > build/include/offsets.h 

Dies ergibt eine Datei, die so aussieht und in Ihre Baugruppenquellen aufgenommen werden kann.

#define MYSTRUCT_B 4 

Sie können dann direkt verwenden.

#include "offsets.h" 

    ldr r1, [r2, #MYSTRUCT_B] 
+0

Siehe: [asm-offset.c] (https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/ kernel/asm-offsets.c) und [Kbuild] (https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Kbuild), die diese Technik für ARM Linux implementieren. Andere Architekturen haben denselben Dateityp. Es erzeugt eine Ausgabe wie, '-> TI_TASK # 12 offsetof (struct thread_info, task)', die das 'sed' in' #define TI_TASK 12' transformiert. Der Linux-Assembler wird mit 'gcc -E 'vorverarbeitet, so dass alle normalen' C'-Vorverarbeitungskonzepte verwendet werden können. –

Verwandte Themen