王爽汇编语言答案(1-4)
<h1 id="王爽汇编语言答案1-4章">王爽汇编语言答案(1-4章)</h1><h2 id="检测点">检测点</h2>
<h3 id="chapter1">chapter1</h3>
<h4 id="检测点11">检测点1.1</h4>
<p>(1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为<strong>13</strong>。<br>
(2)1KB的存储器有个存储单元。存储单元的编号从<strong>0000</strong>到<strong>1023</strong>。<br>
(3)1KB的存储器可以存储个<strong>8192</strong>bit,<strong>1024</strong>个Byte。<br>
(4)1GB、1MB、1KB分别是<strong>2^30 , 2^20 , 2^10</strong>Byte。<br>
(5)8080、8088、80286、80386的地址总线宽度分别为16根、20根、24根、32根,则它们的寻址能力分别为:<strong>64</strong>(KB)、<strong>1</strong>(MB)、<strong>16</strong>(MB)、<strong>4</strong>(GB)。<br>
(6)8080、8088、8086、80286、80386的数据总线宽度分别为8根、8根、16根、16根、32根则它们一次可以传送的数据为:<strong>1(B)、1(B)、2(B)、2(B)、4(B)</strong>。<br>
(7)从内存中读取1024字节的数据,8086至少要读<strong>512</strong>次,80386至少要读<strong>256</strong>次。<br>
(8)在存储器中,数据和程序以形式<strong>二进制</strong>存放。</p>
<h3 id="chapter2">chapter2</h3>
<h4 id="检测点21">检测点2.1</h4>
<p>1.写出每条汇编指令执行后相关寄存器中的值。</p>
<table>
<thead>
<tr>
<th>指令</th>
<th>寄存器</th>
</tr>
</thead>
<tbody>
<tr>
<td>mov ax, 62627</td>
<td>AX = F4A3H</td>
</tr>
<tr>
<td>mov ah, 31H</td>
<td>AX = 31A3H</td>
</tr>
<tr>
<td>mov al, 23H</td>
<td>AX = 3123H</td>
</tr>
<tr>
<td>add ax, ax</td>
<td>AX = 6246H</td>
</tr>
<tr>
<td>mov bx, 826CH</td>
<td>BX = 826CH</td>
</tr>
<tr>
<td>mov cx, ax</td>
<td>CX = 6246H</td>
</tr>
<tr>
<td>mov ax, bx</td>
<td>AX = 826CH</td>
</tr>
<tr>
<td>add ax, bx</td>
<td>AX = 04D8H</td>
</tr>
<tr>
<td>mov al, bh</td>
<td>AX = 0482H</td>
</tr>
<tr>
<td>mov ah, bl</td>
<td>AX = 6C82H</td>
</tr>
<tr>
<td>add ah, ah</td>
<td>AX = D882H</td>
</tr>
<tr>
<td>add al, 6</td>
<td>AX = D888H</td>
</tr>
<tr>
<td>add al, al</td>
<td>AX = D810H</td>
</tr>
<tr>
<td>mov ax, cx</td>
<td>AX = 6246H</td>
</tr>
</tbody>
</table>
<ol start="2">
<li>只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方。</li>
</ol>
<pre><code>mov ax, 2;ax = 2
add ax, ax ;ax = 4
add ax, ax ;ax = 8
add ax, ax ;ax = 16
</code></pre>
<h4 id="检测点22">检测点2.2</h4>
<p>(1)给定段地址为0001H,仅通过变化偏移地址寻址,CPU的寻址范围为<strong>00010H</strong>到<strong>1000FH</strong>。<br>
(2)有一数据存放在内存20000H单元中,现给定段地址为SA,若想用偏移地址寻到此单元。则SA应满足的条件是:最小为<strong>1001H</strong>,最大为<strong>2000H</strong>。</p>
<h4 id="检测点23">检测点2.3</h4>
<p>下面的3条指令执行后,CPU几次修改IP?都是在什么时候?最后IP中的值是多少?</p>
<pre><code>mov ax, bx
sub ax, ax
jmp ax
</code></pre>
<p>**共计4次修改IP的值:</p>
<ol>
<li>mov ax, bx 指令加载至指令缓冲器后</li>
<li>sub ax, ax 指令加载至指令缓冲器后</li>
<li>jmp ax 指令加载至指令缓冲器后</li>
<li>jmp ax 执行后,IP变为0000H**</li>
</ol>
<h3 id="chapter3">chapter3</h3>
<h4 id="检测点31">检测点3.1</h4>
<ol>
<li>在Debug中,用“d 0:0 1f”查看内存,结果如下:</li>
</ol>
<pre><code>0000:0000 70 80 f0 30 EF 60 30 E2-00 80 80 12 66 20 22 60
0000:0010 62 26 E6 D6 CC 2E 3C 3B-AB BA 00 00 26 06 66 88
</code></pre>
<p>下面的程序执行前,AX=0,BX=0,写出每条汇编指令执行完后相关寄存器中的值。</p>
<p>|指令|寄存器|<br>
|-|-|-|<br>
| mov ax, 1 ||<br>
| mov ds, ax ||<br>
| mov ax, | AX=2662H |<br>
| mov bx, | BX=E626H |<br>
| mov ax, bx | AX=E626H |<br>
| mov ax, | AX=2662H |<br>
| mov bx, | BX=D6E6H |<br>
| add ax, bx | AX=FD48H |<br>
| add ax, | AX=2C14H |<br>
| mov ax, 0 | AX=0000H |<br>
| mov al, | AX=00E6H |<br>
| mov bx, 0 | BX=0000H |<br>
| mov bl, | BX=0026H |<br>
| add al, bl | AX=000CH |</p>
<ol start="2">
<li>内存中的情况如图所示<br>
<img src="https://img2020.cnblogs.com/blog/2001073/202104/2001073-20210413211257330-1575235217.png"></li>
</ol>
<p>各寄存器的初始值:CS=2000H,IP=0,DS=1000H,AX=0,BX=0;</p>
<ol>
<li>写出CPU执行的指令序列(用汇编指令写出)。</li>
<li>写出CPU执行每条指令后,CS、IP和相关寄存器中的数值。</li>
<li>再次体会:数据和程序有区别吗?如何确定内存中的信息哪些是数据,哪些是程序?</li>
</ol>
<pre><code>mov ax,6622H;CS= 2000H IP= 0003H AX= 6622H
jmp 0ff0:0100 ;CS= 0fff0 IP= 0100H
mov ax,2000H;CS= 0fff0 IP= 0103H AX= 2000H
mov ds,ax ;CS= 0fff0 IP= 0105H DS= 2000H
mov ax, ;CS= 0fff0 IP= 0108H AX= C389H
mov ax, ;CS= 0fff0 IP= 010BH AX= 6622H
</code></pre>
<p>程序和数据没有区别,都是在内存单元中的二进制码。当内存单元被CS:IP指定时其存储的就被当做程序执行。当内存单元被DS:偏移地址指定时其存储的就是数据。</p>
<h4 id="检测点32">检测点3.2</h4>
<p>1.补全下面的程序,使其可以将10000H<sub>1000FH中的8个字,逆序复制到20000H</sub>2000FH中。</p>
<pre><code class="language-c">mov ax, 1000H
mov ds, ax
mov ax, 2000H
mov ss, ax
mov sp, 0010H
push
push
push
push
push
push
push
push
</code></pre>
<p>2.补全下面的程序,使其可以将10000H<sub>1000FH中的8个字,逆序复制到20000H</sub>2000FH中。</p>
<pre><code class="language-c">mov ax, 2000H
mov ds, ax
mov ax, 2000H
mov ss, ax
mov sp, 0010H
pop
pop
pop
pop
pop
pop
pop
pop
</code></pre>
<h2 id="实验">实验</h2>
<h3 id="实验1-查看cpu和内存用机器指令和汇编指令编程">实验1 查看CPU和内存,用机器指令和汇编指令编程</h3>
<h4 id="debug的使用">Debug的使用</h4>
<p>什么是Debug:<br>
Debug是DOS、Windows都提供的实模式(8086方式)程序的调试工具。使用它,可以查看CPU各种寄存器中的内容、内存的情况和在机器码级跟踪程序的运行。</p>
<p>Debug的命令:</p>
<ol>
<li>用Debug的R命令查看、改变CPU寄存器的内容;</li>
<li>用Debug的D命令查看内存中的内容;</li>
<li>用Debug的E命令改写内存中的内容;</li>
<li>用Debug的U命令将内存中的机器指令翻译成汇编指令;</li>
<li>用Debug的T命令执行一条机器指令;</li>
<li>用Debug的A命令以汇编指令的格式在内存中写入一条机器指令。<br>
Debug的命令比较多,共有20多个,但这6个命令是和汇编学习密切相关的。</li>
</ol>
<p>如何进入Debug:<br>
现在通过其他的虚拟机方式,还原到窗口并不现实,相当麻烦,这里采用Dosbox模拟运行。</p>
<p>具体搭建可见,不是我写的。</p>
<p>关于dubug更详细的操作可以看原书,或者下载非整书,截取了debug部分的内容,提取码<strong>za88</strong>。</p>
<p><strong>注意在debug中,所有的数字均为16进制表示,mov ax,1839后,ax就为1893</strong></p>
<p>第一个小实验<br>
<img src="https://img2020.cnblogs.com/blog/2001073/202104/2001073-20210413172218751-1190044900.png"></p>
<p><img src="https://img2020.cnblogs.com/blog/2001073/202104/2001073-20210413172228539-59728738.png"></p>
<p><img src="https://img2020.cnblogs.com/blog/2001073/202104/2001073-20210413172234772-1435777782.png"></p>
<p><img src="https://img2020.cnblogs.com/blog/2001073/202104/2001073-20210413172244084-1193167478.png"></p>
<p>第三个小实验<br>
会发现内容无法更改图中红圈所示。<br>
<img src="https://img2020.cnblogs.com/blog/2001073/202104/2001073-20210413172338534-1253824598.png"></p>
<p>第四个小实验<br>
e命令选的内存为显存内存,DOS界面被更改。<br>
<img src="https://img2020.cnblogs.com/blog/2001073/202104/2001073-20210413172412201-1050148026.png"></p>
<h3 id="实验2-用机器指令和汇编指令编程">实验2 用机器指令和汇编指令编程</h3>
<ol>
<li>修改SS寄存器<br>
在debug中单步执行以下程序:</li>
</ol>
<pre><code>mov ax,1000H
mov ss,ax
mov bx,8945H
mov sp,2834H
</code></pre>
<p>我们发现,在执行了<code>mov ss, ax</code>后,直接转向执行<code>mov sp, 2834H</code>,观察bx的值,我们发现<code>mov bx, 8945H</code> 已经被执行过了。不单是mov ss,ax,对如mov ss,bx,mov ss,,pop ss等指令都会发生上面的情况,这些指令有哪些共性呢?它们都是修改栈段寄存器ss的指令。产生该现象是由于中断机制的原因,这部分内容将会在后面详细说明。<br>
<img src="https://img2020.cnblogs.com/blog/2001073/202104/2001073-20210415161833606-1121009629.png"></p>
<ol start="2">
<li>使用Debug,将下面的程序段写入内存,逐条执行,根据指令执行后的实际运行情况填空。</li>
</ol>
<pre><code>mov ax, ffff
mov ds, ax
mov ax, 2200
mov ss, ax
mov sp, 0100
mov ax, ;ax= c0ea
add ax, ;ax= c0fc
mov bx, ;bx= 30f0
add bx, ;bx= 6021
push ax ;sp=00fe
push bx ;sp=00fc
pop ax ;sp=00fe ;ax=6021
pop bx ;sp=0100 ;bx=c0fc
push ;sp=00fe
push ;sp=00fc
</code></pre>
<ol start="3">
<li>仔细观察图中程序,思考为什么2000:0~f内存会发生变化。<br>
<img src="https://img2020.cnblogs.com/blog/2001073/202104/2001073-20210415162056352-1021456266.png"></li>
</ol>
<p>通过观察我们可以很明显的发现从内存高位到低位,第2个字的位置储存了CS寄存器中的值,第3个字的位置储存了IP寄存器中的值,而第5个字的位置很有可能储存了AX寄存器中的值,或者SS寄存器,为了验证我们的猜想,我们换一块位置写我们的程序,并且在之前给BX和CX都赋值。<br>
<img src="https://img2020.cnblogs.com/blog/2001073/202104/2001073-20210415161956775-363755582.png"></p>
<p>通过观察可以发现,确实是和bx和cx无关,关于CS和IP寄存器猜想是正确的,5个字中保存了SS寄存器的值。造成这个原因的,应该是修改SS寄存器中断机制的原因。</p>
<h3 id="实验3--编程编译连接跟踪">实验3编程、编译、连接、跟踪</h3>
<ol>
<li>将下面的程序保存为 t1.asm文件,将 其生成可执行文件 t1.exe</li>
<li>用debug跟踪t1.exe的执行过程</li>
<li>PSP的头两个字是CD 20,用debug查看PSP的内容</li>
</ol>
<pre><code>assume cs : codesg
codesg segment
mov ax, 2000H
mov ss, ax
mov sp, 0
add sp, 10
pop ax
pop bx
push ax
push bx
pop ax
pop bx
mov ax, 4c00H
int 21H
codesgends
end
</code></pre>
<p>执行过程</p>
<pre><code>mov ax, 2000H ; ax=2000
mov ss, ax ; ss=2000
mov sp, 0 ; sp=0000
add sp, 10 ; sp=000A
pop ax ; sp=000C ax=0000
pop bx ; sp=000E bx=0000
push ax ; sp=000C
push bx ; sp=000A
pop ax ; sp=000C
pop bx ; sp=000E
mov ax, 4c00H ; ax=4C00
int 21H ;
修改SS,中断并未影响栈
查看PSP d DS:0000
</code></pre><br><br>
来源:https://www.cnblogs.com/cs-Miscellaneous/p/14654317.html
頁:
[1]