硬盘和显卡的访问与控制(一)——《x86汇编语言:从实模式到保护模式》读书笔记01
2016-08-23 09:43
537 查看
本文是《x86汇编语言:从实模式到保护模式》(电子工业出版社)的读书实验笔记。
这篇文章我们先不分析代码,而是说一下在Bochs环境下如何看到实验结果。
需要的源码文件
第一个文件是加载程序
需要说明的是:
书上假设是从硬盘启动,本文假设从软盘启动
第二个文件是用户程序
2.利用源码生成.bin文件
nasm -f bin c08_mbr.asm -o c08mbr.bin
nasm -f bin c08.asm -o c08usr.bin
这时候会提示:
c08.asm:203: warning: uninitialized space declared in stack section: zeroing
“这句话的意思是,c08.asm源程序的第203行声明了未初始化的空间。”本实验的栈空间可以不初始化,所以不用管这个警告。
3.把c08mbr.bin写入启动软盘文件
dd if=c08mbr.bin of=a.img
4.制作一个空的硬盘
因为根据源码,我们知道用户程序在硬盘上,所以我们要制作一个硬盘镜像文件——利用工具bximage
在命令行输入 bximage,其他操作如图所示
注意到最下面的提示了吗?
“The following line should appear in your bochsrc:
ata0-master: type=disk, path=”c.img”, mode=flat, cylinders=2, heads=16, spt=63”
由于我们启动Bochs的时候没有用默认的配置文件,所以我们需要在自己的配置文件中添加这一行
需要注意的是,我们这张硬盘有2016个扇区(每个扇区大小是512字节)
5.把用户程序c08usr.bin写入硬盘镜像
注意:notrunc的含义是,如果目标文件(这里就是c.img)比来源文件大,不截断目标文件多出来的那部分内容。
比如c.img已经有1024字节了,而c08usr.bin假设只有512字节,如果seek=0,那么不加conv=notrunc,c.img就会变成512字节。
【dd命令说明】
if=输入文件
of=输出文件
ibs = n_bytes 一次读取n_bytes字节,即读入缓冲区的字节数。
obs = n_bytes 一次写入n_bytes字节,即写 入缓冲区的字节数。
bs = n_bytes 同时设置读/写缓冲区的字节数(等于设置ibs和obs)。
count=n_blocks:仅拷贝 n_blocks 个块,块大小等于 ibs 指定的字节数
conv=sync:把每个输入记录的大小都调到ibs的大小(不足的话用Null填充)。
skip=xxx指在备份时对if 后面的部分也就是原文件跳过多少块再开始备份(block size由ibs指定 )
seek=xxx指在备份时对of 后面的部分也就是目标文件跳过多少块再开始写(block size由obs指定 )
6.启动Bochs,查看结果
我们可以看到,应用程序成功地被加载器加载了。
关于本文的源码,我们下次再说明。
Goodbye
这篇文章我们先不分析代码,而是说一下在Bochs环境下如何看到实验结果。
需要的源码文件
第一个文件是加载程序
<code class="hljs avrasm has-numbering"> <span class="hljs-comment">;代码清单8-1</span> <span class="hljs-comment">;文件名:c08_mbr.asm</span> <span class="hljs-comment">;文件说明:硬盘主引导扇区代码(加载程序) </span> <span class="hljs-comment">;创建日期:2011-5-5 18:17</span> app_lba_start equ <span class="hljs-number">100</span> <span class="hljs-comment">;声明常数(用户程序起始逻辑扇区号)</span> <span class="hljs-comment">;常数的声明不会占用汇编地址</span> SECTION mbr align=<span class="hljs-number">16</span> vstart=<span class="hljs-number">0x7c00</span> <span class="hljs-comment">;设置堆栈段和栈指针 </span> <span class="hljs-keyword">mov</span> ax,<span class="hljs-number">0</span> <span class="hljs-keyword">mov</span> ss,ax <span class="hljs-keyword">mov</span> sp,ax <span class="hljs-keyword">mov</span> ax,[cs:phy_base] <span class="hljs-comment">;计算用于加载用户程序的逻辑段地址 </span> <span class="hljs-keyword">mov</span> dx,[cs:phy_base+<span class="hljs-number">0x02</span>] <span class="hljs-keyword">mov</span> bx,<span class="hljs-number">16</span> div bx <span class="hljs-keyword">mov</span> ds,ax <span class="hljs-comment">;令DS和ES指向该段以进行操作</span> <span class="hljs-keyword">mov</span> es,ax <span class="hljs-comment">;以下读取程序的起始部分 </span> xor di,di <span class="hljs-keyword">mov</span> si,app_lba_start <span class="hljs-comment">;程序在硬盘上的起始逻辑扇区号 (扇区号为28位,存放在di:si)</span> xor bx,bx <span class="hljs-comment">;加载到DS:0x0000处 </span> <span class="hljs-keyword">call</span> read_hard_disk_0 <span class="hljs-comment">;以下判断整个程序有多大</span> <span class="hljs-keyword">mov</span> dx,[<span class="hljs-number">2</span>] <span class="hljs-comment">;曾经把dx写成了ds,花了二十分钟排错 </span> <span class="hljs-keyword">mov</span> ax,[<span class="hljs-number">0</span>] <span class="hljs-keyword">mov</span> bx,<span class="hljs-number">512</span> <span class="hljs-comment">;512字节每扇区</span> div bx cmp dx,<span class="hljs-number">0</span> jnz <span class="hljs-localvars">@1</span> <span class="hljs-comment">;未除尽,因此结果比实际扇区数少1 </span> <span class="hljs-keyword">dec</span> ax <span class="hljs-comment">;已经读了一个扇区,扇区总数减1 </span> <span class="hljs-localvars">@1</span>: cmp ax,<span class="hljs-number">0</span> <span class="hljs-comment">;考虑实际长度小于等于512个字节的情况 </span> jz direct <span class="hljs-comment">;读取剩余的扇区</span> <span class="hljs-keyword">push</span> ds <span class="hljs-comment">;以下要用到并改变DS寄存器 </span> <span class="hljs-keyword">mov</span> cx,ax <span class="hljs-comment">;循环次数(剩余扇区数)</span> <span class="hljs-localvars">@2</span>: <span class="hljs-keyword">mov</span> ax,ds <span class="hljs-keyword">add</span> ax,<span class="hljs-number">0x20</span> <span class="hljs-comment">;得到下一个以512字节为边界的段地址</span> <span class="hljs-keyword">mov</span> ds,ax xor bx,bx <span class="hljs-comment">;每次读时,偏移地址始终为0x0000 </span> <span class="hljs-keyword">inc</span> si <span class="hljs-comment">;下一个逻辑扇区 </span> <span class="hljs-keyword">call</span> read_hard_disk_0 loop <span class="hljs-localvars">@2</span> <span class="hljs-comment">;循环读,直到读完整个功能程序 </span> <span class="hljs-keyword">pop</span> ds <span class="hljs-comment">;恢复数据段基址到用户程序头部段 </span> <span class="hljs-comment">;======================================================================================</span> <span class="hljs-comment">;计算入口点代码段基址 </span> direct: <span class="hljs-keyword">mov</span> dx,[<span class="hljs-number">0x08</span>] <span class="hljs-keyword">mov</span> ax,[<span class="hljs-number">0x06</span>] <span class="hljs-keyword">call</span> calc_segment_base <span class="hljs-keyword">mov</span> [<span class="hljs-number">0x06</span>],ax <span class="hljs-comment">;回填修正后的入口点代码段基址 </span> <span class="hljs-comment">;开始处理段重定位表</span> <span class="hljs-keyword">mov</span> cx,[<span class="hljs-number">0x0a</span>] <span class="hljs-comment">;需要重定位的项目数量</span> <span class="hljs-keyword">mov</span> bx,<span class="hljs-number">0x0c</span> <span class="hljs-comment">;重定位表首地址</span> realloc: <span class="hljs-keyword">mov</span> dx,[bx+<span class="hljs-number">0x02</span>] <span class="hljs-comment">;32位地址的高16位 </span> <span class="hljs-keyword">mov</span> ax,[bx] <span class="hljs-keyword">call</span> calc_segment_base <span class="hljs-keyword">mov</span> [bx],ax <span class="hljs-comment">;回填段的基址</span> <span class="hljs-keyword">add</span> bx,<span class="hljs-number">4</span> <span class="hljs-comment">;下一个重定位项(每项占4个字节) </span> loop realloc <span class="hljs-keyword">jmp</span> far [<span class="hljs-number">0x04</span>] <span class="hljs-comment">;转移到用户程序 </span> <span class="hljs-comment">;-------------------------------------------------------------------------------</span> <span class="hljs-label">read_hard_disk_0:</span> <span class="hljs-comment">;从硬盘读取一个逻辑扇区</span> <span class="hljs-comment">;输入:DI:SI=起始逻辑扇区号</span> <span class="hljs-comment">; DS:BX=目标缓冲区地址</span> <span class="hljs-keyword">push</span> ax <span class="hljs-keyword">push</span> bx <span class="hljs-keyword">push</span> cx <span class="hljs-keyword">push</span> dx <span class="hljs-keyword">mov</span> dx,<span class="hljs-number">0x1f2</span> <span class="hljs-keyword">mov</span> al,<span class="hljs-number">1</span> <span class="hljs-keyword">out</span> dx,al <span class="hljs-comment">;读取的扇区数</span> <span class="hljs-keyword">inc</span> dx <span class="hljs-comment">;0x1f3</span> <span class="hljs-keyword">mov</span> ax,si <span class="hljs-keyword">out</span> dx,al <span class="hljs-comment">;LBA地址7~0</span> <span class="hljs-keyword">inc</span> dx <span class="hljs-comment">;0x1f4</span> <span class="hljs-keyword">mov</span> al,ah <span class="hljs-keyword">out</span> dx,al <span class="hljs-comment">;LBA地址15~8</span> <span class="hljs-keyword">inc</span> dx <span class="hljs-comment">;0x1f5</span> <span class="hljs-keyword">mov</span> ax,di <span class="hljs-keyword">out</span> dx,al <span class="hljs-comment">;LBA地址23~16</span> <span class="hljs-keyword">inc</span> dx <span class="hljs-comment">;0x1f6</span> <span class="hljs-keyword">mov</span> al,<span class="hljs-number">0xe0</span> <span class="hljs-comment">;LBA28模式,主盘</span> <span class="hljs-keyword">or</span> al,ah <span class="hljs-comment">;LBA地址27~24</span> <span class="hljs-keyword">out</span> dx,al <span class="hljs-keyword">inc</span> dx <span class="hljs-comment">;0x1f7</span> <span class="hljs-keyword">mov</span> al,<span class="hljs-number">0x20</span> <span class="hljs-comment">;读命令</span> <span class="hljs-keyword">out</span> dx,al <span class="hljs-preprocessor">.waits</span>: <span class="hljs-keyword">in</span> al,dx <span class="hljs-keyword">and</span> al,<span class="hljs-number">0x88</span> cmp al,<span class="hljs-number">0x08</span> jnz <span class="hljs-preprocessor">.waits</span> <span class="hljs-comment">;不忙,且硬盘已准备好数据传输 </span> <span class="hljs-keyword">mov</span> cx,<span class="hljs-number">256</span> <span class="hljs-comment">;总共要读取的字数</span> <span class="hljs-keyword">mov</span> dx,<span class="hljs-number">0x1f0</span> <span class="hljs-preprocessor">.readw</span>: <span class="hljs-keyword">in</span> ax,dx <span class="hljs-keyword">mov</span> [bx],ax <span class="hljs-keyword">add</span> bx,<span class="hljs-number">2</span> loop <span class="hljs-preprocessor">.readw</span> <span class="hljs-keyword">pop</span> dx <span class="hljs-keyword">pop</span> cx <span class="hljs-keyword">pop</span> bx <span class="hljs-keyword">pop</span> ax <span class="hljs-keyword">ret</span> <span class="hljs-comment">;-------------------------------------------------------------------------------</span> <span class="hljs-label">calc_segment_base:</span> <span class="hljs-comment">;计算16位段地址</span> <span class="hljs-comment">;输入:DX:AX=32位物理地址</span> <span class="hljs-comment">;返回:AX=16位段基地址 </span> <span class="hljs-keyword">push</span> dx <span class="hljs-keyword">add</span> ax,[cs:phy_base] <span class="hljs-keyword">adc</span> dx,[cs:phy_base+<span class="hljs-number">0x02</span>] shr ax,<span class="hljs-number">4</span> <span class="hljs-keyword">ror</span> dx,<span class="hljs-number">4</span> <span class="hljs-keyword">and</span> dx,<span class="hljs-number">0xf000</span> <span class="hljs-keyword">or</span> ax,dx <span class="hljs-keyword">pop</span> dx <span class="hljs-keyword">ret</span> <span class="hljs-comment">;-------------------------------------------------------------------------------</span> phy_base dd <span class="hljs-number">0x10000</span> <span class="hljs-comment">;用户程序被加载的物理起始地址</span> times <span class="hljs-number">510</span>-($-$$) db <span class="hljs-number">0</span> db <span class="hljs-number">0x55</span>,<span class="hljs-number">0xaa</span> </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li><li>102</li><li>103</li><li>104</li><li>105</li><li>106</li><li>107</li><li>108</li><li>109</li><li>110</li><li>111</li><li>112</li><li>113</li><li>114</li><li>115</li><li>116</li><li>117</li><li>118</li><li>119</li><li>120</li><li>121</li><li>122</li><li>123</li><li>124</li><li>125</li><li>126</li><li>127</li><li>128</li><li>129</li><li>130</li><li>131</li><li>132</li><li>133</li><li>134</li><li>135</li><li>136</li><li>137</li><li>138</li><li>139</li><li>140</li><li>141</li><li>142</li><li>143</li><li>144</li><li>145</li><li>146</li><li>147</li><li>148</li><li>149</li><li>150</li><li>151</li><li>152</li><li>153</li><li>154</li><li>155</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li><li>102</li><li>103</li><li>104</li><li>105</li><li>106</li><li>107</li><li>108</li><li>109</li><li>110</li><li>111</li><li>112</li><li>113</li><li>114</li><li>115</li><li>116</li><li>117</li><li>118</li><li>119</li><li>120</li><li>121</li><li>122</li><li>123</li><li>124</li><li>125</li><li>126</li><li>127</li><li>128</li><li>129</li><li>130</li><li>131</li><li>132</li><li>133</li><li>134</li><li>135</li><li>136</li><li>137</li><li>138</li><li>139</li><li>140</li><li>141</li><li>142</li><li>143</li><li>144</li><li>145</li><li>146</li><li>147</li><li>148</li><li>149</li><li>150</li><li>151</li><li>152</li><li>153</li><li>154</li><li>155</li></ul>
需要说明的是:
书上假设是从硬盘启动,本文假设从软盘启动
第二个文件是用户程序
<code class="hljs perl has-numbering"> ;代码清单<span class="hljs-number">8</span>-<span class="hljs-number">2</span> ;文件名:c08.asm ;文件说明:用户程序 ;创建日期:<span class="hljs-number">2011</span>-<span class="hljs-number">5</span>-<span class="hljs-number">5</span> <span class="hljs-number">18</span>:<span class="hljs-number">17</span> ;=============================================================================== SECTION header vstart=<span class="hljs-number">0</span> ;定义用户程序头部段 program_length dd program_end ;程序总长度[<span class="hljs-number">0x00</span>] ;用户程序入口点 code_entry dw start ;偏移地址[<span class="hljs-number">0x04</span>] dd section.code_1.start ;段地址[<span class="hljs-number">0x06</span>] realloc_tbl_len dw (header_end-code_1_segment)/<span class="hljs-number">4</span> ;段重定位表项个数[<span class="hljs-number">0x0a</span>] ;段重定位表 code_1_segment dd section.code_1.start ;[<span class="hljs-number">0x0c</span>] code_2_segment dd section.code_2.start ;[<span class="hljs-number">0x10</span>] data_1_segment dd section.data_1.start ;[<span class="hljs-number">0x14</span>] data_2_segment dd section.data_2.start ;[<span class="hljs-number">0x18</span>] stack_segment dd section.stack.start ;[<span class="hljs-number">0x1c</span>] header_end: ;=============================================================================== SECTION code_1 align=<span class="hljs-number">16</span> vstart=<span class="hljs-number">0</span> ;定义代码段<span class="hljs-number">1</span>(<span class="hljs-number">16</span>字节对齐) put_string: ;显示串(<span class="hljs-number">0</span>结尾)。 ;输入:DS:BX=串地址 mov cl,[bx] <span class="hljs-keyword">or</span> cl,cl ;cl=<span class="hljs-number">0</span> ? jz .<span class="hljs-keyword">exit</span> ;是的,返回主程序 call put_char inc bx ;下一个字符 jmp put_string .<span class="hljs-keyword">exit</span>: ret ;------------------------------------------------------------------------------- put_char: ;显示一个字符 ;输入:cl=字符ascii <span class="hljs-keyword">push</span> ax <span class="hljs-keyword">push</span> bx <span class="hljs-keyword">push</span> cx <span class="hljs-keyword">push</span> dx <span class="hljs-keyword">push</span> ds <span class="hljs-keyword">push</span> es ;以下取当前光标位置 mov dx,<span class="hljs-number">0x3d4</span> mov al,<span class="hljs-number">0x0e</span> out dx,al mov dx,<span class="hljs-number">0x3d5</span> in al,dx ;高<span class="hljs-number">8</span>位 mov ah,al mov dx,<span class="hljs-number">0x3d4</span> mov al,<span class="hljs-number">0x0f</span> out dx,al mov dx,<span class="hljs-number">0x3d5</span> in al,dx ;低<span class="hljs-number">8</span>位 mov bx,ax ;BX=代表光标位置的<span class="hljs-number">16</span>位数 cmp cl,<span class="hljs-number">0x0d</span> ;回车符? jnz .put_0a ;不是。看看是不是换行等字符 mov ax,bx ;此句略显多余,但去掉后还得改书,麻烦 mov bl,<span class="hljs-number">80</span> div bl mul bl mov bx,ax jmp .set_cursor .put_0a: cmp cl,<span class="hljs-number">0x0a</span> ;换行符? jnz .put_other ;不是,那就正常显示字符 add bx,<span class="hljs-number">80</span> jmp .roll_screen .put_other: ;正常显示字符 mov ax,<span class="hljs-number">0xb800</span> mov es,ax shl bx,<span class="hljs-number">1</span> mov [es:bx],cl ;以下将光标位置推进一个字符 shr bx,<span class="hljs-number">1</span> add bx,<span class="hljs-number">1</span> .roll_screen: cmp bx,<span class="hljs-number">2000</span> ;光标超出屏幕?滚屏 jl .set_cursor mov ax,<span class="hljs-number">0xb800</span> mov ds,ax mov es,ax cld mov si,<span class="hljs-number">0xa0</span> mov di,<span class="hljs-number">0x00</span> mov cx,<span class="hljs-number">1920</span> rep movsw mov bx,<span class="hljs-number">3840</span> ;清除屏幕最底一行 mov cx,<span class="hljs-number">80</span> .cls: mov word[es:bx],<span class="hljs-number">0x0720</span> ; space add bx,<span class="hljs-number">2</span> loop .cls mov bx,<span class="hljs-number">1920</span> .set_cursor: mov dx,<span class="hljs-number">0x3d4</span> mov al,<span class="hljs-number">0x0e</span> out dx,al mov dx,<span class="hljs-number">0x3d5</span> mov al,bh out dx,al mov dx,<span class="hljs-number">0x3d4</span> mov al,<span class="hljs-number">0x0f</span> out dx,al mov dx,<span class="hljs-number">0x3d5</span> mov al,bl out dx,al <span class="hljs-keyword">pop</span> es <span class="hljs-keyword">pop</span> ds <span class="hljs-keyword">pop</span> dx <span class="hljs-keyword">pop</span> cx <span class="hljs-keyword">pop</span> bx <span class="hljs-keyword">pop</span> ax ret ;---------------------------------- 用户程序入口 -------------------------------------------- start: ;初始执行时,DS和ES指向用户程序头部段 mov ax,[stack_segment] ;设置到用户程序自己的堆栈 mov ss,ax mov sp,stack_end mov ax,[data_1_segment] ;设置到用户程序自己的数据段 mov ds,ax mov bx,msg<span class="hljs-number">0</span> call put_string ;显示第一段信息 <span class="hljs-keyword">push</span> word [es:code_2_segment] mov ax,begin <span class="hljs-keyword">push</span> ax ;可以直接<span class="hljs-keyword">push</span> begin,<span class="hljs-number">80386</span>+ retf ;转移到代码段<span class="hljs-number">2</span>执行 <span class="hljs-keyword">continue</span>: mov ax,[es:data_2_segment] ;段寄存器DS切换到数据段<span class="hljs-number">2</span> mov ds,ax mov bx,msg1 call put_string ;显示第二段信息 jmp $ ;=============================================================================== SECTION code_2 align=<span class="hljs-number">16</span> vstart=<span class="hljs-number">0</span> ;定义代码段<span class="hljs-number">2</span>(<span class="hljs-number">16</span>字节对齐) begin: <span class="hljs-keyword">push</span> word [es:code_1_segment] mov ax,<span class="hljs-keyword">continue</span> <span class="hljs-keyword">push</span> ax ;可以直接<span class="hljs-keyword">push</span> <span class="hljs-keyword">continue</span>,<span class="hljs-number">80386</span>+ retf ;转移到代码段<span class="hljs-number">1</span>接着执行 ;=============================================================================== SECTION data_1 align=<span class="hljs-number">16</span> vstart=<span class="hljs-number">0</span> msg<span class="hljs-number">0</span> db <span class="hljs-string">' This is NASM - the famous Netwide Assembler. '</span> db <span class="hljs-string">'Back at SourceForge and in intensive development! '</span> db <span class="hljs-string">'Get the current versions from http://www.nasm.us/.'</span> db <span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' Example code for calculate 1+2+...+1000:'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' xor dx,dx'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' xor ax,ax'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' xor cx,cx'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' @@:'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' inc cx'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' add ax,cx'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' adc dx,0'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' inc cx'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' cmp cx,1000'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' jle @@'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-string">' ... ...(Some other codes)'</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span>,<span class="hljs-number">0x0d</span>,<span class="hljs-number">0x0a</span> db <span class="hljs-number">0</span> ;=============================================================================== SECTION data_2 align=<span class="hljs-number">16</span> vstart=<span class="hljs-number">0</span> msg1 db <span class="hljs-string">' The above contents is written by LeeChung. '</span> db <span class="hljs-string">'2011-05-06'</span> db <span class="hljs-number">0</span> ;=============================================================================== SECTION stack align=<span class="hljs-number">16</span> vstart=<span class="hljs-number">0</span> resb <span class="hljs-number">256</span> stack_end: ;=============================================================================== SECTION trail align=<span class="hljs-number">16</span> program_end: </code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li><li>102</li><li>103</li><li>104</li><li>105</li><li>106</li><li>107</li><li>108</li><li>109</li><li>110</li><li>111</li><li>112</li><li>113</li><li>114</li><li>115</li><li>116</li><li>117</li><li>118</li><li>119</li><li>120</li><li>121</li><li>122</li><li>123</li><li>124</li><li>125</li><li>126</li><li>127</li><li>128</li><li>129</li><li>130</li><li>131</li><li>132</li><li>133</li><li>134</li><li>135</li><li>136</li><li>137</li><li>138</li><li>139</li><li>140</li><li>141</li><li>142</li><li>143</li><li>144</li><li>145</li><li>146</li><li>147</li><li>148</li><li>149</li><li>150</li><li>151</li><li>152</li><li>153</li><li>154</li><li>155</li><li>156</li><li>157</li><li>158</li><li>159</li><li>160</li><li>161</li><li>162</li><li>163</li><li>164</li><li>165</li><li>166</li><li>167</li><li>168</li><li>169</li><li>170</li><li>171</li><li>172</li><li>173</li><li>174</li><li>175</li><li>176</li><li>177</li><li>178</li><li>179</li><li>180</li><li>181</li><li>182</li><li>183</li><li>184</li><li>185</li><li>186</li><li>187</li><li>188</li><li>189</li><li>190</li><li>191</li><li>192</li><li>193</li><li>194</li><li>195</li><li>196</li><li>197</li><li>198</li><li>199</li><li>200</li><li>201</li><li>202</li><li>203</li><li>204</li><li>205</li><li>206</li><li>207</li><li>208</li><li>209</li><li>210</li><li>211</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li><li>102</li><li>103</li><li>104</li><li>105</li><li>106</li><li>107</li><li>108</li><li>109</li><li>110</li><li>111</li><li>112</li><li>113</li><li>114</li><li>115</li><li>116</li><li>117</li><li>118</li><li>119</li><li>120</li><li>121</li><li>122</li><li>123</li><li>124</li><li>125</li><li>126</li><li>127</li><li>128</li><li>129</li><li>130</li><li>131</li><li>132</li><li>133</li><li>134</li><li>135</li><li>136</li><li>137</li><li>138</li><li>139</li><li>140</li><li>141</li><li>142</li><li>143</li><li>144</li><li>145</li><li>146</li><li>147</li><li>148</li><li>149</li><li>150</li><li>151</li><li>152</li><li>153</li><li>154</li><li>155</li><li>156</li><li>157</li><li>158</li><li>159</li><li>160</li><li>161</li><li>162</li><li>163</li><li>164</li><li>165</li><li>166</li><li>167</li><li>168</li><li>169</li><li>170</li><li>171</li><li>172</li><li>173</li><li>174</li><li>175</li><li>176</li><li>177</li><li>178</li><li>179</li><li>180</li><li>181</li><li>182</li><li>183</li><li>184</li><li>185</li><li>186</li><li>187</li><li>188</li><li>189</li><li>190</li><li>191</li><li>192</li><li>193</li><li>194</li><li>195</li><li>196</li><li>197</li><li>198</li><li>199</li><li>200</li><li>201</li><li>202</li><li>203</li><li>204</li><li>205</li><li>206</li><li>207</li><li>208</li><li>209</li><li>210</li><li>211</li></ul>
2.利用源码生成.bin文件
nasm -f bin c08_mbr.asm -o c08mbr.bin
nasm -f bin c08.asm -o c08usr.bin
这时候会提示:
c08.asm:203: warning: uninitialized space declared in stack section: zeroing
“这句话的意思是,c08.asm源程序的第203行声明了未初始化的空间。”本实验的栈空间可以不初始化,所以不用管这个警告。
3.把c08mbr.bin写入启动软盘文件
dd if=c08mbr.bin of=a.img
4.制作一个空的硬盘
因为根据源码,我们知道用户程序在硬盘上,所以我们要制作一个硬盘镜像文件——利用工具bximage
在命令行输入 bximage,其他操作如图所示
注意到最下面的提示了吗?
“The following line should appear in your bochsrc:
ata0-master: type=disk, path=”c.img”, mode=flat, cylinders=2, heads=16, spt=63”
由于我们启动Bochs的时候没有用默认的配置文件,所以我们需要在自己的配置文件中添加这一行
<code class="hljs rust has-numbering">ata0-master: <span class="hljs-keyword">type</span>=disk, path=<span class="hljs-string">"c.img"</span>, mode=flat, cylinders=<span class="hljs-number">2</span>, heads=<span class="hljs-number">16</span>, spt=<span class="hljs-number">63</span></code><ul style="" class="pre-numbering"><li>1</li></ul><ul style="" class="pre-numbering"><li>1</li></ul>
需要注意的是,我们这张硬盘有2016个扇区(每个扇区大小是512字节)
5.把用户程序c08usr.bin写入硬盘镜像
dd if=c08usr.bin of=c.img bs=512 seek=100 conv=notrunk
注意:notrunc的含义是,如果目标文件(这里就是c.img)比来源文件大,不截断目标文件多出来的那部分内容。
比如c.img已经有1024字节了,而c08usr.bin假设只有512字节,如果seek=0,那么不加conv=notrunc,c.img就会变成512字节。
【dd命令说明】
if=输入文件
of=输出文件
ibs = n_bytes 一次读取n_bytes字节,即读入缓冲区的字节数。
obs = n_bytes 一次写入n_bytes字节,即写 入缓冲区的字节数。
bs = n_bytes 同时设置读/写缓冲区的字节数(等于设置ibs和obs)。
count=n_blocks:仅拷贝 n_blocks 个块,块大小等于 ibs 指定的字节数
conv=sync:把每个输入记录的大小都调到ibs的大小(不足的话用Null填充)。
skip=xxx指在备份时对if 后面的部分也就是原文件跳过多少块再开始备份(block size由ibs指定 )
seek=xxx指在备份时对of 后面的部分也就是目标文件跳过多少块再开始写(block size由obs指定 )
6.启动Bochs,查看结果
我们可以看到,应用程序成功地被加载器加载了。
关于本文的源码,我们下次再说明。
Goodbye
相关文章推荐
- 硬盘和显卡的访问与控制(三)——《x86汇编语言:从实模式到保护模式》读书笔记03
- 硬盘和显卡的访问与控制(二)——《x86汇编语言:从实模式到保护模式》读书笔记02
- 硬盘和显卡的访问与控制(一)——《x86汇编语言:从实模式到保护模式》读书笔记01
- 硬盘和显卡的访问与控制(一)——《x86汇编语言:从实模式到保护模式》读书笔记01
- 硬盘和显卡的访问与控制(三)(含多彩的Hello)——《x86汇编语言:从实模式到保护模式》读书笔记03
- 硬盘和显卡的访问与控制(二)——《x86汇编语言:从实模式到保护模式》读书笔记02
- 硬盘和显卡的访问与控制(二)——《x86汇编语言:从实模式到保护模式》读书笔记02
- 关于访问控制权限01
- 《JAVA编程思想》读书笔记6——访问权限控制
- 《c++ prime》读书笔记--继承和访问控制
- security 01: Linux基本防护 、 用户切换与提权 、 SSH访问控制 、 总结和答疑
- Java编程思想,读书笔记四(第6章 访问权限控制)
- Thinking-in-Java 读书笔记-6-访问权限控制
- 结构型模式01-代理模式(为其他对象提供一种代理以控制这个对象的访问)
- 《面向模式的软件体系结构1--模式系统》读书笔记(4)--- 访问控制
- J-01. 电脑远程访问小米路由器硬盘文件
- 《C++ Primer》读书笔记第七章-1-抽象数据类型 And 访问控制与封装
- 《THING IN JAVA》 6章访问权限控制-读书笔记
- 《c++ prime》读书笔记--继承和访问控制
- [李景山php] 深入理解PHP内核[读书笔记]--第五章:类和面向对象 --访问控制的实现