2016-09-27 21 views
5

Như chúng ta đã biết, các tệp lắp ráp (.S) sẽ nhận tiền xử lý trước khi lắp ráp, nhưng tôi thấy rằng sau khi tiền xử lý có thể có cấu trúc nguyên mẫu/chức năng trong tập tin kết quả, Gnu sẽ xử lý các nguyên mẫu này như thế nào? Chỉ cần bỏ qua nó?GNU có thể là cấu trúc quy trình và các nguyên mẫu chức năng trong tệp lắp ráp (.s) không?

Ví dụ, lệnh sau:

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

và kết quả lắp ráp tập tin (tmp.result) là:

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

nhưng khi cố gắng để lắp ráp tập tin này:

as -o tmp.o tmp.result

sản xuất lỗi sau:

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 

Có vẻ như trình biên dịch không thể xử lý cấu trúc trong tmp.result. Làm thế nào mã nguồn Linux (.S) có thể thông qua việc lắp ráp?

+0

Điều gì xảy ra với tệp 'tmp.result'? Lệnh tiếp theo làm việc với 'tmp.result' là gì? – Downvoter

+0

@Downvoter lệnh tiếp theo làm việc trên tmp.result là: 'as -o tmp.o tmp.result', nhưng nó tạo ra lỗi, cho biết nó không nhận ra cấu trúc trong tmp.result, vì vậy tôi đi lang thang cách mã nguồn Linux có thể có được thông qua lắp ráp. – Kingwah

+1

Bạn có thể sử dụng 'gcc -save-temps' để lưu tệp được xử lý trước thực tế mà nó cung cấp cho trình biên dịch. Như câu trả lời của Matteo chỉ ra, nó sẽ khác với những gì bạn nhận được với 'gcc -E'. Bạn cũng có thể sử dụng 'gcc -v' để xem chính xác cách nó gọi CPP. –

Trả lời

3

as không thể xử lý struct và chức năng nguyên mẫu - chúng chỉ dành cho trình biên dịch C và bị "kéo vào" trong quá trình xử lý trước của bạn do nhầm lẫn. Trong thực tế, nếu bạn nhìn vào các tiêu đề đó quy định rằng struct định nghĩa, you'll see:

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

Vì vậy, tiêu đề trên nghĩ để đưa cả hai từ lắp ráp và từ C, nhưng bạn đã không xác định __ASSEMBLY__ để nói với nó rằng bạn đang đưa nó vào một tập tin lắp ráp.

Điều thú vị là gcc không có một BUILTIN __ASSEMBLER__ vĩ mô được xác định trước để phân biệt giữa một đưa vào một file lắp ráp hoặc một tập tin C, nhưng có vẻ như kernel does not use it for historical reasons, thay vào đó dựa vào việc xác định bằng tay __ASSEMBLY__ khi tiền xử lý file lắp ráp.

dài truyện ngắn: để có được kết quả đúng từ tiền xử lý, bạn nên làm một cái gì đó giống như

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

(từ chối trách nhiệm: Tôi không hoàn toàn quen thuộc với kernel quá trình xây dựng, các dòng trên có thể có các vấn đề khác bao gồm đường dẫn hoặc có thể là cách chính xác để gọi cpp thay vì gcc hoặc bất kỳ điều gì - Tôi không biết)

+1

Cảm ơn bạn đã giải thích chi tiết. – Kingwah

Các vấn đề liên quan