linux 0.11 bootsect.s 源代码基于什么汇编语言版本(或类型)?
what is the assembly language version (or type) that linux 0.11 bootsect.s source code based on?
我正在学习linux内核源代码。
而且我已经对汇编语言有了一些基本的了解,比如通用指令的用法(比如mov
、add
、jmp
、call
...), 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”几个文件,那么导出并在其他模块上可用。
我正在学习linux内核源代码。
而且我已经对汇编语言有了一些基本的了解,比如通用指令的用法(比如mov
、add
、jmp
、call
...), 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”几个文件,那么导出并在其他模块上可用。