-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
265 lines (141 loc) · 57.1 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>漫无目的技术研究社</title>
<link href="/atom.xml" rel="self"/>
<link href="http://yoursite.com/"/>
<updated>2020-05-12T03:07:07.026Z</updated>
<id>http://yoursite.com/</id>
<author>
<name>caoxm</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>WIN32 API(1)-WinExec</title>
<link href="http://yoursite.com/2020/05/12/WIN32-API-1-WinExec/"/>
<id>http://yoursite.com/2020/05/12/WIN32-API-1-WinExec/</id>
<published>2020-05-12T03:05:47.000Z</published>
<updated>2020-05-12T03:07:07.026Z</updated>
<content type="html"><![CDATA[<h3 id="WinExec"><a href="#WinExec" class="headerlink" title="WinExec"></a>WinExec</h3><p>函数原型如下:</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">UINT <span class="title">WinExec</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params"> LPCSTR lpCmdLine,</span></span></span><br><span class="line"><span class="function"><span class="params"> UINT uCmdShow</span></span></span><br><span class="line"><span class="function"><span class="params">)</span></span>;</span><br></pre></td></tr></table></figure><p>该函数用于运行一个指定的应用程序,现在已经淘汰,仅用于保持对16位Windows操作系统的兼容,可以使用函数 <code>CreateProcess</code> 来代替。</p><h6 id="参数说明:"><a href="#参数说明:" class="headerlink" title="参数说明:"></a>参数说明:</h6><p><code>lpCmdLine</code> :运行程序所需的命令行参数(文件名+可选参数),若该参数中没有包含可执行文件的路径,将会自动按照下面顺序搜索可执行文件:</p><ol><li>应用程序被加载的目录</li><li>当前目录</li><li>Windows系统目录,该目录可以通过 <code>GetSystemDirectory</code> 函数获得</li><li>Windows目录,该目录可以通过 <code>GetWindowsDirectory</code> 函数获得</li><li>PATH环境变量中指定的目录</li></ol><p><code>uCmdShow</code>:显示方式,可以接受一系列预定义的值(SW宏),改参数和 <code>ShowWindow</code> 函数的 <code>nCmdShow</code> 参数含义一致。</p><h6 id="返回值说明:"><a href="#返回值说明:" class="headerlink" title="返回值说明:"></a>返回值说明:</h6><p>该函数如果成功运行,返回值大于31</p><p>该函数如果执行失败,返回值是下面错误值中的一个:</p><table><thead><tr><th>返回值</th><th>说明</th></tr></thead><tbody><tr><td><strong>0</strong></td><td>系统资源或者内存已用完</td></tr><tr><td><strong>ERROR_BAD_FORMAT</strong></td><td>无效的可执行文件</td></tr><tr><td><strong>ERROR_FILE_NOT_FOUND</strong></td><td>找不到指定的文件</td></tr><tr><td><strong>ERROR_PATH_NOT_FOUND</strong></td><td>找不到指定的路径</td></tr></tbody></table><h6 id="注意事项:"><a href="#注意事项:" class="headerlink" title="注意事项:"></a>注意事项:</h6><p>该函数会在被运行的程序执行 <code>GetMessage</code> 函数时返回,否则会一直等待直到超时。</p><p>不当地使用该函数可能会导致安全问题,因为该函数总是将第一个空白字符分隔的字符串当成可执行文件名,因此如果可执行文件路径包含空格就会导致错误:</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">WinExec(<span class="string">"C:\\Program Files\\MyApp"</span>, ...);</span><br></pre></td></tr></table></figure><p>此时会运行应用程序 Program.exe,而不是 MyApp.exe。如果别用用心的人在系统目录下创建了 Program.exe,则所有像上面那样错误使用了该函数的应用程序都会运行 Program.exe。</p><p>可以使用 <code>CreateProcess</code> 来避免这个错误,也可以给包含空格的路径添加引号:</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">WinExec(<span class="string">"\"C:\\Program Files\\MyApp.exe\" -L -S"</span>, ...)</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h3 id="WinExec"><a href="#WinExec" class="headerlink" title="WinExec"></a>WinExec</h3><p>函数原型如下:</p>
<figure class="highlight cpp"><table><
</summary>
<category term="Windows API" scheme="http://yoursite.com/categories/Windows-API/"/>
</entry>
<entry>
<title>进位标志和溢出标志的含义和理解</title>
<link href="http://yoursite.com/2020/05/04/%E8%BF%9B%E4%BD%8D%E6%A0%87%E5%BF%97%E5%92%8C%E6%BA%A2%E5%87%BA%E6%A0%87%E5%BF%97%E7%9A%84%E5%90%AB%E4%B9%89%E5%92%8C%E7%90%86%E8%A7%A3/"/>
<id>http://yoursite.com/2020/05/04/%E8%BF%9B%E4%BD%8D%E6%A0%87%E5%BF%97%E5%92%8C%E6%BA%A2%E5%87%BA%E6%A0%87%E5%BF%97%E7%9A%84%E5%90%AB%E4%B9%89%E5%92%8C%E7%90%86%E8%A7%A3/</id>
<published>2020-05-03T16:42:49.000Z</published>
<updated>2020-05-03T16:51:50.548Z</updated>
<content type="html"><![CDATA[<p>这次大概总结一下<strong>进位标志(Carry Flag, CF)</strong>和<strong>溢出标志(Overflow Flag, OF)</strong>的含义和理解方式</p><p><strong>首先明确一点基本认识,处理器本身并不在意也不知道参与算术运算或者逻辑运算的操作数是有符号的还是无符号的。</strong>ALU总是为给定的操作数做二进制运算,并根据结果设置相应的标志位。</p><p>因此,视参与运算的整数的实际情况,CF或者OF会被独立的置位或者清零。他们的含义是有程序设计者赋予的,在进行无符号运算时,我们需要检查CF来确定运算结果是否正确,而在进行有符号运算时,则通过检查OF来判断结果是否发生溢出。</p><a id="more"></a><h3 id="1-Carry-Flag"><a href="#1-Carry-Flag" class="headerlink" title="1. Carry Flag"></a>1. Carry Flag</h3><p><code>CF</code> 会在两种情况下变成1:</p><ol><li><strong>运算结果的最高有效位向更高位进位</strong></li><li><strong>运算结果的最高有效位从更高位借位</strong></li></ol><p>只要在这两种情况以外,<code>CF</code> 总是0。</p><h3 id="2-Overflow-Flag"><a href="#2-Overflow-Flag" class="headerlink" title="2. Overflow Flag"></a>2. Overflow Flag</h3><p><code>OF</code> 会在下面两种情形变为1:</p><ol><li><strong>两个最高有效位均为0的数相加,得到的结果最高有效位为1</strong></li><li><strong>两个最高有效位均为1的数相加,得到的结果最高有效位为0</strong></li></ol><p>除了这两种情况以外,<code>OF</code> 为0。</p><p>使用补码表示有符号数时,最高有效位为0表示正数,最高有效位为1表示负数。因此上面的论述也可以表示为,<strong>两个正数相加得到负数,或者两个负数相加得到正数</strong>时 <code>OF</code> 置位,否则复位。</p><p>对于减法来说也是一样的,<strong>正数减去负数得到负数,或者负数减去正数得到正数</strong>则 <code>OF</code> 置位,否则均复位。</p><p>有符号数溢出总是发生在 <code>0x7f-0x80</code> 这个位置,也就是符号改变的时候。异号的两个数字求和结果位于他们之间,只要操作数本身没有溢出那么结果肯定就不会溢出,因此正数和负数相加不可能导致 <code>OF</code> 置位。</p><p>此外,<code>OF</code> 还有另一种理解方式,当次高位向最高有效位的进位值和最高有效位的溢出值不同的时候,<code>OF</code> 为1,否则为0。显然这个规律可以通过亦或运算来表示:$OF=Carray_In \bigoplus Carry_Out $ 。</p>]]></content>
<summary type="html">
<p>这次大概总结一下<strong>进位标志(Carry Flag, CF)</strong>和<strong>溢出标志(Overflow Flag, OF)</strong>的含义和理解方式</p>
<p><strong>首先明确一点基本认识,处理器本身并不在意也不知道参与算术运算或者逻辑运算的操作数是有符号的还是无符号的。</strong>ALU总是为给定的操作数做二进制运算,并根据结果设置相应的标志位。</p>
<p>因此,视参与运算的整数的实际情况,CF或者OF会被独立的置位或者清零。他们的含义是有程序设计者赋予的,在进行无符号运算时,我们需要检查CF来确定运算结果是否正确,而在进行有符号运算时,则通过检查OF来判断结果是否发生溢出。</p>
</summary>
<category term="Assembly" scheme="http://yoursite.com/categories/Assembly/"/>
</entry>
<entry>
<title>通过虚拟机实现裸机汇编环境</title>
<link href="http://yoursite.com/2020/05/01/%E9%80%9A%E8%BF%87%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%AE%9E%E7%8E%B0%E8%A3%B8%E6%9C%BA%E6%B1%87%E7%BC%96%E7%8E%AF%E5%A2%83/"/>
<id>http://yoursite.com/2020/05/01/%E9%80%9A%E8%BF%87%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%AE%9E%E7%8E%B0%E8%A3%B8%E6%9C%BA%E6%B1%87%E7%BC%96%E7%8E%AF%E5%A2%83/</id>
<published>2020-05-01T06:05:27.000Z</published>
<updated>2020-05-01T06:23:34.501Z</updated>
<content type="html"><![CDATA[<h2 id="1-简述"><a href="#1-简述" class="headerlink" title="1. 简述"></a>1. 简述</h2><p>操作系统带来便利的同时也引入了大量限制,在操作系统存在时,我们编写的程序不能直接被硬件加载。我们必须按照操作系统的约定,把程序编译成特定的可执行文件格式(比如<code>Windows</code>的<code>PE</code>文件格式,<code>Linux</code>的<code>ELF</code>文件格式)。执行程序时,由操作系统读取可执行文件,选择合适的内存空间,并将代码和数据加载到内存中相应位置,这样程序才能被处理器所执行,在程序执行过程中遇到诸如I/O之类的操作,还必须进行系统调用,由操作系统完成这些操作。为了了解底层工作原理,尝试跨过操作系统直接运行程序,控制硬件,使用虚拟机是最方便的选择。</p><h2 id="2-Oracle-VM-VirtualBox"><a href="#2-Oracle-VM-VirtualBox" class="headerlink" title="2. Oracle VM VirtualBox"></a>2. Oracle VM VirtualBox</h2><ol><li>首先是下载和安装软件,VirtualBox 免费使用,没什么可说的</li><li>创建虚拟机</li></ol><p>要注意两点,第一个是不要安装任何操作系统(裸机试验环境嘛,肯定是不想要操作系统的)</p><p><img src="1588304847120.png" alt="1588304847120"></p><p>另一方面是创建虚拟硬盘,为了方便我们选择固定大小的VHD格式的虚拟硬盘,此时虚拟硬盘就是一个结构很简单的二进制文件,前面是数据区,结尾是一个512字节的信息区。</p><p>因为只是做简单的汇编实验,硬盘大小有30M左右就足够了,这个根据实际需求来选择。</p><ol><li><p>修改启动顺序,因为我们想把程序写入VHD虚拟硬盘的启动扇区里直接开机运行,因此要把从硬盘启动排在最前面。</p><p><img src="1588305142600.png" alt="1588305142600"></p></li></ol><h2 id="3-bochs"><a href="#3-bochs" class="headerlink" title="3. bochs"></a>3. bochs</h2><p>其实只要 VirtualBox 已经足够了,但是如果想要更方便地调试程序,检测程序执行过程中的寄存器和内存变化,bochs 是一个很优秀的选择。</p><ol><li>下载安装仍然很简单,bochs是开源免费的软件,直接装就可以了,如果使用linux,大多数发型版都可以直接从源内获取相应的二进制包。</li><li>设置虚拟机,和上面处理 VirtualBox 类似,重点还是设置硬盘和启动顺序,不过此处我们不必重新创建虚拟硬盘,直接使用上一步 VirtualBox 创建好的那个就行。配置方法可以使用图形界面编辑,也可以直接通过文本编辑器修改配置文件。需要修改的地方如下图:</li></ol><p><img src="1588306151505.png" alt="1588306151505"></p><p><img src="1588306182981.png" alt="1588306182981"></p><p>设置好之后,别忘了保存为配置文件,以后每次打开虚拟机的时候就可以直接载入相应配置文件来启用这个配置,不用每次都改。</p><p>至于编辑配置文件的方法这里就不介绍了,放上有很多介绍配置文件含义的资料,具体参考那些东西就好。</p><h2 id="4-编写代码"><a href="#4-编写代码" class="headerlink" title="4. 编写代码"></a>4. 编写代码</h2><p>终于回到正题了,不过这篇文章并不是介绍汇编语言的(hhhhh)。对与20位地址总线来说,形成虚拟地址空间 <code>0x00000-0xFFFFF</code> ,ROM,主存,其他I/O设备的主存(比如显卡的显存)都被编入这段地址空间中,其中显存的地址范围是从 <code>0xB8000-BFFFF</code> ,我们向这一段地址空间中写入数据就可以操作显卡显示相应的内容。</p><p>显卡有彩色模式和文本模式,对于彩色模式来说每个像素对应显存中的一段内存区域(比如三个字节表示一个像素,他们分别代表RGB分量,这就是真彩色模式)。而对于文本来说我们用不着关心像素,只需要考虑待写入字符的ASCII编码就可以。<strong>每两个字节表示屏幕上的一个字符,第一个字节放字符编码,第二个字符控制显示模式</strong>,从屏幕第一字符开始,它对应显存前两个字节,第二个字符对应第三和第四个字节,以此类推。</p><p><img src="1588310553100.gif" alt="1588310553100"></p><p>现在我们要做的就是直接通过汇编语言来向显存中写入数据。为了实现内存寻址,我们首先要划定段地址,因为显存起始地址是 <code>0xB800</code> 最简单就是令段寄存器 <code>ES=0xB800</code> ,当然用其他的段寄存器,采用其他的段地址也可以。代码如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">mov ax, 0xB800</span><br><span class="line">mov es, ax ; mov指令不允许移动立即数到段寄存器,必须这样迂回一下</span><br><span class="line">mov byte [es:0x00], 0x48</span><br><span class="line">mov byte [es:0x01], 0x07</span><br><span class="line">mov byte [es:0x02], 0x65</span><br><span class="line">mov byte [es:0x03], 0x07</span><br><span class="line">mov byte [es:0x04], 0x6c</span><br><span class="line">mov byte [es:0x05], 0x07</span><br><span class="line">mov byte [es:0x06], 0x6c</span><br><span class="line">mov byte [es:0x07], 0x07</span><br><span class="line">mov byte [es:0x08], 0x6f</span><br><span class="line">mov byte [es:0x09], 0x07</span><br><span class="line">mov byte [es:0x0A], 0x2c ; ,</span><br><span class="line">mov byte [es:0x0B], 0x07</span><br><span class="line">mov byte [es:0x0C], 0x57 ; W</span><br><span class="line">mov byte [es:0x0D], 0x07</span><br><span class="line">mov byte [es:0x0E], 0x6f</span><br><span class="line">mov byte [es:0x0F], 0x07</span><br><span class="line">mov byte [es:0x10], 0x72 ; r</span><br><span class="line">mov byte [es:0x11], 0x07</span><br><span class="line">mov byte [es:0x12], 0x6c</span><br><span class="line">mov byte [es:0x13], 0x07</span><br><span class="line">mov byte [es:0x14], 0x64</span><br><span class="line">mov byte [es:0x15], 0x07</span><br><span class="line">mov byte [es:0x16], 0x21 ; !</span><br><span class="line">mov byte [es:0x17], 0x07</span><br><span class="line"></span><br><span class="line">jmp $ ; 开始死循环,这个必须有,否则在bochs里面不能打印出来字符串,原因我也没弄明白</span><br><span class="line"></span><br><span class="line">times 510-($-$$) db 0 ; 用于填充的无意义字节</span><br><span class="line"></span><br><span class="line">db 0x55 ; 扇区结束标志</span><br><span class="line">db 0xaa</span><br></pre></td></tr></table></figure><p>我们想把这些代码写入引导扇区里面执行,而一个可以引导的扇区必须以 <code>0x55aa</code> 结束,且扇区大小是512字节(这个是在硬盘设置中定下来的)。</p><h2 id="5-将代码写入扇区"><a href="#5-将代码写入扇区" class="headerlink" title="5. 将代码写入扇区"></a>5. 将代码写入扇区</h2><p>汇编代码的编译通过nasm来完成,该软件是免费的,可以很容易的下载并安装,注意安装好之后配置 <code>path</code> 环境变量到可执行文件目录。</p><p>首先是编译代码,我们不希望生成操作系统下的可执行文件,因此要注意可执行文件的目标格式:</p><p><code>nasm -f bin hello.asm -o hello.bin</code></p><p>然后把二进制文件写入VHD虚拟硬盘的引导扇区,VHD的扇区写入工具有很多,随便找一个就可以。需要注意的是CHS和LBA编号之间的区别:</p><p><code>LBA = C*磁头数*扇区数 + H*扇区数 +(S-1)</code></p><p>对于引导扇区来说,就是LBA编号为1的扇区。</p><h2 id="6-运行"><a href="#6-运行" class="headerlink" title="6. 运行"></a>6. 运行</h2><p>对于<strong>VirtualBox</strong>来说很简单,直接点击启动虚拟机就能看到运行结果:</p><p><img src="1588311593959.png" alt="1588311593959"></p><p>对于<strong>Bochs</strong>来说稍微麻烦一些,上电复位字后,代码段寄存器和指令指针为 <code>CS:IP=0xFFFF:0x0000</code> ,处理器会停在这个位置,而该位置正好输入ROM。通常来说在 <code>0xFFFF0</code> 这个位置存放的是一个跳转指令 <code>jmp 0xF000:0xE05B</code> ,跳转过去之后还有很多ROM代码需要执行,他们负责完成上电自检,查找启动扇区这样的工作,我们不关心这一部分直接跳过去就好。在跳过去之前我们应该先在 <code>0x7C00</code> 这个位置下个断点,因为ROM总是会把启动扇区的代码加载在这个位置,也就是说从 <code>0x7C00</code> 开始就是我们自己编写的代码了。</p><p><img src="1588312328211.png" alt="1588312328211"></p><p>执行之后结果很长,这里只截取最后一部分:</p><p><img src="1588312379368.png" alt="1588312379368"></p><p>可以看到,这就是自己编写的第一条汇编指令,考虑到后面有死循环,这里直接执行就好,最终结果如图:</p><p><img src="1588312449283.png" alt="1588312449283"></p><p>内容到这里就完全结束了~</p>]]></content>
<summary type="html">
<h2 id="1-简述"><a href="#1-简述" class="headerlink" title="1. 简述"></a>1. 简述</h2><p>操作系统带来便利的同时也引入了大量限制,在操作系统存在时,我们编写的程序不能直接被硬件加载。我们必须按照操作系统的约定,
</summary>
<category term="Assembly" scheme="http://yoursite.com/categories/Assembly/"/>
</entry>
<entry>
<title>Intel X86 的内存寻址模式</title>
<link href="http://yoursite.com/2020/04/30/Intel-X86-%E7%9A%84%E5%86%85%E5%AD%98%E5%AF%BB%E5%9D%80%E6%A8%A1%E5%BC%8F/"/>
<id>http://yoursite.com/2020/04/30/Intel-X86-%E7%9A%84%E5%86%85%E5%AD%98%E5%AF%BB%E5%9D%80%E6%A8%A1%E5%BC%8F/</id>
<published>2020-04-30T04:47:53.000Z</published>
<updated>2020-04-30T04:48:58.806Z</updated>
<content type="html"><![CDATA[<h4 id="1-直接寻址(Direct-memory-addressing-mode)"><a href="#1-直接寻址(Direct-memory-addressing-mode)" class="headerlink" title="1. 直接寻址(Direct memory addressing mode)"></a>1. 直接寻址(<strong>Direct memory addressing mode</strong>)</h4><p>通过立即数直接指定偏移地址,段地址隐含在指令中,当然也可以人为指定段寄存器。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">MOV EAX, [0X8FFCBC]</span><br><span class="line">MOV EAX, DWORD PTR DS:[0X8FFCBC]</span><br></pre></td></tr></table></figure><h4 id="2-寄存器间接寻址(Register-based-indirect-addressing-mode)"><a href="#2-寄存器间接寻址(Register-based-indirect-addressing-mode)" class="headerlink" title="2. 寄存器间接寻址(Register based indirect addressing mode)"></a>2. 寄存器间接寻址(Register based indirect addressing mode)</h4><p>偏移地址通过寄存器给出,默认的段寄存器跟使用的基址寄存器有关,如果用了ESP,EBP则默认堆栈段SS,否则默认为数据段DS,这些都可以自行更改。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">MOV EAX, [EBX]</span><br><span class="line">MOV EAX, DWORD PTR DS:[EBX]</span><br><span class="line">MOV EAX, DWORD PTR SS:[ESP]</span><br><span class="line">MOV EAX, DWORD PTR DS:[ESP]</span><br></pre></td></tr></table></figure><h4 id="3-寄存器相对寻址(Register-relative-addressing-mode)"><a href="#3-寄存器相对寻址(Register-relative-addressing-mode)" class="headerlink" title="3. 寄存器相对寻址(Register relative addressing mode)"></a>3. 寄存器相对寻址(<strong>Register relative addressing mode</strong>)</h4><p>相对的意思以寄存器为基址,通过立即数指定相对基址的偏移量,二者共同构成相对段地址的偏移地址</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">MOV EAX, [EBX+0X00101010]</span><br><span class="line">MOV EAX, DWORD PTR DS:[EBX+0X00101010]</span><br><span class="line">MOV EAX, DWORD PTR ES:[EDX+0X00101010]</span><br><span class="line">MOV EAX, DWORD PTR SS:[EAX+0X10123478]</span><br><span class="line">MOV EAX, DWORD PTR FS:[ESI+0X1FF010]</span><br></pre></td></tr></table></figure><h4 id="4-基址-变址寻址(Base-indexed-addressing-mode)"><a href="#4-基址-变址寻址(Base-indexed-addressing-mode)" class="headerlink" title="4. 基址-变址寻址(Base indexed addressing mode)"></a>4. <strong>基址-变址寻址(Base indexed addressing mode)</strong></h4><p>通过一个<strong>基址寄存器</strong>加一个<strong>索引寄存器(也叫变址寄存器)的(1, 2, 4, 8)倍</strong>来构成相对段地址的偏移地址</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">MOV EAX, [EBX+ESI]</span><br><span class="line">MOV EAX, DWORD PTR DS:[EBX+ESI]</span><br><span class="line">MOV EAX, [EBX+ESI*8]</span><br><span class="line">MOV EAX, [EBX*4+EAX]</span><br><span class="line">MOV EAX, [ESI*2+EDI]</span><br></pre></td></tr></table></figure><h4 id="5-相对基址-变址寻址(Relative-based-indexed-addressing-mode)"><a href="#5-相对基址-变址寻址(Relative-based-indexed-addressing-mode)" class="headerlink" title="5. 相对基址-变址寻址(Relative based indexed addressing mode)"></a>5. 相对基址-变址寻址(<strong>Relative based indexed addressing mode</strong>)</h4><p>组合上面所说的相对寻址和索引寻址,即偏移地址由基址寄存器,变址寄存器(1, 2, 4, 8)倍,位移立即数相加而成</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">MOV EAX, [EBX+ESI+0X008CEECF]</span><br><span class="line">MOV EAX, DWORD PTR DS:[EBX+ESI+0X008CEECF]</span><br><span class="line">MOV EAX, [EBX+ESI*4+0X008CEECF]</span><br><span class="line">MOV EAX, [EAX*2+ESI+0X8CEEFE]</span><br><span class="line">MOV EAX, [EBP*8+EDI+0X8BACFF]</span><br></pre></td></tr></table></figure><p>因为任何一个通用寄存器都可以拿来做变址寄存器,所以上面哪一个寄存器乘系数是无所谓的,关键是只能有一个寄存器带有系数。</p>]]></content>
<summary type="html">
<h4 id="1-直接寻址(Direct-memory-addressing-mode)"><a href="#1-直接寻址(Direct-memory-addressing-mode)" class="headerlink" title="1. 直接寻址(Direct mem
</summary>
<category term="Assembly" scheme="http://yoursite.com/categories/Assembly/"/>
</entry>
<entry>
<title>Python虚拟环境</title>
<link href="http://yoursite.com/2018/03/17/Python%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83/"/>
<id>http://yoursite.com/2018/03/17/Python%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83/</id>
<published>2018-03-17T03:05:17.000Z</published>
<updated>2020-04-28T16:00:14.716Z</updated>
<content type="html"><![CDATA[<h1 id="用virtualenv创建Python虚拟环境"><a href="#用virtualenv创建Python虚拟环境" class="headerlink" title="用virtualenv创建Python虚拟环境"></a>用virtualenv创建Python虚拟环境</h1><p>虚拟环境的意义是</p><h2 id="1-安装virtualenv"><a href="#1-安装virtualenv" class="headerlink" title="1.安装virtualenv"></a>1.安装virtualenv</h2><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 注意pip所属的Python环境,之后利用的virtualenv创建的Python环境与当前版本一致</span></span><br><span class="line">pip <span class="keyword">install</span> virtualenv</span><br></pre></td></tr></table></figure><h2 id="2-创建虚拟环境"><a href="#2-创建虚拟环境" class="headerlink" title="2.创建虚拟环境"></a>2.创建虚拟环境</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mkdir envName <span class="comment">#创建保存虚拟环境的文件夹</span></span><br><span class="line"><span class="built_in">cd</span> envName</span><br><span class="line">virtualenv flask_env <span class="comment"># 在刚才创建的文件夹中创建虚拟环境(该过程要联网)</span></span><br></pre></td></tr></table></figure><h2 id="3-使用虚拟环境"><a href="#3-使用虚拟环境" class="headerlink" title="3.使用虚拟环境"></a>3.使用虚拟环境</h2><figure class="highlight taggerscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd .<span class="symbol">\e</span>nvName<span class="symbol">\f</span>lask_env</span><br><span class="line">activate</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="用virtualenv创建Python虚拟环境"><a href="#用virtualenv创建Python虚拟环境" class="headerlink" title="用virtualenv创建Python虚拟环境"></a>用virtualenv创建Pyth
</summary>
<category term="Python" scheme="http://yoursite.com/categories/Python/"/>
</entry>
<entry>
<title>翻译Python文档(2)--数据模型(2)</title>
<link href="http://yoursite.com/2018/03/04/%E7%BF%BB%E8%AF%91Python%E6%96%87%E6%A1%A3%EF%BC%882%EF%BC%89-%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B%EF%BC%882%EF%BC%89/"/>
<id>http://yoursite.com/2018/03/04/%E7%BF%BB%E8%AF%91Python%E6%96%87%E6%A1%A3%EF%BC%882%EF%BC%89-%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B%EF%BC%882%EF%BC%89/</id>
<published>2018-03-04T15:04:40.000Z</published>
<updated>2020-04-28T16:01:35.522Z</updated>
<content type="html"><![CDATA[<h2 id="3-2-标准类型层次"><a href="#3-2-标准类型层次" class="headerlink" title="3.2. 标准类型层次"></a>3.2. 标准类型层次</h2><p>  下面是内置到Python中的类型的列表。扩展模块(用C,Java,或者是其他语言编写,依赖于实现)可以定义额外的类型。以后的Python版本或许会添加新的类型(例如,合理的数值,有效存储的整数数组,等等),尽管这些类型总是会通过标准库额外提供。<br>下面的某些类型描述中包含了列出‘特殊属性’的段落。这是些提供了对实现进行访问的属性,而非用于通常用途。他们的定义在未来可能会改变。</p><hr><p><strong>None</strong>:</p><p>  该类型具有单一值。对应该值仅有一个对象。这个对象可以通过内置名字<code>None</code>来访问。在很多情况中,这被用来表达值不存在。比如,被没有指定返回值的函数返回。它的逻辑值是False。<br><strong>NotImplemented</strong>:</p><p>  该类型具有单一值。对应该值仅有一个对象。这个对象可以通过内置名字<code>NotImplemented</code>来访问。数值方法和富比较方法应当在未能对提供的操作数执行操作返回这个值。该逻辑值是True。(注:方法对不能正常操作的参数返回NotImplemented,已提示解释器寻找其他的方法来完成该操作,而不是抛出异常。NotImplemented   对象向运行时环境发出一个信号,告诉运行环境如果当前操作失败,它应该再检查一下其他可行方法。例如在 a == b 表达式,如果 a.__eq__(b) 返回 NotImplemented,那么 Python 会尝试 b.__eq__(a)。如果调用 b 的 __eq__() 方法可以返回 True 或者 False,那么该表达式就成功了。如果 b.__eq__(a) 也不能得出结果,那么 Python 会继续尝试其他方法,例如使用 != 来比较。)<br><strong>Ellipsis</strong>:</p><p>  该类型具有单一值。对应该值仅有一个对象。该对象通过字面值<code>...</code>或者内置名字<code>Ellipsis</code>来访问。它的逻辑值时True。(注:Ellipsis主要用于省略,可以用来替代pass语句在函数中占位,也经常出现在输出结果中表达省略或者优化显示效果??)</p><p><strong>numbers.Number</strong>:<br>  数值类型的对象可以由数值字面值来创建,也可以作为算数运算符或者是内置算数函数的结果返回。数值对象是不可变的;他们的值一旦被创建就不能再改变。Python的数值类型与数学中的数值是很相似的,但是尽管如此也同样受限于数值在计算机中的表示方法。<br>  Python区分整数,浮点数和复数类型:</p><ul><li><strong>numbers.Integral</strong><br>  这些对象代表数学中整数集中的元素(正数或者负数)。<br>  整数类型中又分为更具体的两种类型:<ul><li>Integers(int)<br>  他们代表无限范围内的数值,仅仅受到内存(虚拟的)的限制。为了移位和掩码操作,需要采用二进制表示,负数被通过二进制补码的变体表示,这种表示的符号位是向左延伸的无限长字符串。</li><li>Booleans (bool)<br>  这些对象代表了逻辑值False和True。这两种对象是仅有的布尔型对象。Boolean类型是整数类型的子类型,布尔数值表现起来像0和1,特殊之处在于当把布尔类型转换为字符串的时候,会返回”False”和”True”。<br>  整数类型的规定意在给包括负数在内的整数做移位和掩码操作时给出最具有意义的解释。</li></ul></li><li><strong>numbers.Real(float)</strong><br>  表示机器层面的双精度浮点数。你在底层机器架构(以及C和Java实现)对范围和溢出处理方式面前束手无策。Python不支持单精度浮点数类型;在使用Python对象面前,因为处理器和内存使用这样的原因使用单精度显得爱笑,所以没有理由在同一种语言中实现两种浮点数类型。</li><li><strong>numbers.Complex(complex)</strong>:<br>  通过机器层面的一对双进度浮点数表示负数。复数z的实部和虚部可以通过只读属性z.real和z.imag来访问。</li></ul>]]></content>
<summary type="html">
<h2 id="3-2-标准类型层次"><a href="#3-2-标准类型层次" class="headerlink" title="3.2. 标准类型层次"></a>3.2. 标准类型层次</h2><p>&emsp;&emsp;下面是内置到Python中的类型的列表。扩展模块
</summary>
<category term="Python" scheme="http://yoursite.com/categories/Python/"/>
</entry>
<entry>
<title>Anaconda 环境中安装openCV</title>
<link href="http://yoursite.com/2018/03/04/Anaconda-%E7%8E%AF%E5%A2%83%E4%B8%AD%E5%AE%89%E8%A3%85openCV/"/>
<id>http://yoursite.com/2018/03/04/Anaconda-%E7%8E%AF%E5%A2%83%E4%B8%AD%E5%AE%89%E8%A3%85openCV/</id>
<published>2018-03-04T02:25:52.000Z</published>
<updated>2020-04-28T15:59:40.916Z</updated>
<content type="html"><![CDATA[<ul><li>Python3.x自带pip,直接按下面的命令安装即可。</li><li><p>多Python版本共存时注意确认使用的哪个环境中的Python!</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pip <span class="keyword">install</span> opencv-python</span><br><span class="line">pip <span class="keyword">install</span> opencv-contrib-python</span><br></pre></td></tr></table></figure></li><li><p>Anaconda安装环境中默认没有安装Python3.dll,这会导致cv2的导入失败,要解决该问题,去官网下载Python相应版本的zip包,自行拷贝其中的Python3.dll到Anaconda根目录即可。</p></li><li>验证<figure class="highlight haskell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># python</span></span><br><span class="line">>>><span class="keyword">import</span> cv2 <span class="keyword">as</span> cv</span><br></pre></td></tr></table></figure></li></ul>]]></content>
<summary type="html">
<ul>
<li>Python3.x自带pip,直接按下面的命令安装即可。</li>
<li><p>多Python版本共存时注意确认使用的哪个环境中的Python!</p>
<figure class="highlight cmake"><table><tr><td class=
</summary>
<category term="Python" scheme="http://yoursite.com/categories/Python/"/>
</entry>
<entry>
<title>翻译Python文档(1)--数据模型(1)</title>
<link href="http://yoursite.com/2018/03/02/%E7%BF%BB%E8%AF%91Python%E6%96%87%E6%A1%A3%EF%BC%881%EF%BC%89-%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B%EF%BC%881%EF%BC%89/"/>
<id>http://yoursite.com/2018/03/02/%E7%BF%BB%E8%AF%91Python%E6%96%87%E6%A1%A3%EF%BC%881%EF%BC%89-%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B%EF%BC%881%EF%BC%89/</id>
<published>2018-03-02T04:02:33.000Z</published>
<updated>2020-04-28T16:01:17.886Z</updated>
<content type="html"><![CDATA[<h1 id="翻译Python-language-reference-1-—3-数据模型"><a href="#翻译Python-language-reference-1-—3-数据模型" class="headerlink" title="翻译Python language reference(1)—3.数据模型"></a>翻译Python language reference(1)—3.数据模型</h1><h2 id="3-1-对象,值,和类型"><a href="#3-1-对象,值,和类型" class="headerlink" title="3.1 对象,值,和类型"></a>3.1 对象,值,和类型</h2><p>  对象是python对数据的抽象,python程序中的一切数据均由对象和对象之间的关系来表示(在某种意义上,这与Von Neumann的“存储程序的计算机”模型一致,代码也被表示为对象。)。<br>每一个对象都具有一个标识,一个类型和一个数值。自创建起,对象的id不会改变,你可以把他理解成对象在内存的地址。<code>is</code>运算符比较两个对象的身份标识; <code>id()</code> 函数返回一个代表id的整数。<br>  <strong>CPython实现细节</strong>:对于CPython来说,<code>id(x)</code>返回存储x的内存地址。<br>  一个对象的类型决定了对象所支持的操作,也定义了对象可能的取值。<code>type()</code>函数返回对象的类型(返回值自身也是对象)。如同对象的id,对象的类型也是不能改变的。【1】<br>  某些对象的值可以改变,数值可以改变的对象被称为mutable;创建后取值不可变的对象被称为immutable。(一个引用到可变对象的不可变容器对象的值在后者的值改变时可以被改变,尽管如此,容器依然被认为是不可变的,因为他引用到的对象不能改变,所以,immutability和值不变是两个不完全相同的概念,后者更顽固。)一个对象的可变性由对象的类型决定;例如,数值,字符串,元组是不可变类型,而字典和列表是可变类型。<br>  对象永远不能被明确指定销毁;然而,当他们变得不可访问时会被GC回收。一种实现允许你延迟垃圾回收或者忽略他-这是垃圾回收的实现质量的问题–有一定是确定的,没有对象会在可以被访问的时候被回收。<br>  <strong>CPython实现细节</strong>:CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage(CPython目前使用引用计数的方式对循环引用的垃圾做延迟检测), which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references.(他会在对象变得不可用时搜集其中的大多数,但是不保证收集包含循环引用的垃圾) See the documentation of the gc module for information on controlling the collection of cyclic garbage. (参考gc模块的文档来获取关于循环垃圾回收控制的实现细节)Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become unreachable (so you should always close files explicitly).<br>  注意到使用追踪或者调试工具可以保持对象生存,同时注意通过<code>try...except</code>语句捕获异常可以达到同样的效果。<br>  一些对象包含了对外部资源的引用,比如打开文件或窗体。很明显这些资源在垃圾回收时会被释放。考虑到gc并不能保证会发生,这类对象提供了明确的方法来释放外部资源,通常是<code>close()</code>方法,强烈建议程序明确的关闭此类对象,语句<code>try...finally</code>和<code>with</code>为完成这样的工作提供了合适的途径。<br>一些对象包含了对其他对象的引用;这些对象叫做容器例如元组,列表和字典。引用仅仅是容器取值的一部分,在大多数情况下,当我们谈及容器的值时,我们指的是取值而不仅是所包含对象的身份标识;然而当我们讨论容器的可变性的时候,指的仅仅是容器包含的对象的身份。因此,如果一个不可变容器包含了对可变对象的引用,他的取值会随着可变对象的改变而改变。<br>  类型影响着对象行为的方方面面。在某种意义上,甚至于id的重要性也受到影响:对于不可变类型,计算新值的操作会返回对相同类型和数值的已存在对象的引用,然而对可变对象这是不允许的。E.g.,在<code>a=1;b=1</code>之后,a和b是否引用到相同对象(数值1)引来于实现机制,而在执行<code>c=[];d=[]</code>之后,c和d确定会引用到两个不同的,独立的,新的空列表。(注意这与<code>c=d=[]</code>的复制操作不同)。</p>]]></content>
<summary type="html">
<h1 id="翻译Python-language-reference-1-—3-数据模型"><a href="#翻译Python-language-reference-1-—3-数据模型" class="headerlink" title="翻译Python language
</summary>
<category term="Python" scheme="http://yoursite.com/categories/Python/"/>
</entry>
<entry>
<title>Spigot插件学习(1)---使用maven构建项目</title>
<link href="http://yoursite.com/2018/03/01/Spigot%E6%8F%92%E4%BB%B6%E5%AD%A6%E4%B9%A0-1-%E4%BD%BF%E7%94%A8maven%E6%9E%84%E5%BB%BA%E9%A1%B9%E7%9B%AE/"/>
<id>http://yoursite.com/2018/03/01/Spigot%E6%8F%92%E4%BB%B6%E5%AD%A6%E4%B9%A0-1-%E4%BD%BF%E7%94%A8maven%E6%9E%84%E5%BB%BA%E9%A1%B9%E7%9B%AE/</id>
<published>2018-03-01T03:35:03.000Z</published>
<updated>2020-04-28T16:00:45.223Z</updated>
<content type="html"><![CDATA[<h1 id="一-安装Maven"><a href="#一-安装Maven" class="headerlink" title="一. 安装Maven"></a>一. 安装Maven</h1><ol><li>不多说,去apache下载安装即可</li><li>配置环境变量:MAVEN_HOME=maven根目录 path+=%MAVEN_HOME%\bin</li><li>检验安装是否成功: mvn -v</li></ol><h1 id="二-命令行新建项目"><a href="#二-命令行新建项目" class="headerlink" title="二. 命令行新建项目"></a>二. 命令行新建项目</h1><ol><li><p>新建maven项目,第一次执行会下载很多文件,速度会很慢,修改为国内镜像源后人生会变得很美好,修改方法:</p><pre><code>编辑配置文件:%MAVEN_HOME%\conf\settings.xml找到mirror标签修改为:</code></pre></li></ol><img src="/2018/03/01/Spigot插件学习-1-使用maven构建项目/1.jpg" title="settings.xml"><pre><code>然后创建项目:</code></pre><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">> mvn archetype:generate <span class="attribute">-DgroupId</span>=io.github.caoxm <span class="attribute">-DartifactId</span>=TutorialPlugin <span class="attribute">-DarchetypeArtifactId</span>=maven-archetype-quickstart</span><br></pre></td></tr></table></figure><ol><li><p>修改pom.xml,添加依赖等标签,添加后如下:</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"> <span class="tag"><<span class="name">project</span> <span class="attr">xmlns</span>=<span class="string">"http://maven.apache.org/POM/4.0.0"</span> <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">properties</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">project.build.sourceEncoding</span>></span>UTF-8<span class="tag"></<span class="name">project.build.sourceEncoding</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">properties</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">modelVersion</span>></span>4.0.0<span class="tag"></<span class="name">modelVersion</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>io.github.caoxm<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>TutorialPlugin<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">packaging</span>></span>jar<span class="tag"></<span class="name">packaging</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.0-SNAPSHOT<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">name</span>></span>TutorialPlugin<span class="tag"></<span class="name">name</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">repositories</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">repository</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">id</span>></span>spigot-repo<span class="tag"></<span class="name">id</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">url</span>></span>https://hub.spigotmc.org/nexus/content/repositories/snapshots/<span class="tag"></<span class="name">url</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">repository</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">repositories</span>></span> </span><br><span class="line"> <span class="tag"><<span class="name">dependencies</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.spigotmc<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>spigot-api<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.12.2-R0.1-SNAPSHOT<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">scope</span>></span>provided<span class="tag"></<span class="name">scope</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">dependencies</span>></span></span><br><span class="line"><span class="tag"></<span class="name">project</span>></span></span><br></pre></td></tr></table></figure></li><li><p>编写插件的主类,下面是个示例:</p><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> io.github.caoxm; <span class="comment">//这里是包名,这个类放在这下面哦</span></span><br><span class="line"><span class="keyword">import</span> org.bukkit.plugin.java.<span class="type">JavaPlugin</span>;</span><br><span class="line"><span class="comment">/*下面内容参考Spiogt API来写就好了,JavaPlugin是表示插件的抽象基类</span></span><br><span class="line"><span class="comment"> *通常我们的主类要继承JavaPlugin并重写其方法</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">public <span class="class"><span class="keyword">class</span> <span class="title">TutorialPlugin</span> <span class="keyword">extends</span> <span class="title">JavaPlugin</span></span>{</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line">public void onEnable() {</span><br><span class="line">getLogger().info(<span class="string">"onEnable is called!"</span>);</span><br><span class="line">}</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line">public void onDisable() {</span><br><span class="line">getLogger().info(<span class="string">"onDisable is called!"</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>编写plugin.yml,从而让该插件被识别</p><pre><code>plugin.yml要放在\src\main\resources目录下,如果maven未创建该目录可以自行创建</code></pre><figure class="highlight avrasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">name:</span> TutorialPlugin</span><br><span class="line"><span class="symbol">version:</span> <span class="number">1.0</span></span><br><span class="line"><span class="symbol">main:</span> io.github.caoxm.TutorialPlugin</span><br><span class="line"><span class="symbol">author:</span> caoxm-me</span><br></pre></td></tr></table></figure></li></ol><h1 id="三-编译,测试"><a href="#三-编译,测试" class="headerlink" title="三. 编译,测试"></a>三. 编译,测试</h1><pre><code>进入项目根目录,在该路径下打开cmd</code></pre><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">></span><span class="bash">mvn compile</span></span><br><span class="line"><span class="meta">></span><span class="bash">mvn package</span></span><br><span class="line"><span class="meta">></span><span class="bash">mvn install</span></span><br></pre></td></tr></table></figure><h1 id="四-从该项目创建模板,方便重用"><a href="#四-从该项目创建模板,方便重用" class="headerlink" title="四. 从该项目创建模板,方便重用"></a>四. 从该项目创建模板,方便重用</h1><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">></span><span class="bash">mvn archetype:create-from-project</span></span><br><span class="line"><span class="meta">></span><span class="bash"><span class="built_in">cd</span> .\target\generated-sources\archetype</span></span><br><span class="line"><span class="meta">></span><span class="bash">mvn clean install</span></span><br></pre></td></tr></table></figure><pre><code>之后便会在本地仓库建立该项目模板,可以通过该模板建立新项目</code></pre><figure class="highlight verilog"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">>mvn archetype:<span class="keyword">generate</span> -DarchetypeCatalog=<span class="keyword">local</span></span><br></pre></td></tr></table></figure><pre><code>上面的命令会开启交互模式,自行输入序号选择模板即可</code></pre><p>#五. 使用IDE建立maven项目<br> 使用Eclipse,IDEA这样的集成开发环境建立maven项目的过程很简单,只要安装了maven插件即可,这里就不写了</p>]]></content>
<summary type="html">
<h1 id="一-安装Maven"><a href="#一-安装Maven" class="headerlink" title="一. 安装Maven"></a>一. 安装Maven</h1><ol>
<li>不多说,去apache下载安装即可</li>
<li>配置环境变量:
</summary>
<category term="minecraft" scheme="http://yoursite.com/categories/minecraft/"/>
</entry>
<entry>
<title>编译Spigot Server</title>
<link href="http://yoursite.com/2018/02/23/%E7%BC%96%E8%AF%91spigot/"/>
<id>http://yoursite.com/2018/02/23/%E7%BC%96%E8%AF%91spigot/</id>
<published>2018-02-23T06:10:06.000Z</published>
<updated>2020-04-28T16:01:01.843Z</updated>
<content type="html"><![CDATA[<h1 id="一-编译方法"><a href="#一-编译方法" class="headerlink" title="一.编译方法"></a>一.编译方法</h1><p> <strong>1. 下载BuildTools</strong></p><pre><code>官网链接:[https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar][1]。如果使用命令行,则可使用下面两种办法或者: <figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -o BuildTools.jar -k https:<span class="regexp">//</span>hub.spigotmc.org<span class="regexp">/jenkins/</span>job<span class="regexp">/BuildTools/</span>lastSuccessfulBuild<span class="regexp">/artifact/</span>target<span class="regexp">/BuildTools.jar</span></span><br></pre></td></tr></table></figure>或者: <figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget -O BuildTools.jar https:<span class="regexp">//</span>hub.spigotmc.org<span class="regexp">/jenkins/</span>job<span class="regexp">/BuildTools/</span>lastSuccessfulBuild<span class="regexp">/artifact/</span>target<span class="regexp">/BuildTools.jar</span></span><br></pre></td></tr></table></figure></code></pre><p><strong>2. 使用BuildTools编译spigot</strong></p><pre><code>在BuildTools.jar所在目录输入命令: <figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">java</span> <span class="selector-tag">-jar</span> <span class="selector-tag">BuildTools</span><span class="selector-class">.jar</span> <span class="selector-tag">--rev</span> 1<span class="selector-class">.12</span><span class="selector-class">.2</span></span><br></pre></td></tr></table></figure></code></pre><h1 id="二-基本流程"><a href="#二-基本流程" class="headerlink" title="二.基本流程"></a>二.基本流程</h1><ol><li>依次从相应git仓库clone文件到本地,文件存放在当前目录Bukkit、raftBukkit、Spigot、Builddata目录下</li><li>安装apache-maven到当前目录下,使用maven构建项目</li><li>编译Spigot server</li><li>编译完成后,会在当前路径下发现craftbukkit-1.10.jar 和 spigot-1.10.jar</li></ol>]]></content>
<summary type="html">
<h1 id="一-编译方法"><a href="#一-编译方法" class="headerlink" title="一.编译方法"></a>一.编译方法</h1><p> <strong>1. 下载BuildTools</strong></p>
<pre><code>官网链接:
</summary>
<category term="minecraft" scheme="http://yoursite.com/categories/minecraft/"/>
</entry>
</feed>