硬盘和显卡的访问与控制(一)——《x86汇编语言:从实模式到保护模式》读书笔记01
本文是《x86匯編語言:從實模式到保護模式》(電子工業(yè)出版社)的讀書實驗筆記。
這篇文章我們先不分析代碼,而是說一下在Bochs環(huán)境下如何看到實驗結(jié)果。
第一個文件是加載程序
需要說明的是:
書上假設(shè)是從硬盤啟動,本文假設(shè)從軟盤啟動
第二個文件是用戶程序
<code class="hljs perl has-numbering"> ;代碼清單<span class="hljs-number">8</span>-<span class="hljs-number">2</span>;文件名:c08.asm;文件說明:用戶程序 ;創(chuàng)建日期:<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>;段重定位表項個數(shù)[<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>字節(jié)對齊) put_string: ;顯示串(<span class="hljs-number">0</span>結(jié)尾)。;輸入: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_charinc 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,almov dx,<span class="hljs-number">0x3d5</span>in al,dx ;高<span class="hljs-number">8</span>位 mov ah,almov dx,<span class="hljs-number">0x3d4</span>mov al,<span class="hljs-number">0x0f</span>out dx,almov 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>位數(shù)cmp cl,<span class="hljs-number">0x0d</span> ;回車符?jnz .put_0a ;不是。看看是不是換行等字符 mov ax,bx ;此句略顯多余,但去掉后還得改書,麻煩 mov bl,<span class="hljs-number">80</span> div blmul blmov bx,axjmp .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,axshl 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_cursormov ax,<span class="hljs-number">0xb800</span>mov ds,axmov es,axcldmov si,<span class="hljs-number">0xa0</span>mov di,<span class="hljs-number">0x00</span>mov cx,<span class="hljs-number">1920</span>rep movswmov 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> ; spaceadd bx,<span class="hljs-number">2</span>loop .clsmov 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,almov dx,<span class="hljs-number">0x3d5</span>mov al,bhout dx,almov dx,<span class="hljs-number">0x3d4</span>mov al,<span class="hljs-number">0x0f</span>out dx,almov dx,<span class="hljs-number">0x3d5</span>mov al,blout 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> axret;---------------------------------- 用戶程序入口 --------------------------------------------start:;初始執(zhí)行時,DS和ES指向用戶程序頭部段mov ax,[stack_segment] ;設(shè)置到用戶程序自己的堆棧 mov ss,axmov sp,stack_endmov ax,[data_1_segment] ;設(shè)置到用戶程序自己的數(shù)據(jù)段mov ds,axmov 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 ;轉(zhuǎn)移到代碼段<span class="hljs-number">2</span>執(zhí)行 <span class="hljs-keyword">continue</span>:mov ax,[es:data_2_segment] ;段寄存器DS切換到數(shù)據(jù)段<span class="hljs-number">2</span> mov ds,axmov bx,msg1call 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>字節(jié)對齊)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 ;轉(zhuǎn)移到代碼段<span class="hljs-number">1</span>接著執(zhí)行 ;=============================================================================== 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.制作一個空的硬盤
因為根據(jù)源碼,我們知道用戶程序在硬盤上,所以我們要制作一個硬盤鏡像文件——利用工具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個扇區(qū)(每個扇區(qū)大小是512字節(jié))
5.把用戶程序c08usr.bin寫入硬盤鏡像
dd if=c08usr.bin of=c.img bs=512 seek=100 conv=notrunk
注意:notrunc的含義是,如果目標文件(這里就是c.img)比來源文件大,不截斷目標文件多出來的那部分內(nèi)容。
比如c.img已經(jīng)有1024字節(jié)了,而c08usr.bin假設(shè)只有512字節(jié),如果seek=0,那么不加conv=notrunc,c.img就會變成512字節(jié)。
【dd命令說明】
if=輸入文件
of=輸出文件
ibs = n_bytes 一次讀取n_bytes字節(jié),即讀入緩沖區(qū)的字節(jié)數(shù)。
obs = n_bytes 一次寫入n_bytes字節(jié),即寫 入緩沖區(qū)的字節(jié)數(shù)。
bs = n_bytes 同時設(shè)置讀/寫緩沖區(qū)的字節(jié)數(shù)(等于設(shè)置ibs和obs)。
count=n_blocks:僅拷貝 n_blocks 個塊,塊大小等于 ibs 指定的字節(jié)數(shù)
conv=sync:把每個輸入記錄的大小都調(diào)到ibs的大小(不足的話用Null填充)。
skip=xxx指在備份時對if 后面的部分也就是原文件跳過多少塊再開始備份(block size由ibs指定 )
seek=xxx指在備份時對of 后面的部分也就是目標文件跳過多少塊再開始寫(block size由obs指定 )
6.啟動Bochs,查看結(jié)果
我們可以看到,應(yīng)用程序成功地被加載器加載了。
關(guān)于本文的源碼,我們下次再說明。
Goodbye
總結(jié)
以上是生活随笔為你收集整理的硬盘和显卡的访问与控制(一)——《x86汇编语言:从实模式到保护模式》读书笔记01的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汇编语言笔记14-端口
- 下一篇: 硬盘和显卡的访问与控制(二)——《x86