注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

编程学习

我的网上家园

 
 
 

日志

 
 

《x86汇编语言:从实模式到保护模式》检测点与习题答案  

2013-03-15 16:36:40|  分类: 《x86汇编语言: |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
    检测点 1.1 
将下列二进制数转换成十进制数: 
1101、1111、1001110、11111111、10000000、1101101100011011 

答案:
13,15,78,255,128,56091

 检测点 1.2 
将下列十进制数转换成二进制数: 
8、10、12、15、25、64、100、255、1000、65535、1048576 

答案:
1000,1010,1100,1111,11001,1000000,1100100,11111111,1111101000,1111111111111111,100000000000000000000


 检测点 1.3 
将下列十六进制数转换成十进制数: 
8、A、B、C、D、E、F、10、1F、6CD、3FE、FFC、FFFF 

答案: 8,10,11,12,13,14,15,16,31,1741,1022,4092,65535

 检测点 1.4 
将下列十进制数转换成十六进制数: 
8、10、12、15、25、64、100、255、1000、65535、1048576 
答案: 8,A,C,F,19,40,64,FF,3E8,FFFF,100000

 检测点 1.5 
 略
 检测点 1.6 
 略

 习题:
 略,自己用 windows 计算器验证一下就可以了.


 检测点 2.1 
1.  一个字含有(  2  )个字节和(  16  )比特?一个双字含有(  4  )个字节、(  2  )个字和
(   32 )个比特? 
2.  二进制数 10000000 中,位(  7    )的那个比特是“1”,也就是第(   8   )位。它是最低位
还是最高位?  最高位
3.  一个存储器的容量是  16  个字节,地址范围为(  00H    )~(  0FH    )。用该存储器保存字数据
时,可存放(   8   )个字,这些字的地址分别是(  00H,02H,04H,06H,08H,0AH,0CH,0EH  ),保存双字呢? 
00H,04H,08H,0CH

检测点 2.2 
在内存中,指令和数据一模一样,都是无差别的数。如图  2-6  所示,假如处理器访问内存时
是按低端字节序的,那么,从地址 0008H 处取出一个字时,该字的值为( A3D8 H     )
 

 检测点 2.3 
1.INTEL  8086  处理器有(  8  )个 16  位通用寄存器,分别是( ax bx cx dx si di bp sp        )。其中,
有些还可以分开来作为两个独立的 8 位寄存器来用,这几个 8 位寄存器分别是( ah al bh bl ch cl dh dl  )。 
2.选择题(可多选):INTEL  8086  处理器取指令时,使用段寄存器( A   )和指令指针寄存器
(  C  )。方法是,将段寄存器的值( D F   ),加上指令指针寄存器的当前值,形成物理地址访问内存。 
A.CS    B.DS    C.IP    D.左移 4 位    E.右移 4 位    F.乘以 16    G.除以 10H 
3.物理地址 132FEH 对应的逻辑地址是(可多选): A B C D F
A.132FH:000EH        B.1300H:02FEH      C.1000H:32FEH      D.1320H:00FEH 
E.102FH:03E0H        F.0FE0H:34FEH 

习题:
1.在段与段之间互不重叠的前提下,1MB 内存可以完整地划分为多少个16KB 的段?
不重叠,1M/16KB= 64
2.数据段寄存器 DS 的值为25BCH 时,计算 Intel 8086可以访问的物理地址范围。
25BC0+0 ~ 25BC0+FFFF ==> 25BC0H ~ 35BBFH

检测点3.1 
1.  更正错误,应该是图3-1 ,而不是图3-10 
2.  选择填空:指令  mov  ax,0xf5fc  中,“mov”指示这是一条(  B传送   )指令,0xf5fc  是
(   A 立即数   )。指令执行后,寄存器 AX 中的内容是( C    )。 
A.立即数    B.传送    C.0xf5fc    D.加法    E.0xfcf5    F.寄存器 


习题: 
如图 3-6 所示,请问: 
(1)源程序共有 3 行,每一行第一个字符在文件内的偏移量分别是多少? 
 按书中图示,图3-6中,每一行第一个字符在文件内的偏移量分别是: 0x0,0x35,0x40
 分析: 第一行,第一个字符是 m (mov ax,0x3f) ,右边的字符与左边的二进制是一一对应的,它是第一个,偏移是0
第二行,第一个字符是 a (add bx,ax) ,查看右边的字符,是第6个,再来看最左边的十六进制行首偏移是0x30,
0x30+6-1=0x35 偏移是从0开始计算的.

(2)该源程序文件的大小是多少字节? 
 0x48


 检测点 4.1 
1.  硬盘的磁头(盘面)是从数字( 0  )开始编号的;每个盘面磁道是从数字( 0  )开始编
号的;每磁道/柱面上的扇区是从数字(  1 )开始编号的,主引导扇区的位置是(  0  )面
(  0  )道(  1  )扇区; 
2.  如果希望处理器从当前位置转移到物理地址  0xc5030  处开始执行,可以使用下面的哪些
指令(可多选): A B C D
A. jmp 0xc000:0x5030    B. jmp 0xc500:0x0030 
C. jmp 0xc503:0x0000    D. jmp 0xbb00:0xa030 

检测点 4.2 
1.  运行 NASMIDE 程序,输入以下汇编指令并保存为文件 4-2.asm(不要考虑这些指令的含
义和功能): 
mov ax,0xb800 
mov ds,ax 
mov [0x00],’a’ 
mov [0x02],’s’ 
mov [0x04],’m’ 
jmp $ 

times 510-($-$$) db 0
db 0x55,0xaa

修正: 添加上面两行代码,以补全程序


2.  将上面的  4-2.asm  文件编译,得到二进制文件  4-2.bin,并写入虚拟硬盘的主引导扇区。
注意,该虚拟硬盘应当是 VirtualBox 虚拟机的启动硬盘。 
3.  启动你的  VirtualBox  虚拟机。当虚拟机启动时,会像真实的计算机一样加载硬盘上的主
引导扇区代码,并执行。此时,注意观察屏幕上都显示了什么内容。 



检测点 5.1 
1.在我们日常使用的个人计算机上,文本模式下的显示缓冲区被映射到物理内存地址空间,
起始地址为(  0xb8000         ),它对应的段地址为(  0xb800    )。在标准的 80×25 文本模式下,要想在屏幕
右下角显示一个绿底白字的字符“H”,那么,应当在该段内偏移量为(   3998 ,十六进制 F9EH    )的地方开始,连
续写入两个字节(    0x48        )和(     0x27      )。 
2.以下指令中,哪些是正确的,不正确的原因是什么? E F H J L
A.mov al,0x55aa        B.mov ds,0x6000        C.mov ds,al   
D.mov [0x06],0x55aa     E.mov ds,bx            F.mov ax,0x02   
G.mov word [0x0a],ax    H.mov es,cx            I.mov ax,bl   
J.mov byte [0x00],’c’    K.mov [0x02],[0xf000]   L.mov ds,[0x03] 

不正确原因: A,al是8位寄存器,0x55aa是16位立即数 B,不允许把立即数传送到段寄存器 C,al是8位寄存器,DS段寄存器是16位
D,没有说明立即数大小,应该加上 word 修饰词,以说明立即数大小 G,ax是16位寄存器,无须再加word修饰词
I,ax跟bl大小不同  K,不可以在内存单元之间直接传送

检测点 5.2 
找出下面代码片断中的错误。用 nasmide 程序实际编译一下,看看结果如何。 
data1 db 0x55,0xf000,0x0f 
data2 dw 0x38,0x20,0x55aa 

0xf000 超过了字节大小,导致编译器只截取了低8位,高8位,0xf0丢弃.


检测点 5.3 
1.INTEL  x86  处理器访问内存时,是按低端字节序进行的。那么,以下程序片断执行后,寄
存器 AX 中的内容是多少? 
           mov word [data],0x2008 
           xor byte [data],0x05 
           add word [data],0x0101 
           mov ax,[data] 
     data db 0,0 

AX=210E

2.对于以上程序片断,如果标号 data  在编译时的汇编地址是 0x0030,那么,当该程序加载
到内存后,该程序片断所在段的段地址为 0x9020 时,该标号处的段内偏移地址和物理内存地址各
是多少? 

标号处的段内偏移地址是 0x0030 物理内存地址是 0x90230

3.对于以下指令的写法,说出哪些是正确的,哪些是错误的,错误的原因是什么。 
  A.mov ax,[data1]         B.div [data1]       C.xor ax,dx 
D.div byte [data2]      E.xor al,[data3]     F.add [data4],0x05  
G.xor 0xff,0x55        H.add 0x06,al       I.div 0xf0 
J.add ax,cl   

正确: A C D E 
错误: B,没有byte或word指示大小 F,没有指定数据大小 G,两个立即数不能参与运算
H,目的操作数不能是立即数 I,不可以除立即数 J,两个操作数大小不相同



4.如果寄存器 AX、BX 和 DX 的内容分别为 0xA000、0x9000 和 0x0001,那么,执行 div  bh
后,这三个寄存器的内容各是多少?执行 div bx 后呢? 

div bh,商在AL  余数在AH 0xa000/0x90 结果会溢出. BX DX值不变
div bx,dx:ax/bx=0x0001a000/0x9000 BX值不变. AX=商=2 DX=余数=0x8000


 检测点 5.4 
写出以下程序片断中那两条 JMP 指令的机器指令码,并在 NASMIDE 中编译验证你的答案是
否正确: 
jmp near start     (  0xe90200            ) 
  data   db 0x55,0xaa 
start: mov ax,0 
        jmp 0x2000:0x0005  ( 0xea05000020    ) 



习题: 
1.试找出以下程序片断中隐藏的问题并进行修正: 
mov ax,21015 
mov bl,10 
div bl 
and cl,0xf0 

div bl会发生溢出.
mov ax,21015
mov dx,0
mov bl,10
div bx
and cl,0xf0

2.本章的程序在内存中的加载地址是 0x0000:0x7C00,此时,指令 jmp  near  infi 在段内的偏
移地址是多少?试修改本章的源程序以显示该值。 

把 mov ax,number 修改一下即可以达到目的. mov ax,infi   

注意,只改成 mov ax,infi是从0开始计算偏移的,如果要从0X7C00开始计算偏移,需要加一条指令
add ax,0x7c00  同时修改 times 后面的数值,以保证编译出的文件正好是512字节.

3.汇编语言编译器采用助记符来方便指令的书写和阅读。比如,mov  是传送指令,div  是除
法指令。假如 Intel 公司新推出一款处理器,该处理器新增了一条指令,其机器码为 CD  88。因为
是新指令,你的 NASM  编译器肯定没有一个助记符与之相对应。在这种情况下,如何在你的程序
中使用该指令? 

在这种情况下,可以使用 db 伪指令来达到目的. db 0xcd 0x88 ,编译器会直接使用给定的数值.


检测点 6.1 
选择填空:MOVSB  指令每次传送一个( 字节  ),MOVSW  指令每次传送一个( 字  )。原始数据
在段内的偏移地址在寄存器( Si  )中,要传送的目标位置的偏移地址在寄存器( DI  )中。如果要
连续传送多个字或字节,则需要( REP  )前缀,在寄存器( CX  )中设置传送的次数,并设置传送的
方向。其中,( CLD  )指令指示正向传送,( STD  )指令指示反向传送。反向传送时,每传送一次,SI
和 DI 的内容将( 减小   )。 
A.字节    B.字    C.di    D.si    E.cx    F.rep    G.减小    H.std    I.cld    J.增大


检测点 6.2 
选择题:下面哪些指令是错误的,为什么? 
A.add ax,[bx]    B.mov ax,[si]    C.mov ax,[cx]    D.mov dx,[di]   
E.mov dx,[ax]    F.inc byte [di]  G.div word [bx] 

C,cx不能用作偏移 E,ax也不能用作偏移 


检测点 6.3 
假如以下声明的是有符号数,那么,其中的负数是( 0xf0,0xff,0x81,0xffff,0x8a08         )。 
data0 db 0xf0,0x05,0x66,0xff,0x81 
data1 dw 0xfff,0xffff,0x8b,0x8a08


 检测点 6.4 
1.ZF 标志位和与该标志位有关的条件转移指令用得非常频繁,但很多人容易在 ZF 标志位上
犯糊涂,以为计算结果为零时,ZF  为“0”。为了证明你不糊涂,请填空:当 ZF=( 1 )
时,表明计算结果为零;jz  指令的意思是当 ZF=( 1 ),即计算结果为( 0 )时转移;je  指
令的意思是当 ZF=( 1 ),即计算结果为(0  )时转移;jnz 指令的意思是当 ZF=( 0 ),即计
算结果不为(0 )时转移;jne 指令的意思是当 ZF=(0 ),即计算结果不为(0 )时转移。 

2.写一小段程序,先比较寄存器 AX 和 BX 中的数值,然后,当 AX 的内容大于 BX 的内容
时,转移到标号 lbb 处执行;AX 的内容等于 AX 的内容时,转移到标 lbz 处执行;AX 的
内容小于 BX 的内容时,转移到标号 lbl 处执行

