linux 0.11 bootsect.s 源代码基于什么汇编语言版本(或类型)?

what is the assembly language version (or type) that linux 0.11 bootsect.s source code based on?

我正在学习linux内核源代码。

而且我已经对汇编语言有了一些基本的了解,比如通用指令的用法(比如movaddjmpcall ...), AT&T型和Intel型的区别

所以现在,了解这些 asm 代码的粗略概念对我来说不是什么大问题。但是在下面代码的头部和尾部显示的 .text .data 这样的指令让我很困惑。

所以,我的直接问题是.text对,.data对是什么意思?我的根本问题是 asm 版本或键入这些语法的依据是什么?我认为这是对 Intel 的颠覆,因为常量前没有“$”。但是为什么有'#'和'_start'而不是'main'呢?我在哪里可以找到所有这些相关的 asm 语法的完整介绍?

请帮帮我!

非常感谢!

.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text

BOOTSEG  = 0x07c0           ! original address of boot-sector
INITSEG  = 0x9000           ! we move boot here - out of the way
SETUPSEG = 0x9020           ! setup starts here

entry _start
_start:
    mov ah,#0x03        
    xor bh,bh
    int 0x10
... ...

.text
endtext:
.data
enddata:
.bss
endbss:

完整介绍所有这些相关的asm语法你会在汇编程序的文档中找到。与 mov, add, jmp, call,,, 等机器指令不同,有许多未规范化的指令和伪指令,它们取决于语言作者的个性和经验。

声明.globl begtext, begdata, begbss, endtext, enddata, endbss声明一些标签(稍后在源文本的某处定义)将是全局别名PUBLIC,即它们可以从与内核链接的其他程序模块访问。

标签.text, .data, .bss指令,它告诉汇编程序重定向其输出(发出的代码和数据)到一个特定的分割。可执行程序文件包含一个机器指令段(.text 别名 .code)和数据段(.data, .rodata, .bss),但源文本不必按此顺序编写。 想象一下,Linus(或任何编写源代码的人)是将源代码口述给他的秘书(汇编程序)的老板。他告诉它发出三个使用 BIOS 服务 INT 0x10 将控制台切换到 80*25 文本模式的指令:

.text
 mov ah,#0x03        
 xor bh,bh
 int 0x10

秘书将在标有 .text 的 sheet 纸上写(发出)这些指示。然后 Linus 决定定义一些消息,所以他告诉秘密指令 .data,然后是消息定义:

.data    
 Message DB "Kernel is starting, please wait."

秘书将再拿一张 sheet 纸,在上面贴上标签 .data 并在上面写下消息定义。当 Linus 决定口述其他机器代码时,秘书收回 sheet .text 并在它被中断的位置(原点)继续写入 - 在指令 INT 0x10 下方。通过这种方式,他们可以随意交替输出段 ad libitum 并将数据保持在操作它的代码附近(这有利于程序的可读性)。最后,所有论文 sheet 将被装订(链接)在一起,因此所有机器指令最终在 .text 段中彼此靠近,而相似数据在 .data 段中。

您正在寻找不同的东西:启动代码。

引导码必须是16位的,特殊。它还需要一个不同的 assembler(16 位,实模式)。

所以,我们处于 16 位实模式,所以我们有段。 .text 用于 CS 段(因此 .text 上的偏移量是相对于 CS 的)。 .data 预计用于 DS 段,但这可以更改(并且您可以告诉 assembler,以便它知道计算偏移量很热)。

注意:boot code也比较特殊,因为BIOS在07C0h:0000h和运行里面加载boot code,但是我们把它和运行移到第二部分,所以相同的代码会有不同的 CS 段(您可能会发现一些看似不必要的 LONG JUMP)。然后加载其余的引导代码。然后设置东西(在 BIOS 级别和硬件级别,例如恢复 A20 行),然后准备内存表(我们仍然只有第一个 MB 可用内存(和一些被 BIOS 使用)用于保护和 32 位模式,所以我们可以在 32 位中切换、刷新缓存和执行。然后是其余的设置。

编辑:添加更多解释。

我们处于 16 位实模式,因此内存地址由两个部分计算:段和偏移量(均为 16 位长,段移位 4 位)。所以当前代码在CS:IP中,通常我们读取DS段中的数据(少数例外,或者我们可以显式给出段)。

当您 assemble 代码时,您会在不同的段中获得不同的部分。

.text
begtext:

第一行声明:我们现在处于.text段(text通常用于代码)。下一行我们声明一个标签:begtext,我假设它是用于 beginning of our text segment.

您对其他细分(.data.bss)执行相同的操作。原因是我们想知道初始偏移量,所以我们可以移动数据(我们不知道 assembler 或加载器是否会把 as 放在不同的偏移量,所以在开始定义标签是安全的,所以我们可以使用它,如果我们需要移动代码)。您在文件末尾看到相同的内容(例如 endtext),以了解最后一点,以及使用的段的大小(endtext - begtext)。

注意:我们不能移动整个段,因为段可能重叠,或者 CS 可能是 DS,只是偏移量不同,所以我们有覆盖错误部分的风险(以防我们以不同的顺序移动代码和数据).

entry: 定义入口点:您希望加载程序从 _start 开始。但这取决于生成文件的格式(因此 assembler 指令)。有时你有 org 明确告诉当前位置(例如在 DOS .com 文件中我们有 org 100h,IIRC,那是 DOS 调用的入口点)。

您还定义了一些常量(07c0 是 PC 上的 BIOS 加载和执行引导扇区的位置)。

.glovl 只是将值声明为“全局”,因此如果你想“link”几个文件,那么导出并在其他模块上可用。