您的位置:首页 > 其它

[翻译]如何用汇编创建一个基础内核 (三)

2011-03-12 23:45 573 查看
原文是 OSDev Wiki上的一个 Tutorials 文章。

1,第一个启动扇区

2,使用BIOS写消息

3,看看机器码

4,不用BIOS向屏幕打印输出

5,中断

6,进入保护模式

7,非实模式

8,32 位打印输出

附录A,更多资讯



3,看看机器码

上代码:

; nasmw encode.asm -f bin -o encode.bin

mov cx, 0xFF
times 510-($-$$) db 0
db 0x55
db 0xAA

C:\osdev\debug encode.bin

别把代码写入磁盘。windows用户使用 DEBUG高度, linux用户使用 Hexdump命令。

在“-”之后键入“d”看看二进制文件。("?"查看帮助,"q"退出) 。你会看到一些如下的东西:

0AE3:0100 B9 FF 00 00 00 00 etc...

http://www.baldwin.cx/386htm/MOV.htmhttp://www.baldwin.cx/386htm/s17_02.htm查看 mov 指令的 opcode相关介绍。

也就是说,你在转储中看到的,唯一一个寄存器(CX=1)到在基础 opcode 编码中编码为‘B8’。

但在当你用 ECX替换 CX时,会发生什么事:

mov ecx, 0xFF
times 510-($-$$) db 0
db 0x55
db 0xAA

0AE3:0100 66 B9 FF 00 00 00 00 etc...

"66" 是汇编器在默认模式下,以按地址大小覆盖操作数前缀的生成方式。当你使用NASM生成二进制文件时,它是16位格式的。同样,当你使用 bits 指令来改变字长模式时,会生成不同的操作码:

[BITS 32]
2 mov cx, 0xFF
times 510-($-$$) db 0 db 0x55
db 0xAA

这实际上并没有改变处理器的模式,但它确实有助于解决后面的字节序列。

地址

地址编码有点复杂:

mov cx, [temp]

temp db 0x99
times 510-($-$$) db 0
db 0x55
db 0xAA

0AE3:0100 8B 0E 04 00 99 00 00 00 etc...

“8B”是opcode

"0E"是帮助opcode解释的 Mod R/M 字节

http://www.baldwin.cx/386htm/s17_02.htm 的17.2.1节查看 “ModR/M and SIB Bytes”。

解释,参见图17-2(译注,指上面的连接中的图17-2),可见这个字节是包含有不同的域的,

参照这个图表可以更容易理解这个规则。查看“0E”,你会看到右边标“disp 16”,这是指是

按16位偏移来解释,“0400” 就是这个16位的偏移。若你不清楚为什么是 “0X0004”,这是因为

Intel处理器是小端的。一个数的小端是在前面的。

“99”就理所当然是在0x0004处字节的修正了。(8B的是0x0000)

有另一种 按地址大小覆盖操作数的前缀是“67”,就是上面的“66”一样。

造成这种现象有许多原因。当我们从16位实模式转入32位保护模式时,我们的代码也将发生变化。

而注意到这种细节,可以减少对这种转换的错误认识 。

(第三篇END)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: