我在各种项目中看到过 .S
文件,例如在Linux内核、FreeBSD内核或其他一些项目中。这些文件的作用是什么?为什么我们不能使用 .c
文件代替呢?
我在各种项目中看到过 .S
文件,例如在Linux内核、FreeBSD内核或其他一些项目中。这些文件的作用是什么?为什么我们不能使用 .c
文件代替呢?
.S
文件是用汇编语言编写的源代码文件,汇编语言属于一种极低级别的编程语言。这些文件按顺序包含给处理器的汇编指令,并且通常基于所选的体系结构进行编译。例如,在特定体系结构(如x86、sparc、ARM等)的Linux内核中经常看到此类文件。
有关汇编语言的更多信息,请参见以下内容:
.S
文件通常是汇编语言。
有一些事情没人提到,为什么要用大写的 S
?
.S
(大写的 S)代表必须通过一个预处理器的汇编代码。这意味着它可以包含 #include
和 #define
等宏定义。它也可以被写成 .sx
。
.s
(小写的 s)是纯汇编代码,可以编译成目标文件。
为什么不使用 .c
呢?作为操作系统,不可能全部使用 C 语言编写。实际上,那将是理想的方式,C 语言本身的背景历史与帮助创建操作系统并减少编码所需的汇编量有关。但是许多低级操作太依赖于机器。
下面是一个很好的例子,展示了一个在 Linux 引导中使用 #include <linux/linkage.h>
的内存复制程序。
#define SOME_CONST 1
更改为SOME_CONST = 1
并将其放入.s
文件中。这让我很困惑。我检查了编译标志,没有线索......然后我猜可能后缀很重要?然后一次搜索命中了这个链接和答案 :) - bruin.S
文件是汇编文件。
为什么使用
.S
而不是.c
文件?
因为需要进行机器相关的操作和早期初始化,例如设置缓存和内存,只能使用汇编级别的指令,例如 I/O 指令。
内核没有使用 libc
库来处理各种资源的初始化的豪华条件。
任何时间点的硬件资源甚至在应用程序执行期间都会调用系统调用,这些调用 I/O 程序是用汇编语言编写的。
这些文件是汇编代码文件:
汇编语言是一种面向计算机、微处理器、微控制器和其他可编程设备的低级编程语言,其中每个语句对应于单个机器语言指令。与大多数高级编程语言可能更具可移植性不同,汇编语言特定于某种计算机体系结构。
因此,这些文件与C代码文件不同。
请注意,C文件可以嵌入汇编指令。
.S文件是用汇编语言编写的代码,即编程的低级形式。在Linux内核源代码中,.S通常是内核启动时运行的起始文件(例如:head.S)。我们使用.S而不是.C来编写这个文件,因为此时我们还没有准备好运行.C编译后的.O文件。我们需要使用与体系结构相关的寄存器并启动内核。
.S文件是汇编语言文件。它们是一种机器码形式,属于低级编程。所有与机器相关的代码都是用汇编语言编写的,不同处理器的汇编语言是不同的。
为了完整起见:还有另一个“.s”文件,它不是汇编文件,而是“SREC”二进制文件(以ASCII编码),用于编程微控制器。
https://en.wikipedia.org/wiki/SREC_(file_format)
打开这样的文件后,你会看到像这样的文本行:S315000000500C9413110C94D510189518950C949710B0
S31500000060189518950C941010189518950C946A10FC
S31500000070189518950C9403131895189518951895B6
S315000000800C940B1218951895189518950C944912FE
S315000000900C943D101895189518951895189518955F
.asm
? - Liga.s
/.S
,但如今在现代的x86上,通常使用.asm
作为NASM/YASM/FASM/MASM/JWASM等源文件的扩展名(使用dd
指令),而对于GAS/clang汇编源文件,则使用.S
扩展名(使用.long
指令,并默认采用AT&T语法)。我认为有些人确实会将.asm
用于GAS源文件,特别是对于其他架构,如ARM,也许特别是嵌入式开发。(非GAS ARM汇编器,如Keil使用不同的语法。) - Peter Cordes