您的位置:首页 > 其它

硬盘和显卡的访问与控制(一)——《x86汇编语言:从实模式到保护模式》读书笔记01

2016-08-23 09:43 537 查看
本文是《x86汇编语言:从实模式到保护模式》(电子工业出版社)的读书实验笔记。

这篇文章我们先不分析代码,而是说一下在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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