cmp ax,bx
ja lbb       (有符号数比较使用 jg)
jz lbz
jb lbl       (有符号数比较使用 jl)
lbb:
...
lbz:
...
lbl:


习题:
1.在某程序中声明和初始化了以下的有符号数。请问,正数和负数各有多少? 
data1 db 0x05,0xff,0x80,0xf0,0x97,0x30 
data2 dw 0x90,0xfff0,0xa0,0x1235,0x2f,0xc0,0xc5bc 

正数: 0x05,0x30 0x90,0xa0,0x1235,0x2f,0xc0
负数: 0xff,0x80,0xf0,0x97 0xfff0,0xc5bc

2.如果可能的话,尝试编写一个主引导扇区程序来做上面的工作。

一个数是正数还是负数,在数据宽度不同时,解释也是不同的.
比如: 0x0090,以字单位读取时,高位是0,所以是正数,如果以字节读取,变成0x90,
高位是1,这是个负数.

这个留给读者自己想办法编程实验吧.
 
3.请问下面的循环将执行多少次: 
         mov cx,0 
delay: loop delay 

循环 65536次


 检测点 7.1 
1. 以下指令执行后,寄存器 AX 中的内容是多少? 
mov ax,0xfff0 
and [data],ax 
or ax,[data] 
data db 0x55,0xaa 

ax=FFF0

2. 下面的说法中哪些是正确的? A B C
A.8086 处理器执行压栈操作时,是先将 SP 的内容减 2,再访问栈段。 
B.8086 处理器执行出栈操作时,是先将 SP 的内容加 2,再访问栈段。 
C.如果 SP 的内容为 0xFFFC,则执行 push ax 后,SP 的内容变为 0xFFFA。 


3. 在空白处补充指令或指令的操作数,使得程序可以把栈段当成数据段访问,并在寄存器
DX 中得到 AX 的压栈值。 
push ds         ;保护本次操作之前的 DS 
push bx         ;保护本次操作之前的 BX 
push ax 
mov bx,___  ss
      mov ds  ______,bx 
mov bx,sp 
___________ mov dx,[bx]
pop ax 
pop bx         ;恢复本次操作之前的 BX 
pop ds         ;恢复本次操作之前的 DS 




本  章  习  题 
1.修改代码清单 7-1 的第 31~37 行,使用 loop 指令来计算累加和。要求:CX 寄存器既用来
控制循环次数,同时还用来作为被累加的数。 

xor ax,ax
mov cx,100
@f:
add ax,cx
loop @f



2.在 16  位的处理器上,做加法的指令是 add,但它每次只能做 8  位或 16  位的加法。除此之
外,还有一个带进位加法指令adc(Add With Carry),它的指令格式和add 一样,目的操作数可以是
8 位或 16 位的通用寄存器和内存单元,源操作数可以是与目的操作数宽度一致的通用寄存器、内存
单元和立即数(但目的操作数和源操作数同为内存单元的除外)。不过,adc  指令在执行的时候,除
了将目的操作数和源操作数相加,还要加上当前标志寄存器的 CF 位。也就是说,视 CF 位的状态,
还要再加0 或者加1。这样一来,用adc 指令配合add 指令,就可以计算16 位以上的加法。 
adc 指令对 OF、SF、ZF、AF、CF 和 PF 的影响视计算结果而定。 
现在,请编写一段主引导扇区程序,计算 1 到 1000 的累加和,并在屏幕上显示结果。


jmp start
message: db '1+2+3+...+1000='
start:
xor ax,ax
mov ss,ax
mov sp,0x7c00
mov bx,0x7c0
mov ds,bx
mov bx,0xb800
mov es,bx
mov si,message
xor di,di
mov cx,start-message
mov bh,10
@s:
mov bl,[si]
mov [es:di],bx
add di,2
inc si
loop @s

mov cx,1000
xor dx,dx
@1:
add ax,cx
adc dx,0
loop @1

;dx:ax 中为1+2+3+...+1000的结果

mov bx,10
@2:
div bx
add dx,0x30
push dx
inc cx
or ax,ax
jz @3
xor dx,dx
jmp @2

@3:
pop dx
mov [es:di],dl
mov byte [es:di+1],10
add di,2
loop @3

jmp $

times 510-($-$$) db 0
db 0x55,0xaa















  评论这张
 
阅读(2997)| 评论(2)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017