汇编语言复习提纲
<h1 id="汇编语言复习提纲" data-source-line="1">汇编语言复习提纲</h1><blockquote data-source-line="2">
<p>考试时间:十六周周一<br>考试形式:笔试<br>考试范围:第一章-第九章<br>题型:填空、简答、程序设计<br>教材:IBM-PC汇编语言程序设计(第二版)<br>作者:@TheSilverMoon<br>博客:https://www.cnblogs.com/TheSilverMoon/</p>
</blockquote>
<h2 id="第一章" data-source-line="10">第一章</h2>
<ol data-source-line="11">
<li>进制转换</li>
<li>补码加法、减法</li>
<li>与或非、异或运算</li>
</ol><hr><hr><hr>
<h2 id="第二章" data-source-line="19">第二章</h2>
<h3 id="80x86寄存器组" data-source-line="20">80x86寄存器组</h3>
<ul data-source-line="21">
<li>ax(accumulator),做为累加器用,在乘除等指令中指定用来存放操作数</li>
<li>bx(base),可以做为通用寄存器,经常用做基址寄存器</li>
<li>cx(count),可以做为通用寄存器,常用来保存计数值(比如在loop中)</li>
<li>dx(data),可以做为通用寄存器,一般在双字长运算时把dx和ax组合在一起存放一个双字长数,dx存高位。</li>
<li>sp(stack pointer)堆栈指针寄存器(指示段顶偏移地址)</li>
<li>bp(base pointer)基址指针寄存器(堆栈区中的一个基地址)</li>
<li>si(source index)源变址寄存器和di(destination index)目的变址寄存器一般与ds联用,用来确定数据段中某一存储单元的地址。串处理指令中,si和di做为隐含的源变址和目的变址寄存器。</li>
<li>ip(instruction pointer)指令指针寄存器,用来存放代码段中的偏移地址</li>
<li>flags 标志寄存器</li>
</ul>
<hr><hr>
<h3 id="条件码" data-source-line="32">条件码</h3>
<ul data-source-line="33">
<li>of(overflow)操作数超出了机器能表示的范围时为1</li>
<li>sf(sign flag)记录运算结果的符号,负置1</li>
<li>zf(zero flag)运算结果为0时,置1</li>
<li>cf(carry flag)进位标志,进位置1</li>
<li>af(auxiliary carry flag)记录第三位(半个字节)产生的进位值</li>
<li>if(interrrupt flag)if为1时,CPU正常响应可屏蔽中断请求</li>
</ul>
<hr>
<blockquote data-source-line="41">
<p>80x86地址总线为20位 1m=2^20,当机器字长为16位时,大部分数据是以字为单位,存放时,低位字节放入低地址,高位字节放入高地址,如存放5678h,低位78h存放在0004h单元中,高位56h存放在0005h单元中</p>
</blockquote>
<hr>
<blockquote data-source-line="44">
<p>20位物理地址由16位段地址和16位偏移地址组成,段地址左移4位(16进制左移1位)再加上偏移地址即为物理地址。</p>
</blockquote>
<hr><hr><hr>
<h2 id="第三章" data-source-line="50">第三章</h2>
<h3 id="80x86寻址方式" data-source-line="51">80x86寻址方式</h3>
<ul data-source-line="52">
<li>立即寻址方式<br>例:mov al(八位寄存器),5(源操作数)</li>
<li>寄存器寻址方式 例:mov ax,bx 16位寄存器:ax,bx,cx,dx,si,di,sp,bp 8位寄存器:al,ah,bl,bh,cl,ch,dl,dh</li>
<li>直接寻址方式<br>例:mov ax(16位寄存器),(EA)<br>EA(Effective Address)=基址+(变址X比例因子)+位移量<br>加中括号表示偏移地址,默认在DS<br>可以使用段跨越前缀,如mov ax,ES:,但在某些情况下不可以使用段跨越前缀(书P39)</li>
<li>寄存器间接寻址方式 例:mov ax, 若ds=2000h,bx=1000h 物理地址=20000+1000=21000h</li>
<li>寄存器相对寻址方式<br>move ax,count count为16位位移量的符号地址 类似的,可以有mov eax,tableesi内容指向此表格中的一项<br>适用于字符串、数组、表格的处理</li>
<li>基址变址寻址方式 例:mov ax,或mov ax,</li>
</ul>
<hr>
<p data-source-line="73">段内直接寻址:<br>指令格式为:</p>
<pre data-source-line="75"><code class="hljs"><span class="hljs-keyword">jmp <span class="hljs-built_in">near <span class="hljs-built_in">ptr progia
<span class="hljs-keyword">jmp short quest
</span></span></span></span></code></pre>
<p data-source-line="79">如果位移量为16位,在符号地址前加near ptr操作符;如果为8位,在其之前加short</p>
<p data-source-line="81">段内直接寻址:</p>
<pre data-source-line="82"><code class="hljs"><span class="hljs-keyword">jmp <span class="hljs-keyword">bx
</span></span></code></pre>
<hr>
<h3 id="80x86指令系统" data-source-line="86">80x86指令系统</h3>
<p data-source-line="87">数据传送指令:</p>
<blockquote data-source-line="88">
<p>mov 传送<br>movsx 带符号扩展传送<br>push 进栈<br>pop 出栈<br>xhcg 交换<br>lea 有效地址送寄存器</p>
</blockquote>
<pre data-source-line="95"><code class="hljs">lea reg,src <span class="hljs-comment">;<span class="zh-hans">把源操作数的有效地址送到指定寄存器当中
</span></span></code></pre>
<hr>
<p data-source-line="99">类型转换指令:</p>
<blockquote data-source-line="100">
<p>cbw 字节转换成字<br>cwd 字转换为双字</p>
</blockquote>
<ol data-source-line="103">
<li>执行的操作:al的内容符号扩展到ah,形成ax中的字。即如果al的最高有效位为0,则ah为0;如al的最高有效位为1,则ah=0ffffh</li>
<li>执行的操作:ax的内容符号扩展到dx,形成dx:ax中的双字</li>
</ol><hr>
<p data-source-line="108">算数指令:</p>
<blockquote data-source-line="110">
<p>add 加法<br>adc 带进位加法<br>inc 加一<br>xadd 交换并相加<br>sub 减法<br>sbb 带借位减法<br>dec 减一<br>cmp 比较<br>mul 无符号乘法<br>imul 带符号乘法<br>div 除法<br>idiv 带符号除法</p>
</blockquote>
<pre data-source-line="123"><code class="hljs"><span class="hljs-keyword">add dst,src
adc dst,src
adc dst.src
inc opr <span class="hljs-comment">;opr<span class="zh-hans">是操作数的意思
<span class="hljs-comment">;<span class="zh-hans">除inc<span class="zh-hans">指令不影响cf<span class="zh-hans">外,其他都影响条件标志位
<span class="hljs-comment">;of <span class="zh-hans">可以用来表示带符号数的溢出,cf<span class="zh-hans">可以表示无符号数的溢出
<span class="hljs-keyword">sub dst,src
<span class="hljs-keyword">sbb dst,src
dec opr <span class="hljs-comment">;
cmp opr1,opr2<span class="hljs-comment">;<span class="zh-hans">执行减法操作,但是不保存结果,只是根据结果设置条件标志位,后面往往跟着一条条件转移指令,根据结果产生不同的程序分支
<span class="hljs-keyword">mul src
<span class="hljs-comment">;<span class="zh-hans">字节操组数: ax <- al * src<span class="zh-hans">两个八位数相乘得到的十六位数,存在ax<span class="zh-hans">中
<span class="hljs-comment">;<span class="zh-hans">字操作数: (dx.ax) <- ax * src<span class="zh-hans">两个八位数相乘得到的十六位数,存在dx,ax<span class="zh-hans">中;dx<span class="zh-hans">存高位,ax<span class="zh-hans">存低位
<span class="hljs-keyword">div src<span class="hljs-comment">;16<span class="zh-hans">位被除数在ax<span class="zh-hans">中,8<span class="zh-hans">位除数为源操作数,结果的8<span class="zh-hans">位商在al<span class="zh-hans">中,8<span class="zh-hans">位余数在ah<span class="zh-hans">中
idiv src<span class="hljs-comment">;32<span class="zh-hans">位的被除数在dx<span class="zh-hans">,ax<span class="zh-hans">中,16<span class="zh-hans">位除数为源操作数,结果的16<span class="zh-hans">位在ax<span class="zh-hans">中,16<span class="zh-hans">位的余数在dx<span class="zh-hans">中
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<hr>
<p data-source-line="144">逻辑指令:</p>
<blockquote data-source-line="145">
<p>and 逻辑与<br>or 逻辑或<br>not 逻辑非<br>xor 异或<br>test 测试</p>
</blockquote>
<pre data-source-line="151"><code class="hljs">anddst,src
or des,src
not opr
xor dst,src
<span class="hljs-keyword">test opr1,opr2 ;<span class="zh-hans">两个操作数想与,结果不保存,只根据其特征置条件码
;not <span class="zh-hans">不允许使用立即数,其他的至少有个一个操作数必须存放在寄存器中
</span></span></span></code></pre>
<hr>
<p data-source-line="161">位移指令:</p>
<blockquote data-source-line="162">
<p>shl 逻辑左移<br>sal 算术左移<br>shr 逻辑右移 sar 算术右移<br>rol 循环左移<br>ror 循环右移<br>rcl 带进位左移<br>rcr 带进位右移</p>
</blockquote>
<pre data-source-line="171"><code class="hljs">shl opr,<span class="hljs-keyword">cnt
sal opr,<span class="hljs-keyword">cnt
sar opr,<span class="hljs-keyword">cnt
rol opr,<span class="hljs-keyword">cnt
ror opr,<span class="hljs-keyword">cnt
rcl opr,<span class="hljs-keyword">cnt
rcr opr,<span class="hljs-keyword">cnt
</span></span></span></span></span></span></span></code></pre>
<p data-source-line="180">如果大于cnt大于1,则需要存在cl中,cf保存移出的最后一位</p>
<hr>
<p data-source-line="183">串处理指令:</p>
<blockquote data-source-line="184">
<p>movs 串传送<br>cmps 串比较<br>ins 串输入<br>outs 串输出<br>rep 重复<br>repe 相等则重复<br>repne 不相等则重复</p>
</blockquote>
<pre data-source-line="192"><code class="hljs">rep <span class="hljs-keyword">string <span class="hljs-keyword">primitive<span class="hljs-title"> ;string primitive<span class="zh-hans">可为各种指令
movs dst,src
</span></span></span></span></code></pre>
<hr>
<p data-source-line="197">条件转移指令:</p>
<blockquote data-source-line="198">
<p>jz(jump if zero) 结果为0则转移<br>jnz(jump if not zero) 结果不为0则转移<br>js(jump if sign) 结果为负则转移 jns(jump if not sign) 结果为正则转移<br>jbe(jump if below or equal)低于或等于,或不高于则转移<br>jnbe(jump if not below or equal,or not above) 不低于或等于,或高于则转移<br>jge 不小于则转移 jng 不大于则转移</p>
</blockquote>
<hr>
<p data-source-line="208">循环指令:</p>
<blockquote data-source-line="209">
<p>loop 循环<br>loopz 相等或为0时循环<br>loopnz 不相等或不为0时循环</p>
</blockquote>
<hr>
<p data-source-line="214">子程序:</p>
<blockquote data-source-line="215">
<p>call 调用<br>ret 返回</p>
</blockquote>
<pre data-source-line="218"><code class="hljs"><span class="hljs-keyword">call dst
<span class="hljs-keyword">ret
</span></span></code></pre>
<hr>
<p data-source-line="223">中断:</p>
<blockquote data-source-line="224">
<p>int中断指令</p>
</blockquote>
<pre data-source-line="226"><code class="hljs">int<span class="hljs-built_in"> type
</span></code></pre>
<hr><hr><hr>
<h2 id="第四章" data-source-line="233">第四章</h2>
<h3 id="伪操作" data-source-line="234">伪操作</h3>
<blockquote data-source-line="235">
<p>assume 伪操作</p>
</blockquote>
<p data-source-line="237">明确段和段寄存器的关系<br><em>例:</em></p>
<pre data-source-line="239"><code class="hljs"><span class="hljs-meta">assume <span class="hljs-built_in">cs:code,<span class="hljs-built_in">ds:data,<span class="hljs-built_in">ss:stack
</span></span></span></span></code></pre>
<hr>
<blockquote data-source-line="243">
<p>数据定义及存储器分配伪操作</p>
</blockquote>
<ul data-source-line="245">
<li>DB 定义字节,其后的每个操作数都占有一个字节(8位)</li>
<li>DW 定义字,其后的每个操作数占有一个字(16位,低位字节在第一个字节地址中,高位字节在第二个字节地址中)</li>
<li>DD 定义双字,其后的每个操作数占有两个字(32位)</li>
</ul>
<pre data-source-line="248"><code class="hljs">data_byte db <span class="hljs-number">10,<span class="hljs-number">4,<span class="hljs-number">10h
data_word dw <span class="hljs-number">100,<span class="hljs-number">100h,<span class="hljs-number">-5
data_dw dd <span class="hljs-number">3*<span class="hljs-number">20,<span class="hljs-number">0fffdh
</span></span></span></span></span></span></span></span></span></code></pre>
<p data-source-line="253"><img src="https://img2018.cnblogs.com/blog/1402778/201906/1402778-20190603231242843-1504945619.png?ynotemdtimestamp=1561117812667" alt="image" data-src="https%3A%2F%2Fimg2018.cnblogs.com%2Fblog%2F1402778%2F201906%2F1402778-20190603231242843-1504945619.png" data-processed="https%3A%2F%2Fimg2018.cnblogs.com%2Fblog%2F1402778%2F201906%2F1402778-20190603231242843-1504945619.png"></p>
<ul data-source-line="254">
<li>操作数'?'可以保留存储空间,但不存入数据</li>
</ul>
<pre data-source-line="255"><code class="hljs">abc db <span class="hljs-number">0,?,?,<span class="hljs-number">0
</span></span></code></pre>
<ul data-source-line="259">
<li>dup 复制操作符</li>
</ul>
<pre data-source-line="260"><code class="hljs"><span class="hljs-built_in">array1 db <span class="hljs-number">2 dup(<span class="hljs-number">0,<span class="hljs-number">1,<span class="hljs-number">2,?)
<span class="hljs-built_in">array2 db <span class="hljs-number">100 dup(?)
</span></span></span></span></span></span></span></code></pre>
<p data-source-line="264"><img src="https://img2018.cnblogs.com/blog/1402778/201906/1402778-20190603231710957-131540888.png?ynotemdtimestamp=1561117812667" alt="image" data-src="https%3A%2F%2Fimg2018.cnblogs.com%2Fblog%2F1402778%2F201906%2F1402778-20190603231710957-131540888.png" data-processed="https%3A%2F%2Fimg2018.cnblogs.com%2Fblog%2F1402778%2F201906%2F1402778-20190603231710957-131540888.png"></p>
<ul data-source-line="266">
<li>EQU 表达式赋值伪操作</li>
</ul>
<pre data-source-line="267"><code class="hljs"><span class="hljs-symbol">constant <span class="hljs-meta">equ <span class="hljs-number">256
<span class="hljs-symbol">data <span class="hljs-meta">equ height+<span class="hljs-number">12
<span class="hljs-symbol">alpha <span class="hljs-meta">equ <span class="hljs-number">7
<span class="hljs-keyword">beta <span class="hljs-meta">equ alpha-<span class="hljs-number">2
<span class="hljs-keyword">addr <span class="hljs-meta">equ var+<span class="hljs-keyword">beta
<span class="hljs-keyword">b <span class="hljs-meta">equ [<span class="hljs-keyword">bp+8]
<span class="hljs-symbol">p8 <span class="hljs-meta">equ ds:[<span class="hljs-keyword">bp+8]
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<hr>
<blockquote data-source-line="277">
<p>地址计数器与对准伪操作</p>
</blockquote>
<ul data-source-line="279">
<li>'$'地址计数器<br>汇编程序使用地址计数器来保存当前正在汇编的指令的偏移地址。开始汇编或在每一段开始时,地址计数器初始化为0,之后每处理一条指令,地址计数器就增加一个值,此值为该指令所需要的字节数<br><em>例:</em></li>
</ul>
<pre data-source-line="282"><code class="hljs"><span class="hljs-built_in">array dw <span class="hljs-number">1,<span class="hljs-number">2,$+<span class="hljs-number">4,<span class="hljs-number">3,<span class="hljs-number">4,$+<span class="hljs-number">4
</span></span></span></span></span></span></span></code></pre>
<p data-source-line="285">若汇编时array分配的偏移地址为0074,则存储区如下:<br><img src="https://img2018.cnblogs.com/blog/1402778/201906/1402778-20190603233156848-208259572.png?ynotemdtimestamp=1561117812667" alt="iamge" data-src="https%3A%2F%2Fimg2018.cnblogs.com%2Fblog%2F1402778%2F201906%2F1402778-20190603233156848-208259572.png" data-processed="https%3A%2F%2Fimg2018.cnblogs.com%2Fblog%2F1402778%2F201906%2F1402778-20190603233156848-208259572.png">TIPS:$只代表该指令的首地址</p>
<hr>
<blockquote data-source-line="291">
<p>数值回送操作符</p>
</blockquote>
<ul data-source-line="293">
<li>type</li>
</ul>
<pre data-source-line="294"><code class="hljs"><span class="hljs-keyword">type <span class="hljs-type">expression
</span></span></code></pre>
<p data-source-line="297"><em>例:</em></p>
<pre data-source-line="298"><code class="hljs">array dw 123<span class="hljs-built_in">
add si,type<span class="hljs-built_in"> array
</span></span></code></pre>
<p data-source-line="302">该语句形成为:add si,2<br>**如果该表达式是变量,db回送1,dw回送2,dd回送4,如果该表达式为常量,回送0 **</p>
<ul data-source-line="305">
<li>length</li>
</ul>
<pre data-source-line="306"><code class="hljs"><span class="hljs-built_in">length <span class="hljs-built_in">variable
</span></span></code></pre>
<p data-source-line="309">对于变量中使用dup的情况,回送分配给该变量的单元数,其他情况送1</p>
<ul data-source-line="311">
<li>size</li>
</ul>
<pre data-source-line="312"><code class="hljs"><span class="hljs-built_in">size variable
</span></code></pre>
<p data-source-line="315">回送分配给该变量的字节数,此值是length和type的乘积</p>
<ul data-source-line="317">
<li>offset</li>
</ul>
<pre data-source-line="318"><code class="hljs">offset variable/<span class="hljs-keyword">label</span></code></pre>
<p data-source-line="321">回送变量或标号的偏移地址值</p>
<ul data-source-line="323">
<li>seg</li>
</ul>
<pre data-source-line="324"><code class="hljs">seg variable/<span class="hljs-keyword">label</span></code></pre>
<p data-source-line="327">回送变量或标号的段地址值</p>
<ul data-source-line="329">
<li>high&low</li>
</ul>
<pre data-source-line="330"><code class="hljs">const <span class="hljs-built_in">equ <span class="hljs-number">0abcdh
<span class="hljs-keyword">mov <span class="hljs-number">ah,high const
</span></span></span></span></code></pre>
<p data-source-line="334">将汇编成mov ah,0abh</p>
<hr><hr>
<h3 id="上机过程" data-source-line="338">上机过程(★)</h3>
<pre data-source-line="339"><code class="hljs"><span class="hljs-attr">mount <span class="hljs-string">d d:\masm
<span class="hljs-attr">d:<span class="hljs-string">
<span class="hljs-attr">masm <span class="hljs-string">filename
<span class="hljs-attr">link <span class="hljs-string">filename
<span class="hljs-attr">debug <span class="hljs-string">filename.exe / filename.exe
</span></span></span></span></span></span></span></span></span></span></code></pre>
<hr><ol data-source-line="347">
<li>建立asm文件</li>
<li>用masm程序产生obj文件</li>
<li>用link程序产生exe文件</li>
<li>执行程序</li>
</ol><hr>
<p data-source-line="352">常用命令:</p>
<ol data-source-line="353">
<li>G命令:运行当前在内存中的程序</li>
<li>D命令:显示一定范围内存地址的内容<br>格式:d <br>如果键入以下命令,Debug 将从 CS:100 开始显示 20h 个字节的内容:<br>dcs:100 l 20<br>如果键入以下命令,Debug 将显示范围从CS 段的100h 到115h 中所有字节的内容:<br>dcs:100 115</li>
<li>R命令:显示或改变一个或多个 CPU 寄存器的内容<br>r </li>
<li>U命令:反汇编字节并显示相应的原语句,其中包括地址和字节值。反汇编代码看起来象已汇编文件的列表<br>u <br>参数<br>如果在没有参数的情况下使用,则 u 命令分解 20h 字节(默认值),从前面 u 命令所显示地址后的第一个地址开始。<br>range<br>指定要反汇编代码的起始地址和结束地址,或起始地址和长度。</li>
</ol><hr><hr><hr>
<h2 id="第五章" data-source-line="372">第五章</h2>
<blockquote data-source-line="373">
<p>本章内容老师上课说以作业为主,下面放一下作业的代码</p>
</blockquote>
<p data-source-line="375">5.6 编写程序,将一个包含有20个数据的数组m分成两个数组:正数数组p和负数数组n,并分别把这两个数组中数据的个数求出来</p>
<pre data-source-line="376"><code class="hljs">data <span class="hljs-meta">segment
count <span class="hljs-built_in">equ <span class="hljs-number">20
array <span class="hljs-built_in">dw <span class="hljs-number">20 dup(?)<span class="hljs-comment">;<span class="zh-hans">存放数组
count1 <span class="hljs-built_in">equ <span class="hljs-number">0<span class="hljs-comment">;<span class="zh-hans">正数个数
array1 <span class="hljs-built_in">dw <span class="hljs-number">20 dup(?)
count2 <span class="hljs-built_in">equ <span class="hljs-number">0<span class="hljs-comment">;<span class="zh-hans">负数个数
array2 <span class="hljs-built_in">dw <span class="hljs-number">20 dup(?)
data ends
code <span class="hljs-meta">segment
main proc <span class="hljs-built_in">far
<span class="hljs-meta">assume <span class="hljs-built_in">cs:code,<span class="hljs-built_in">ds:data
<span class="hljs-symbol">start:
<span class="hljs-keyword">push <span class="hljs-built_in">ds<span class="hljs-comment">;<span class="zh-hans">设置返回dos
<span class="hljs-keyword">xor <span class="hljs-built_in">ax,<span class="hljs-built_in">ax
<span class="hljs-keyword">mov <span class="hljs-built_in">ax,data
<span class="hljs-keyword">mov <span class="hljs-built_in">ds,<span class="hljs-built_in">ax<span class="hljs-comment">;<span class="zh-hans">给ds<span class="zh-hans">赋值
<span class="hljs-symbol">
begin:
<span class="hljs-keyword">mov <span class="hljs-built_in">cx,count
<span class="hljs-keyword">lea <span class="hljs-built_in">bx,array
<span class="hljs-keyword">lea <span class="hljs-built_in">si,array1
<span class="hljs-keyword">lea <span class="hljs-built_in">di,array2
<span class="hljs-symbol">
begin1:
<span class="hljs-keyword">mov <span class="hljs-built_in">ax,[<span class="hljs-built_in">bx]
<span class="hljs-keyword">cmp <span class="hljs-built_in">ax,<span class="hljs-number">0
<span class="hljs-keyword">js negative
<span class="hljs-keyword">mov [<span class="hljs-built_in">si],<span class="hljs-built_in">ax<span class="hljs-comment">;<span class="zh-hans">是正数,存入数组
<span class="hljs-keyword">inc count1
<span class="hljs-keyword">add <span class="hljs-built_in">si,<span class="hljs-number">2
<span class="hljs-keyword">jmp next
<span class="hljs-symbol">
negative:
<span class="hljs-keyword">mov [<span class="hljs-built_in">di],<span class="hljs-built_in">ax
<span class="hljs-keyword">inc count2
<span class="hljs-keyword">add <span class="hljs-built_in">di,<span class="hljs-number">2
<span class="hljs-symbol">
next:
<span class="hljs-keyword">add <span class="hljs-built_in">bx,<span class="hljs-number">2
<span class="hljs-keyword">loop begin1
<span class="hljs-keyword">mov <span class="hljs-built_in">al,count1
<span class="hljs-keyword">call print
<span class="hljs-keyword">mov <span class="hljs-built_in">al,count2
<span class="hljs-keyword">call print
<span class="hljs-keyword">mov <span class="hljs-number">ah,<span class="hljs-number">4ch
<span class="hljs-keyword">int <span class="hljs-number">21h
<span class="hljs-keyword">ret
main endp
print proc <span class="hljs-built_in">near
<span class="hljs-keyword">aam <span class="hljs-comment">;<span class="zh-hans">将(AL)<span class="zh-hans">中的二进制数转换为二个非压缩 BCD <span class="zh-hans">码,AH<span class="zh-hans">←AL/10(<span class="zh-hans">商)<span class="zh-hans">,AL<span class="zh-hans">←AL%10(<span class="zh-hans">余数)
<span class="hljs-keyword">add <span class="hljs-number">ah, <span class="zh-hans">‘<span class="hljs-number">0<span class="zh-hans">’ <span class="hljs-comment">;<span class="zh-hans">变为 0<span class="zh-hans">~9 <span class="zh-hans">的 ASCII <span class="zh-hans">码
<span class="hljs-keyword">mov <span class="hljs-built_in">dl, <span class="hljs-number">ah
<span class="hljs-keyword">mov <span class="hljs-number">ah, <span class="hljs-number">2 <span class="hljs-comment">;<span class="zh-hans">显示一个字符的 DOS <span class="zh-hans">调用
<span class="hljs-keyword">int <span class="hljs-number">21H
<span class="hljs-keyword">add <span class="hljs-built_in">al, <span class="zh-hans">‘<span class="hljs-number">0<span class="zh-hans">’ <span class="hljs-comment">;<span class="zh-hans">变为 0<span class="zh-hans">~9 <span class="zh-hans">的 ASCII <span class="zh-hans">码
<span class="hljs-keyword">mov <span class="hljs-built_in">dl, <span class="hljs-built_in">al
<span class="hljs-keyword">mov <span class="hljs-number">ah, <span class="hljs-number">2 <span class="hljs-comment">;<span class="zh-hans">显示一个字符的 DOS <span class="zh-hans">调用
<span class="hljs-keyword">int <span class="hljs-number">21h
<span class="hljs-keyword">ret
code ends
end start
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p data-source-line="441">5.7 试编制一个汇编语言程序,求出首地址为data的100d字数组中的最小偶数,并将其存在ax中</p>
<pre data-source-line="443"><code class="hljs">dsg <span class="hljs-meta">segment
data <span class="hljs-built_in">dw <span class="hljs-number">100 dup(?)
dsg ends
code <span class="hljs-meta">segment
main proc <span class="hljs-built_in">far
<span class="hljs-meta">assume <span class="hljs-built_in">cs:code,<span class="hljs-built_in">ds:dsg
<span class="hljs-symbol">
start:
<span class="hljs-symbol">
begin:
<span class="hljs-keyword">mov <span class="hljs-built_in">bx,<span class="hljs-number">0
<span class="hljs-keyword">mov <span class="hljs-built_in">cx,<span class="hljs-number">100
<span class="hljs-symbol">
comp:
<span class="hljs-keyword">mov <span class="hljs-built_in">ax,data[<span class="hljs-built_in">bx]
<span class="hljs-keyword">add <span class="hljs-built_in">bx,<span class="hljs-number">2
<span class="hljs-keyword">test <span class="hljs-built_in">ax,<span class="hljs-number">01h <span class="hljs-comment">;<span class="zh-hans">判断是否是偶数
<span class="hljs-keyword">loopnz comp<span class="hljs-comment">;loop not zero <span class="zh-hans">,继续比较下一个
<span class="hljs-keyword">jnz stop
<span class="hljs-keyword">jcxz stop<span class="hljs-comment">;<span class="zh-hans">若cx=0<span class="zh-hans">,则最后一个是偶数,即为最小偶数
<span class="hljs-symbol">
comp1:
<span class="hljs-keyword">mov <span class="hljs-built_in">dx,data[<span class="hljs-built_in">bx]
<span class="hljs-keyword">add <span class="hljs-built_in">bx,<span class="hljs-number">2
<span class="hljs-keyword">test <span class="hljs-built_in">dx,<span class="hljs-number">01h
<span class="hljs-keyword">jnz next<span class="hljs-comment">;<span class="zh-hans">不是,比较下一个数
<span class="hljs-keyword">cmp <span class="hljs-built_in">ax,<span class="hljs-built_in">dx <span class="hljs-comment">;ax<dx<span class="zh-hans">吗
<span class="hljs-keyword">jle next
<span class="hljs-keyword">mov <span class="hljs-built_in">ax,<span class="hljs-built_in">dx
<span class="hljs-symbol">next:<span class="hljs-keyword">loop comp1
<span class="hljs-symbol">stop:<span class="hljs-keyword">ret
main endp
code ends
end start
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p data-source-line="483">5.12 有一个首地址为MEM的100d字数组,试编制程序删除数组中所有为0的项,并将后续项向前压缩,最后将数组的剩余部分补上0</p>
<pre data-source-line="484"><code class="hljs">data <span class="hljs-meta">segment
mem <span class="hljs-built_in">dw <span class="hljs-number">100 dup(?)
data ends
code <span class="hljs-meta">segment
main proc <span class="hljs-built_in">far
<span class="hljs-meta">assume <span class="hljs-built_in">cs:code,<span class="hljs-built_in">ds:data
<span class="hljs-symbol">start:
<span class="hljs-keyword">push <span class="hljs-built_in">ds
<span class="hljs-keyword">xor <span class="hljs-built_in">ax,<span class="hljs-built_in">ax
<span class="hljs-keyword">push <span class="hljs-built_in">ax
<span class="hljs-keyword">mov <span class="hljs-built_in">ax,data
<span class="hljs-keyword">mov <span class="hljs-built_in">ds,<span class="hljs-built_in">ax
<span class="hljs-symbol">
begin:
<span class="hljs-keyword">mov <span class="hljs-built_in">si,(<span class="hljs-number">100-<span class="hljs-number">1)*<span class="hljs-number">2<span class="hljs-comment">;SI<span class="zh-hans">指向mem<span class="zh-hans">末元素的首地址
<span class="hljs-keyword">mov <span class="hljs-built_in">bx,-<span class="hljs-number">2 <span class="hljs-comment">;<span class="zh-hans">地址指针的初值
<span class="hljs-keyword">mov <span class="hljs-built_in">cx,<span class="hljs-number">100 <span class="hljs-comment">;count
<span class="hljs-symbol">
comp:
<span class="hljs-keyword">add <span class="hljs-built_in">bx,<span class="hljs-number">2
<span class="hljs-keyword">cmp mem[<span class="hljs-built_in">bx],<span class="hljs-number">0
<span class="hljs-keyword">jz cons
<span class="hljs-keyword">loop comp
<span class="hljs-keyword">jmp finish<span class="hljs-comment">;<span class="zh-hans">比较完了,无0<span class="zh-hans">结束
<span class="hljs-symbol">
cons:
<span class="hljs-keyword">mov <span class="hljs-built_in">di,<span class="hljs-built_in">bx
<span class="hljs-symbol">cons1:
<span class="hljs-keyword">cmp <span class="hljs-built_in">di,<span class="hljs-built_in">si<span class="hljs-comment">;<span class="zh-hans">到最后了吗
<span class="hljs-keyword">jae nomov
<span class="hljs-keyword">mov <span class="hljs-built_in">ax,mem[<span class="hljs-built_in">di+<span class="hljs-number">2]<span class="hljs-comment">;<span class="zh-hans">后面元素向前移
<span class="hljs-keyword">mov mem[<span class="hljs-built_in">di],<span class="hljs-built_in">ax
<span class="hljs-keyword">add <span class="hljs-built_in">di,<span class="hljs-number">2
<span class="hljs-keyword">jmp cons1
<span class="hljs-symbol">
nomov:
<span class="hljs-keyword">mov [<span class="hljs-built_in">si],<span class="hljs-number">0<span class="hljs-comment">;<span class="zh-hans">最后元素补0
<span class="hljs-keyword">loop comp
<span class="hljs-symbol">finish:
<span class="hljs-keyword">ret
main endp
code ends
end start
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<hr><hr><hr>
<h2 id="第六章" data-source-line="536">第六章</h2>
<h3 id="子程序" data-source-line="537">子程序</h3>
<p data-source-line="538">格式:</p>
<pre data-source-line="539"><code class="hljs">procedure_name proc attribute(near/far)
.
.
.
procedure_name endp
</code></pre>
<p data-source-line="546">堆栈过程:<br>栈是一种先入后出的数据结构<br>pushf 的功能是将标志寄存器的值压栈</p>
<p data-source-line="550">十进制转十六进制和十六进制转十进制<br>十进制转十六进制:</p>
<pre data-source-line="552"><code class="hljs"><span class="hljs-comment">;_______________________________________________________________
code <span class="hljs-meta">segment
<span class="hljs-meta">assume <span class="hljs-built_in">cs:code
main proc <span class="hljs-built_in">far
<span class="hljs-keyword">call DecToBinary
<span class="hljs-keyword">call BinaryToHex
main endp
<span class="hljs-comment">;_______________________________________________________________
DecToBinary proc <span class="hljs-built_in">near <span class="hljs-comment">;<span class="zh-hans">十进制转二进制
<span class="hljs-keyword">mov <span class="hljs-built_in">bx,<span class="hljs-number">0 <span class="hljs-comment">;<span class="zh-hans">清空bx
<span class="hljs-symbol">input:
<span class="hljs-keyword">mov <span class="hljs-number">ah,<span class="hljs-number">1
<span class="hljs-keyword">int <span class="hljs-number">21h <span class="hljs-comment">;<span class="zh-hans">调用dos
<span class="hljs-keyword">sub <span class="hljs-built_in">al,<span class="hljs-number">30h <span class="hljs-comment">;<span class="zh-hans">转为二进制(通过ASCII<span class="zh-hans">)
<span class="hljs-keyword">jl exit <span class="hljs-comment">;<span class="zh-hans">如果小于0,<span class="zh-hans">退出
<span class="hljs-keyword">cmp <span class="hljs-built_in">al,<span class="hljs-number">9d <span class="hljs-comment">;<span class="zh-hans">如果大于9
<span class="hljs-keyword">jg exit <span class="hljs-comment">;<span class="zh-hans">直接退出
<span class="hljs-keyword">cbw <span class="hljs-comment">; <span class="zh-hans">把字节转换成字。AL<span class="zh-hans">的内容符号扩展到AH,<span class="zh-hans">形成AX<span class="zh-hans">中的字
<span class="hljs-comment">;<span class="zh-hans">当前数字在ax<span class="zh-hans">中
<span class="hljs-keyword">xchg <span class="hljs-built_in">ax,<span class="hljs-built_in">bx <span class="hljs-comment">;<span class="zh-hans">交换ax<span class="zh-hans">,bx<span class="zh-hans">中的数字,<span class="zh-hans">交换之后ax<span class="zh-hans">是0<span class="zh-hans">,bx<span class="zh-hans">是原来ax<span class="zh-hans">中的数字
<span class="hljs-keyword">mov <span class="hljs-built_in">cx,<span class="hljs-number">10d
<span class="hljs-keyword">mul <span class="hljs-built_in">cx
<span class="hljs-keyword">xchg <span class="hljs-built_in">ax,<span class="hljs-built_in">bx
<span class="hljs-comment">;<span class="zh-hans">把ax<span class="zh-hans">中的数字加到bx<span class="zh-hans">中
<span class="hljs-keyword">add <span class="hljs-built_in">bx,<span class="hljs-built_in">ax
<span class="hljs-keyword">jmp input
<span class="hljs-symbol">exit:
<span class="hljs-keyword">ret
DecToBinary endp
<span class="hljs-comment">;_______________________________________________________________
BinaryToHex proc <span class="hljs-built_in">near
<span class="hljs-keyword">mov <span class="hljs-number">ch,<span class="hljs-number">4<span class="hljs-comment">;cx<span class="zh-hans">高位设置为4
<span class="hljs-symbol">rotate:
<span class="hljs-keyword">mov <span class="hljs-built_in">cl,<span class="hljs-number">4 <span class="hljs-comment">;cx<span class="zh-hans">低位设置为4
<span class="hljs-keyword">rol <span class="hljs-built_in">bx,<span class="hljs-built_in">cl <span class="hljs-comment">;bx<span class="zh-hans">中的数左移4<span class="zh-hans">位
<span class="hljs-keyword">mov <span class="hljs-built_in">al,<span class="hljs-built_in">bl <span class="hljs-comment">;<span class="zh-hans">移到al
<span class="hljs-keyword">and <span class="hljs-built_in">al,<span class="hljs-number">0fh
<span class="hljs-keyword">add <span class="hljs-built_in">al,<span class="hljs-number">30h <span class="hljs-comment">;<span class="zh-hans">把十六进制转换成ASCII
<span class="hljs-keyword">cmp <span class="hljs-built_in">al,<span class="hljs-number">3ah <span class="hljs-comment">;<span class="zh-hans">判断是否大于9
<span class="hljs-keyword">jl print <span class="hljs-comment">;<span class="zh-hans">如果小于9<span class="zh-hans">直接输出
<span class="hljs-keyword">add <span class="hljs-built_in">al,<span class="hljs-number">7h<span class="hljs-comment">;A-F
<span class="hljs-symbol">
print:
<span class="hljs-keyword">mov <span class="hljs-built_in">dl,<span class="hljs-built_in">al <span class="hljs-comment">;<span class="zh-hans">把要打印的ASCII<span class="zh-hans">放到dl<span class="zh-hans">中
<span class="hljs-keyword">mov <span class="hljs-number">ah,<span class="hljs-number">2
<span class="hljs-keyword">int <span class="hljs-number">21h <span class="hljs-comment">;<span class="zh-hans">调用dos
<span class="hljs-keyword">dec <span class="hljs-number">ch
<span class="hljs-keyword">jnz rotate
<span class="hljs-keyword">ret
BinaryToHex endp
code ends
end main
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p data-source-line="614">十六进制转十进制:</p>
<pre data-source-line="615"><code class="hljs">code <span class="hljs-meta">segment
main proc <span class="hljs-built_in">far
<span class="hljs-meta">assume <span class="hljs-built_in">cs:code
<span class="hljs-symbol">star:
<span class="hljs-keyword">push <span class="hljs-built_in">ds
<span class="hljs-keyword">sub <span class="hljs-built_in">ax,<span class="hljs-built_in">ax
<span class="hljs-keyword">push <span class="hljs-built_in">ax
<span class="hljs-keyword">call hToB
<span class="hljs-keyword">call bTOD
<span class="hljs-keyword">jmp main
<span class="hljs-keyword">ret
main endp
<span class="hljs-comment">;____________________________________________
hToB proc <span class="hljs-built_in">near
<span class="hljs-symbol">newchar:
<span class="hljs-keyword">mov <span class="hljs-built_in">bx,<span class="hljs-number">0
<span class="hljs-keyword">mov,<span class="hljs-number">ah,<span class="hljs-number">1
<span class="hljs-keyword">int <span class="hljs-number">21h
<span class="hljs-keyword">sub <span class="hljs-built_in">al,<span class="hljs-number">30h<span class="hljs-comment">;ascii<span class="zh-hans">码转成二进制
<span class="hljs-keyword">jl exit
<span class="hljs-keyword">cmp <span class="hljs-built_in">al,<span class="hljs-number">10d <span class="hljs-comment">;<span class="zh-hans">是否大于9
<span class="hljs-keyword">jl add_to
<span class="hljs-keyword">sub <span class="hljs-built_in">al,<span class="hljs-number">27h<span class="hljs-comment">;ascii<span class="zh-hans">码转成二进制
<span class="hljs-keyword">cmp <span class="hljs-built_in">al,<span class="hljs-number">0ah
<span class="hljs-keyword">jl exit<span class="hljs-comment">;<span class="zh-hans">小于a<span class="zh-hans">则没有字母,直接跳出
<span class="hljs-keyword">cmp <span class="hljs-built_in">al,<span class="hljs-number">10h
<span class="hljs-keyword">jge exit
<span class="hljs-symbol">add_to:
<span class="hljs-keyword">mov <span class="hljs-built_in">cl,<span class="hljs-number">4
<span class="hljs-keyword">shl <span class="hljs-built_in">bx,<span class="hljs-built_in">cl
<span class="hljs-keyword">mov <span class="hljs-number">ah,<span class="hljs-number">0
<span class="hljs-keyword">add <span class="hljs-built_in">bx,<span class="hljs-built_in">ax
<span class="hljs-keyword">jmp newchar
<span class="hljs-symbol">exit:
<span class="hljs-keyword">ret
hToB endp
<span class="hljs-comment">;____________________________________________
bTOD proc <span class="hljs-built_in">near
<span class="hljs-keyword">mov <span class="hljs-built_in">cx,<span class="hljs-number">10000d
<span class="hljs-keyword">call dec_div
<span class="hljs-keyword">mov <span class="hljs-built_in">cx,<span class="hljs-number">1000d
<span class="hljs-keyword">call dec_div
<span class="hljs-keyword">mov <span class="hljs-built_in">cx,<span class="hljs-number">100d
<span class="hljs-keyword">call dec_div
<span class="hljs-keyword">mov <span class="hljs-built_in">cx,<span class="hljs-number">10d
<span class="hljs-keyword">call dec_div
<span class="hljs-keyword">mov <span class="hljs-built_in">cx,<span class="hljs-number">1d
<span class="hljs-keyword">call dec_div
<span class="hljs-keyword">ret
<span class="hljs-comment">;____________________________________________
dec_div proc <span class="hljs-built_in">near
<span class="hljs-keyword">mov <span class="hljs-built_in">ax,<span class="hljs-built_in">bx <span class="hljs-comment">;<span class="zh-hans">低位
<span class="hljs-keyword">mov <span class="hljs-built_in">dx,<span class="hljs-number">0 <span class="hljs-comment">;<span class="zh-hans">高位置0
<span class="hljs-keyword">div <span class="hljs-built_in">cx
<span class="hljs-keyword">mov <span class="hljs-built_in">bx,<span class="hljs-built_in">dx
<span class="hljs-keyword">mov <span class="hljs-built_in">dl,<span class="hljs-built_in">al<span class="hljs-comment">;<span class="zh-hans">要输出的放入dl<span class="zh-hans">中
<span class="hljs-keyword">add <span class="hljs-built_in">dl,<span class="hljs-number">30h <span class="hljs-comment">;<span class="zh-hans">转换成ascii
<span class="hljs-keyword">mov <span class="hljs-number">ah,<span class="hljs-number">2
<span class="hljs-keyword">int <span class="hljs-number">21h
<span class="hljs-keyword">ret
dec_div endp
<span class="hljs-comment">;____________________________________________
bTOD endp
code ends
end start
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<hr><hr><hr>
<h2 id="第七章" data-source-line="690">第七章</h2>
<h3 id="宏定义" data-source-line="691">宏定义</h3>
<h4 id="宏定义-宏调用-宏展开" data-source-line="692">宏定义、宏调用、宏展开</h4>
<ol data-source-line="693">
<li>定义:<br>macro_name macro 宏定义名 macro 哑元表(形参) · · · endm</li>
<li>调用<br>macro_name </li>
</ol>
<p data-source-line="704">宏定义体=>复制到宏定义位置</p>
<blockquote data-source-line="705">
<p>&操作符<br>展开时可以把&前后两个符号合并形成一个符号,这个符号可以是操作码、操作数或者一个字符串</p>
</blockquote>
<blockquote data-source-line="708">
<p>%expresion<br>把跟在%之后的表达式的值转换成当前基数下的数,在展开期间用这个数取代哑元</p>
</blockquote>
<h4 id="宏库的调用" data-source-line="711">宏库的调用</h4>
<p data-source-line="712">扩展名为.MAC或者.INC 引用格式:</p>
<blockquote data-source-line="714">
<p>include c:\macro.mac</p>
</blockquote>
<p data-source-line="716">子程序与宏定义的区别:<br>使用子程序,需要为转子和返回、保存和恢复寄存器以及参数的传递等增加程序的额外开销,子程序是在程序运行期间由主程序调用的,他只占有自身大小的一个空间;而宏调用是在汇编期间展开的,每调用一次都把宏展开一次因而占用空间与调用次数有关,次数越多占用空间越大。</p>
<hr><hr><hr>
<h2 id="第八章" data-source-line="721">第八章</h2>
<h3 id="中断" data-source-line="722">中断</h3>
<p data-source-line="723">软件中断:</p>
<ol data-source-line="724">
<li>由中断指令引起</li>
<li>由于cpu某些错误引起</li>
<li>为调试程序debug设置的中断</li>
</ol>
<p data-source-line="728">硬件中断:</p>
<ol data-source-line="729">
<li>非屏蔽中断</li>
<li>来自外部设备的中断(可屏蔽中断)</li>
</ol>
<p data-source-line="732">FLAGS中:IF=1 允许中断,IF=0 不允许中断</p>
<p data-source-line="734">STI:IF置1<br>CLI:IF置0</p>
<blockquote data-source-line="737">
<p>中断号*4 -> 偏移地址 -> 下一个字 段地址</p>
</blockquote>
<p data-source-line="739">中断过程:</p>
<ol data-source-line="740">
<li>取中断号N</li>
<li>标志寄存器flags入栈</li>
<li>代码段寄存器cs入栈</li>
<li>指令计数器ip入栈</li>
<li>IF=0,TF=0</li>
<li>从中断向量表取4 * N的字内容送ip,取4 * N + 2中的字送cs</li>
<li>转中断处理程序</li>
</ol><hr><hr><hr>
<h2 id="第九章" data-source-line="752">第九章</h2>
<blockquote data-source-line="753">
<p>1号功能<br>从键盘输入一个字符并回显在屏幕上 al=字符</p>
</blockquote>
<blockquote data-source-line="756">
<p>2号功能<br>显示器输出,要输出的字符放在dl中</p>
</blockquote>
<blockquote data-source-line="759">
<p>9号功能<br>显示字符串,DS:DX=串地址,必须要$结尾</p>
</blockquote>
<blockquote data-source-line="762">
<p>A号功能<br>键盘输入到缓冲区,DS:DX缓冲区首地址,DS:DX+1=实际输入的字符</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/TheSilverMoon/p/10957476.html
頁:
[1]