2016-09-27 15 views
5

Jak wiemy, pliki zespołów (.S) otrzymywałyby wstępne przetwarzanie przed montażem, ale odkryłem, że po wstępnym przetworzeniu mogą pojawiać się prototypy struktur/funkcji w wynikowych plikach zespołów, w jaki sposób gnu traktowałoby te prototypy? Po prostu to zignorowałeś?Czy GNU może być prototypem struktury i funkcji w pliku zespołu (.s)?

Na przykład, następujące polecenia:

gcc -E -o tmp.result arch/x86/boot/copy.S -Iinclude/ -Iarch/x86/include/

a plik wynikowy zespół (tmp.result) wynosi:

# 1 "arch/x86/boot/copy.S"                                         
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "arch/x86/boot/copy.S" 
# 11 "arch/x86/boot/copy.S" 
# 1 "include/linux/linkage.h" 1 
# 1 "include/linux/compiler.h" 1 
# 5 "include/linux/linkage.h" 2 
# 1 "include/linux/stringify.h" 1 
# 6 "include/linux/linkage.h" 2 
# 1 "include/linux/export.h" 1 
# 26 "include/linux/export.h" 
struct kernel_symbol 
{ 
unsigned long value; 
const char *name; 
}; 
# 7 "include/linux/linkage.h" 2 
# 1 "arch/x86/include/asm/linkage.h" 1 
# 8 "include/linux/linkage.h" 2 
# 12 "arch/x86/boot/copy.S" 2 
.code16 
.text 
GLOBAL(memcpy) 
pushw %si 
pushw %di 
movw %ax, %di 
movw %dx, %si 
pushw %cx 
shrw $2, %cx 
rep; movsl 
popw %cx 
andw $3, %cx 
rep; movsb 
popw %di 
popw %si 
retl 
ENDPROC(memcpy) 

ale podczas próby montaż ten plik

as -o tmp.o tmp.result

produkują następujący błąd:

include/linux/export.h: Assembler messages: 
include/linux/export.h:26: Error: no such instruction: `struct kernel_symbol' 
include/linux/export.h:27: Error: junk at end of line, first unrecognized character is `{' 
include/linux/export.h:28: Error: no such instruction: `unsigned long value' 
include/linux/export.h:29: Error: no such instruction: `const char *name' 
include/linux/export.h:30: Error: junk at end of line, first unrecognized character is `}' 
arch/x86/boot/copy.S:20: Error: invalid character '(' in mnemonic 
arch/x86/boot/copy.S:34: Error: invalid character '(' in mnemonic 
arch/x86/boot/copy.S:36: Error: invalid character '(' in mnemonic 
arch/x86/boot/copy.S:49: Error: invalid character '(' in mnemonic 
arch/x86/boot/copy.S:51: Error: invalid character '(' in mnemonic 
arch/x86/boot/copy.S:58: Error: invalid character '(' in mnemonic 
arch/x86/boot/copy.S:60: Error: invalid character '(' in mnemonic 
arch/x86/boot/copy.S:67: Error: invalid character '(' in mnemonic 

Wygląda na to, że asembler nie radzi sobie z struct w tmp.result. W jaki sposób kod źródłowy systemu Linux (.S) może przejść przez składanie?

+0

Co dzieje się z plikiem 'tmp.result'? Jaka jest następna komenda działająca na 'tmp.result'? – Downvoter

+0

@Downvoter Kolejną komendą działającą na tmp.result jest: 'as -o tmp.o tmp.result', ale wygenerował błąd, powiedział, że nie rozpoznaje struktury w tmp.result, więc wędruję, jak kod źródłowy linux może przejść przez montaż. – Kingwah

+1

Możesz użyć 'gcc -save-temps', aby zapisać aktualny wstępnie przetworzony plik, który podaje do asemblera. Jak wskazuje odpowiedź Matteo, będzie to coś innego niż to, co otrzymasz za pomocą 'gcc -E'. Możesz również użyć 'gcc -v', aby zobaczyć, jak dokładnie wywołuje CPP. –

Odpowiedz

3

as nie może przetworzyć struct i prototypów funkcji - są one przeznaczone tylko dla kompilatora C i przez pomyłkę zostają "wciągnięte" w proces wstępnego przetwarzania. W faktach, jeśli spojrzeć na nagłówek, który stanowi, że struct definicja, you'll see:

#ifndef __ASSEMBLY__ 
struct kernel_symbol 
{ 
     unsigned long value; 
     const char *name; 
}; 

Tak, nagłówek powyżej jest uważano być zawarte zarówno z zespołu i z C, ale nie definiują __ASSEMBLY__ powiedzieć, że włączasz go do pliku zespołu.

Co ciekawe, gcc ma wbudowaną __ASSEMBLER__ predefiniowane makra do rozróżniania pomiędzy włączenia w pliku zespołu lub pliku C, ale wydaje się, że jądro does not use it for historical reasons, opierając się na określeniu ręcznie __ASSEMBLY__ gdy przerób plików montażu.

Krótko mówiąc: aby uzyskać prawidłowe wyjście z preprocesora, powinieneś robić coś

gcc -E -D__ASSEMBLY__ -o tmp.result arch/x86/boot/copy.S -Iinclude/ -Iarch/x86/include/ 

(Zastrzeżenie: Nie jestem zaznajomiony z procesem kompilacji jądra, linia powyżej mogą mieć inne problemy ze ścieżkami dołączania, a może poprawnym sposobem byłoby wywołanie cpp zamiast gcc lub cokolwiek - nie wiem)

+1

Dzięki za wyjaśnienie szczegółów. – Kingwah