2016-09-27 18 views
5

Bilindiği gibi, montaj dosyaları (.S) montaj öncesi ön işleme alınacaktı, ancak önişlemeden sonra ortaya çıkan montaj dosyalarında struct/function prototipleri olabileceğini öğrendim, bu prototiplerle nasıl başa çıkılırdı? Sadece görmezden mi geldi? ÖrneğinGNU, montaj dosyasında (.s) süreç yapısı ve işlev prototipleri olarak kullanılabilir mi?

aşağıdaki komutu:

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

ve ortaya çıkan derleme dosyası (tmp.result) 'dir:

as -o tmp.o tmp.result

:

# 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) 

ama bu dosyayı birleştirmek için çalışırken

aşağıdaki hatayı üretir:

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 

Montajcı tmp.result içindeki yapıyla ilgilenemiyor gibi görünüyor. Linux kaynak kodu (.S) montajdan nasıl geçebilir?

+0

"tmp.result" dosyasında ne yapılıyor? Tmp.result üzerinde çalışan sonraki komut nedir? – Downvoter

+0

@Downvoter tmp.result üzerinde çalışan bir sonraki komut: 't-to-tmp.o tmp.result' olarak, ancak hata üretti, tmp.result içindeki yapıyı tanıyamadığını söyledi, bu yüzden linux kaynak kodunun nasıl dolaştığını montajdan geçin. – Kingwah

+1

"gcc -save-temps" işlevini, beslediği gerçek işlenmiş dosyayı biriktiriciye kaydetmek için kullanabilirsiniz. Matteo'nun cevabı belirttiği gibi, gcc -E ile aldığınızdan farklı olacak. Ayrıca CPP'yi nasıl çağırdığını görmek için gcc-v'yi de kullanabilirsiniz. –

cevap

3

as, struct'u işleyemez ve prototipleri işleyemez - bunlar yalnızca C derleyicisine aittir ve önişleminizde yanlışlıkla "içeri çekilir".

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

Yani, Yukarıdaki başlık düzeneğinden ve C hem dahil edilmesi düşünülen, ancak __ASSEMBLY__ tanımlamak vermedi: gerçekler, sen struct tanımı, you'll see öngörmektedir başlığında bakarsak bunu bir montaj dosyasına dahil ettiğinizi söylemek için.

İlginçtir, gcc bir montaj dosyası veya C dosyasında bir içerme arasındaki ayrım için yerleşik __ASSEMBLER__ önceden tanımlanmış makro var, ama o çekirdek does not use it for historical reasons, montaj dosyaları ön işleme manuel __ASSEMBLY__ tanımlayan yerine güvenerek gibi görünüyor.

kısa

Uzun hikaye: önişlemcisinden doğru çıktı almak için, yapmanız gerektiğinden

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

(reddi gibi bir şey: Ben çekirdek kurulumu işlemi ile tamamen aşina değilim, çizgi üzerinde olabilir yollarla diğer problemler, ya da belki de doğru yol, gcc yerine cpp'u çağırmak ya da ne olursa olsun - Bilmiyorum)

+1

Detay açıklaması için teşekkürler. – Kingwah

İlgili konular