实际上就是如何让汇编程序(内不涉及DOS调用,但可能有BIOS调用)能够在一台裸机上开机自动运行?
有没有不是写“软盘”引导区的方法,因为现在电脑“软驱”都没有了。
------解决方案--------------------------------------------------------
有的。为兄的正在写一本汇编的书,里面就是这样做的。首先从MBR进入加载器,加载器从其它扇区读入用户程序,分析它,并重定位各个段,然后将控制权交给它。本书有两个地方涉及到这个问题,一个是讲实模式的时候;另一个是讲保护模式的时候。换句话说,两种模式的实现方法。
唯一的问题是,程序的格式和流行的EXE/COM不同。如果你是想加载EXE程序,就算了。
以下是前半部分的目录:
目录
前 言 3
目 录 4
第1部分 预备知识 5
第一章 十六进制计数法 6
1.1 二进制计数法回顾 6
1.1.1 关于二进制计数法 6
1.1.2 二进制到十进制的转换 6
1.1.3 十进制到二进制的转换 7
1.2 十六进制计数法 7
1.2.1 十六进制计数法的原理 7
1.2.2 十六进制到十进制的转换 8
1.2.3 十进制到十六进制的转换 8
1.3 为什么需要十六进制 9
本章习题 10
第二章 处理器、内存和指令 11
2.1 最早的处理器 11
2.2 寄存器和算术逻辑部件 11
2.3 内存储器 12
2.4 指令和指令集 13
2.5 古老的INTEL 8086处理器 14
2.5.1 8086的通用寄存器 15
2.5.2 程序的重定位难题 15
2.5.3 内存分段机制 17
2.5.4 8086的内存分段机制 17
本章习题 19
第三章 汇编语言和汇编软件 20
3.1 汇编语言简介 20
3.2 NASM编译器 21
3.2.1 从网上下载NASM安装程序 21
3.2.2 安装NASM编译器 22
3.2.3 下载配书源码和工具 23
3.2.4 用nasmide体验代码的书写和编译过程 24
3.2.5 用HexView观察编译后的机器代码 25
本章习题 26
第四章 虚拟机的安装和使用 27
4.1 计算机的启动过程 27
4.1.1 如何将编译好的程序提交给处理器 27
4.1.2 计算机的加电和复位 27
4.1.3 基本输入输出系统BIOS 28
4.1.4 硬盘及其工作原理 29
4.1.5 一切从主引导扇区开始 30
4.2 创建和使用虚拟机 30
4.2.1 别害怕,虚拟机是软件 30
4.2.2 下载Oracle VM VirtualBox 31
4.2.3 安装Oracle VM VirtualBox 31
4.2.4 创建一台虚拟PC(个人计算机) 32
4.2.5 虚拟硬盘(VHD)简介 34
4.2.6 练习使用FixVhdWr工具向虚拟硬盘写数据 35
第2部分 16位处理器下的实模式 38
第五章 编写主引导扇区代码 39
5.1 欢迎来到主引导扇区 39
5.1.1 本章意图 39
5.1.2 本章代码清单 39
5.2 注释 42
5.3 在屏幕上显示文字 42
5.3.1 显卡和显存 42
5.3.2 初始化段寄存器 44
5.3.3 显存的访问和ASCII代码 44
5.3.4 在屏幕上显示字符 46
5.4 显示标号的汇编地址 47
5.4.1 标号 47
5.4.2 如何显示十进制数字 50
5.4.3 在程序中声明并初始化数据(伪指令db/dw/dd/dq) 51
5.4.4 分解数的各个数位(div/and/xor) 51
5.4.5 显示分解出来的各个数位(add) 55
5.5 使程序进入无限循环状态 56
5.6 完成并编译主引导扇区代码 56
5.6.1 主引导扇区有效标志(伪指令times) 56
5.6.2 代码的保存和编译 57
5.7 加载和运行主引导扇区代码 57
5.7.1 把编译后的指令写入主引导扇区 57
5.7.2 启动虚拟机观察运行结果 58
本章习题 59
第六章 相同的功能,不同的代码 60
6.1 本章代码清单 60
6.2 跳过非指令的数据区 62
6.3 在数据声明中使用字面值 62
6.4 段地址的初始化 62
6.5 段之间的批量数据传送(cld/std/movsb/movsw) 63
6.6 使用循环分解数位(inc /loop) 64
6.7 计算机中的负数 65
6.7.1 无符号数和有符号数(neg/cbw/cwd) 65
6.7.2 处理器视角中的数据类型(sub/ idiv) 67
6.8 数位的显示(dec/jns) 69
6.9 其它标志位和条件转移指令 70
6.9.1 奇偶标志位PF(Parity Flag) 70
6.9.2 进位标志CF(Carry Flag)。 70
6.9.3 溢出标志OF(overflow flag) 71
6.9.4 现有指令对标志位的影响 71
6.9.5 条件转移指令(cmp/jcc) 72
6.10 NASM编译器的$和$$标记 74
6.11 观察运行结果 74
本章习题 74
第七章 比高斯更快的计算 76
7.1 从1加到100的故事 76
7.2 本章代码清单 76
7.3 显示字符串 79
7.4 计算1到100的累加和 79
7.5 累加和各个数位的分解和显示 79
7.5.1 堆栈和堆栈段的初始化 79
7.5.2 分解各个数位并压栈(or/push) 80
7.5.3 出栈并显示各个数位(pop) 82
7.5.4 进一步认识堆栈 82
7.6 程序的编译和运行 83
7.7 8086处理器的寻址方式 83
7.7.1 寄存器寻址 84
7.7.2 立即寻址 84
7.7.3 内存寻址 84
本章习题 88
第八章 直接硬盘读和带光标跟随的字符显示 89
8.1 本章代码清单 89
8.1.1 本章意图 89
8.1.2 主引导扇区(加载器)代码清单 89
8.1.3 用户程序代码清单 94
8.2 用户程序的结构 99
8.2.1 分段、段的汇编地址和段内汇编地址 99
8.2.2 用户程序头部 101
8.3 加载程序(器)的工作流程 102
8.3.1 初始化和决定加载位置(伪指令equ) 102
8.3.2 准备加载用户程序 103
8.3.3 外围设备及其接口 104
8.3.4 I/O端口和端口访问(in/out) 105
8.3.5 通过硬盘控制器端口读扇区数据 107
8.3.6 过程调用(call/call far/ret/retf) 109
8.3.7 加载用户程序 113
8.3.8 用户程序重定位(adc/shr/shl/ror/rol) 114
8.3.9 将控制权交给用户程序(jmp far) 116
8.3.10 8086处理器的无条件转移指令 116
8.4 用户程序的工作流程 118
8.4.1 初始化段寄存器和堆栈切换 118
8.4.2 调用字符串显示例程 119
8.4.3 过程的嵌套 119
8.4.4 屏幕光标控制 120
8.4.5 取当前光标位置 120
8.4.6 处理回车和换行字符(mul) 121
8.4.7 显示可打印字符 122
8.4.8 滚动屏幕内容 122
8.4.9 重置光标 122
8.4.10 切换到另一个代码中执行 123
8.4.11 访问另一个数据段 123
8.5 编译和运行程序并观察结果 123
本章习题 124
第九章 中断和动态时钟显示 125