中山大学本科生期末考试
考试科目:《汇编与接口》(A卷)
学年学期:2014-2015学年第三学期姓名:
学院/系:信科院计算机系学号:
考试方式:开卷年级专业:
考试时长:120分钟班别:
“考试作弊者,不授予学士学位。”------------以下为试题区域,共三道大题,总分100分,考生请在答题纸上作答------------ 一、填空题(共15小题,每小题2分,共30分)
1.Intel的16位CPU中的程序状态字PSW寄存器为___、程序计数器PC为___。
2.Intel 酷睿i系列CPU的字长为___位、地址总线宽___位。
3.在Intel x86处理器的实模式下,地址线为___位、可寻址的空间大小为___。
4.Intel 80386新增加的两个段寄存器分别为___和___。
5.在NASM中定义数据的两类汇编指令分别为___和___。
6.在NASM中$和$$分别表示___和___。
7.将AL赋值给AX的CPU指令为___,使32位通用寄存器值的字节反序的CPU指令为___。8.PC机中的中断控制器和可编程计时器的型号分别为___和___。
9.Intel处理器实模式下的中断向量表包含___个中断向量,每个中断向量有___字节。
10.IA-32中的描述符和选择符大小分别为___位和___位。
11.段选择符的低三位全为0表示___,全为1表示___。
12.启动PC机的分页机制所涉及的两个控制寄存器分别为___和___。
13.打开和关闭可屏蔽中断的CPU指令分别为___和___。
14.IDT的英文原文是___,中文译文为___。
15.PC机的键盘接口芯片和DMA控制芯片的型号分别为___和___。
二、简答题(共6小题,每小题5分,共30分)
1.Intel 8086 CPU有哪些通用寄存器?给出它们的名称含义和功用。
2.
●给出NASM和MASM的英文原文和中文译文,它们有哪些主要区别?(汇编)
●计算机系统的广义接口有哪些?计算机的硬件接口电路主要由哪三部分组成?(接口)
3.x86的实模式和保护模式各有哪些主要优缺点?
4.字符串(内存块)的字节传送使用什么CPU指令?执行指令前需要做哪些准备工作?
5.IA-32处理器的系统地址寄存器有哪些?它们各自的功用是什么?大小是多少?
6.给出IA-32段页式保护模式下(采用4KB页面大小与两级分页方式的)逻辑地址和线性地址的构成及转换成物理地址的方法和过程。
三、编程题(共4小题,每小题10分,共40分)
1.编写一个返回4字节无符号整数的十进制数串的汇编子程序GetDStr,整数通过寄存器EAX传入,返回的字符串缓冲区地址为[ES:BP],串长在CX中。
2.编写将时钟中断号设置成20h,再将时间间隔设置成每秒30次的汇编代码段。
3.设已经初始化好的GDTR指针为GdtPtr,且已知32位代码段的选择符为SelectorCode32,写出进入保护模式汇编程序的剩余代码部分。
4.从下面的两个小题中任选一题:
1)编写可编译成COM文件的完整汇编程序,用欧美的时间格式(如May 18, 2015 Mon 02:11:48)显示
系统的当前日期和时间。(月份的缩写:Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)。
2)编写定义和装入GDT的相关汇编代码段。其中的GDT含3个段描述符:空白(系统要求)、CODE
(代码段)和VIDEO(彩色文本窗口对应的显存数据段),代码段的基址和长度分别为SegCodeBase 和SegCodeLen。表示代码段、可读写数据段、32位段的符号常量分别为DA_C、DA_DRW和DA_32。
《汇编与接口》模拟试题参考答案
一、填空题(共15小题,每小题2分,共30分)
1.Flags、IP
2.64、36
3.20、1MB
4.FS、GS
5.Dx:DB/DW/DD、RESx:RESB/RESW/RESD
6.当前地址、当前节/段起始地址
7.MOVZX、BSW AP
8.8259A、8253/4
9.256、4
10.64、16
11.GDT/PL=0、LDT/PL=3
12.CPL、DPL
13.CR0、CR3
14.Interrupt Descriptor Table、中断描述符表
15.8042、8237A-5
二、简答题(共6小题,每小题5分,共30分)
1.8个通用寄存器(其中的X:eXtended扩展,是原8位寄存器的扩展):
1.AX:Accumulator累加寄存器,用于算术与逻辑运算及I/O端口读写,如乘除;
2.BX:Base address基址寄存器,用于扩展地址的变址、算术与逻辑运算、DI/SI的基址,如MOV;
3.CX:Count计数寄存器,用于循环计数、左右移位数、算术与逻辑运算,如串操作;
4.DX:Data数据寄存器,用于I/O端口地址、与AX配对用于大数值的乘除法;
5.SI:Source Index源变址寄存器,用于间接寻址和字符串处理操作;
6.DI:Destination Index目的变址寄存器,也用于间接寻址和字符串处理操作;
7.BP:Base Pointer基址指针寄存器,用于过程中(堆栈内的)参数与局部变量的访问、用作SI/DI
的基址;
8.SP:Stack Pointer堆栈指针寄存器,用作栈顶指针。
2.
1)汇编:
●NASM(Netwide Assembler,网宽汇编程序)、MASM(Macro Assembler,宏汇编程序)
●区别:
1.标签:大小写——NASM区分、MASM不区分;冒号——NASM可选/均为起始地址、MASM
无冒号为变量/有冒号为代码入口地址;
2.变量类型:NASM的变量无类型、MASM的变量有类型;
3.内存寻址:NASM的内存单元必须放在方括号内[x],没有方括号的标签x为其偏移地址;MASM
的内存单元直接使用标签本身(无方括号)x,偏移地址需使用OFFSET x;
4.子程序:在MASM中用伪操作符对PROC NEAR/FAR和ENDP来定义子程序,由near或far
属性自动生成近/远过程调用和返回;在NASM中无类似的伪操作符,必须在调用和返回指令
指明远近类型:call far和retf。
2)接口:
计算机系统的分层与接口
●计算机硬件接口电路主要由如下三部分组成:
1.控制命令逻辑电路——为接口电路的“CPU”,控制接口的全部操作。一般由命令字寄存器和控制执行逻辑组成。有些智能接口的该部分由微处理器承担。
2.状态设置和存储电路——主要由一组数据寄存器构成,用于CPU和外设协调动作。
3.数据存储和缓冲电路——也由一组数据寄存器构成,用于暂存CPU与外设之间传送的数据,以完成速度匹配工作。
3.
●实模式
?优点:编程简单、支持BIOS和中断向量表IVT、内存访问自由;
?缺点:只能访问20位地址空间(1MB)、无保护功能、不支持分页和虚拟内存管理,不能构建
现代操作系统。
●保护模式
?优点:可访问大容量内存、提供内存保护、支持内存分页/虚拟内存管理;
?缺点:编程复杂、BIOS和IVT失效。
4.
●指令:REP MOVSB
●准备:
1.将存放在数据段中的源串首(DF=1时为末)偏移地址放入(E)SI中;
2.将附加段中的目的串首(DF=1时为末)偏移地址放入(E)DI中;
3.将数据长度(单位个数/字节数)放入计数寄存器(E)CX中;
4.用CLD/STD指令设置方向标志位为0/1(默认DF=0)。
5.
●全局描述符表寄存器GDTR:存放当前GDT的32位基地址和16位界限值、用于访问当前的GDT、
48位
●局部描述符表寄存器LDTR:存放当前LDT(段)的16位段选择符、32位基地址、20位界限值和
12位属性、用于访问当前的LDT、80位
●中断描述符表寄存器IDTR:存放当前IDT的32位基地址和16位界限值、用于访问当前的IDT、
48位
●任务寄存器TR:存放当前任务状态段TSS的16位段选择符、32位基地址、20位界限值和12位属
性、用于访问当前的TSS、80位
6.
●逻辑地址:
?构成:在IA-32的分段保护模式下,48位的逻辑地址由一个16位的段选择符和一个32位的偏
移量构成
?转换:由段选择符定位指定描述符表中对应段描述符,再由段描述符中的段基地址加上逻辑地
址中的偏移量,可得到线性地址(如果没有分页,该线性地址就是物理地址)
●线性地址
?构成:采用4KB页面大小与两级分页方式时,32位的线性地址由一个10位的页目录序号、一
个10位的页表序号和一个12位的页偏移量构成
?转换:由线性地址中的页目录序号定位CR3所指的页目录中的对应页目录项,再由页目录项所
指的页表和线性地址中的页表序号定位页表中的页表项,最后由页表项所含的页基地址加上线
性地址中的页偏移量,可得到物理地址
三、编程题(共4小题,每小题10分,共40分)
1.源代码
; --------------------------------------------------------------------
dn equ 30 ; 最大位数
sbuf: resb dn ; 用于存放十进制数字串的缓冲区,大小= 常量dn(=30)
; 获取32位数据值十进制串例程
GetDStr: ; 以EAX为传递参数,[串地址]BP和[字符个数]CX为返回值
mov cx, 1 ; 当前字符个数(初始化为1)
mov bp, sbuf ; BP = fsbuf + fsbuflen - 1 = fsbuf的当前位置
add bp, dn - 1 ; BP = 串尾
mov ebx, 10 ; 除数=10
.1: ; 循环开始处
mov edx, 0 ; EDX = 0
div ebx ; EDX:EAX / EBX -> 商EAX、余EDX
add dl, 30h ; 余数+ 30h = 对应的数字符ASCII码
mov [bp], dl ; fsbuf[BP] = DL
cmp eax, 0 ; 商EAX = 0 ?
je .2 ; = 0 跳出循环
dec bp ; 数字符的当前位置BP--
inc cx ; 串长CX++
jmp .1 ; 继续循环
.2: ; 退出循环
ret ; 从例程返回
2.源代码
; 初始化8259A,将时钟中断号设置成20h -------------------------------------------------------------------
Init8259A:
mov al, 11h
out 20h, al ; 主8259A, ICW1.
call io_delay
out 0A0h, al ; 从8259A, ICW1.
call io_delay
mov al, 20h; IRQ0对应中断向量0x20
out 21h, al ; 主8259A, ICW2.
call io_delay
mov al, 28h; IRQ8对应中断向量0x28
out 0A1h, al ; 从8259A, ICW2.
call io_delay
mov al, 4 ; IR2对应从8259A
out 21h, al ; 主8259A, ICW3.
call io_delay
mov al, 2 ; 对应主8259A的IR2
out 0A1h, al ; 从8259A, ICW3.
call io_delay
mov al, 1
out 21h, al ; 主8259A, ICW4.
call io_delay
out 0A1h, al ; 从8259A, ICW4.
call io_delay
ret
; Init8259A -------------------------------------------------------------------------------------------
io_delay:
nop
nop
nop
nop
ret
; 设置8253计数器,将时间间隔设置成每秒30次
SetTimer:
mov al,34h ; 设控制字值
out 43h,al ; 写控制字到控制字寄存器
mov ax,1193182/30; 每秒30次中断(33.33ms一次)
out 40h,al ; 写计数器0的低字节
mov al,ah ; AL=AH
out 40h,al ; 写计数器0的高字节
ret
3.源代码
; 加载GDTR
lgdt [GdtPtr]
; 关中断
cli
; 打开地址线A20
in al, 92h
or al, 00000010b ; or al, 2(关闭:and al,0FDh)
out 92h, al
; 准备切换到保护模式(置CR0的PE位为1)
mov eax, cr0
or eax, 1 ; PE = 1
mov cr0, eax
; 真正进入保护模式
jmp dword SelectorCode32:0 ;执行这一句会把SelectorCode32 装入CS,
; 并跳转到Code32Selector:0处
4.
1)源代码:
org 100h ; 可编译成COM文件
; 通过AX中转,将CS的值赋给DS、ES和SS
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 100h - 4 ; 置栈顶指针SP=100h-4
call newline ; 回车换行
; 获取月信息
mov al, 8 ; 月的偏移地址为8
out 70h, al ; 指定存储单元地址
in al, 71h ; 读入月信息
; 转换BCD为普通二进制值
mov cl, al ; CL = AL
shr al, 4 ; AL >> 4
mov bl, 10 ; BL = 10
mul bl ; AL *= 10
and cl, 0Fh ; 取CL的低4位
add al, cl ; AL = CL
; 计算月串地址
mov bl, 3 ; BL = 3
mul bl ; AX = AL * BL
add ax, monthstrs ; AX += monthstrs
mov bp, ax ; BP = AX 指向对应月串mov cx, 3 ; 串长CX = 3
call DispStr ; 显示字符串
; 显示空格分隔符
mov al, ' ' ; AL = ' '
call ShowChar ; 显示字符
; 获取日信息
mov al, 7 ; 日的偏移地址为7
out 70h, al ; 指定存储单元地址
in al, 71h ; 读入日信息
; 显示日信息
call ShowBCD ; 显示BCD十进制数
; 显示逗号分隔符
mov al, ',' ; AL = ','
call ShowChar ; 显示字符
; 显示空格分隔符
mov al, ' ' ; AL = ' '
call ShowChar ; 显示字符
; 显示'2'和'0'
mov al, '2' ; AL = '2'
call ShowChar ; 显示字符
mov al, '0' ; AL = '0'
call ShowChar ; 显示字符
; 获取年信息
mov al, 9 ; 年的偏移地址为9
out 70h, al ; 指定存储单元地址
in al, 71h ; 读入年信息
; 显示年信息
call ShowBCD ; 显示BCD十进制数
; 显示空格分隔符
mov al, ' ' ; AL = ' '
call ShowChar ; 显示字符
; 获取星期信息
mov al, 6 ; 星期的偏移地址为6 out 70h, al ; 指定存储单元地址
in al, 71h ; 读入星期信息
; 显示星期信息
mov bl, 3 ; BL = 3
mul bl ; AX = AL * BL
add ax, weekstrs ; AX += weekstrs
mov bp, ax ; BP = AX 指向对应星期串
mov cx, 3 ; 串长CX = 3
call DispStr ; 显示字符串
; 显示空格分隔符
mov al, ' ' ; AL = ' '
call ShowChar ; 显示字符
; 获取时信息
mov al, 4 ; 时的偏移地址为4
out 70h, al ; 指定存储单元地址
in al, 71h ; 读入时信息
; 显示时信息
call ShowBCD ; 显示BCD十进制数
; 显示冒号分隔符
mov al, ':' ; AL = ':'
call ShowChar ; 显示字符
; 获取分信息
mov al, 2 ; 分的偏移地址为2
out 70h, al ; 指定存储单元地址
in al, 71h ; 读入分信息
; 显示分信息
call ShowBCD ; 显示BCD十进制数
; 显示冒号分隔符
mov al, ':' ; AL = ':'
call ShowChar ; 显示字符
; 获取秒信息
mov al, 0 ; 秒的偏移地址为0
out 70h, al ; 指定存储单元地址
in al, 71h ; 读入秒信息
; 显示秒信息
call ShowBCD ; 显示BCD十进制数
; 退回DOS
mov ax, 4c00h ; ┓退出程序
int 21h ; ┛回到DOS
monthstrs: ; 定义月串数组
db 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
weekstrs: ; 定义星期串数组
db 'Sun'
db 'Mon'
db 'Tue'
db 'Wed'
db 'Thu'
db 'Fri'
db 'Sat'
; ------------------------------------------------------------------- ShowBCD: ; 显示单字节BCD十进制数(以AL为传递参数)push ax ; 保存AL进栈
shr al, 4 ; AL >> 4 (高位数字)
add al, 30h ; 数字字符= 数值+=30h
call ShowChar ; 显示字符
pop ax ; 从栈中恢复AL
and al, 0Fh ; 取AL的低4位
add al, 30h ; 数字字符= 数值+=30h
call ShowChar ; 显示字符
ret ; 从例程返回
; ------------------------------------------------------------------- ShowChar: ; 显示单个字符(以AL为传递参数)
mov ah, 0Eh ; 功能号(以电传方式显示单个字符)
mov bl, 0 ; 对文本方式置0
int 10h ; 调用10H号中断
ret ; 从例程返回
; -------------------------------------------------------------------
newline: ; 换行(显示回车符和换行符)
; 显示回车符CR(置当前列号=0)
mov ah, 0Eh ; 功能号
mov al, 0Dh ; 设置AL为回车符CR(ASCII码为0DH)mov bl, 0 ; 对文本方式置0
int 10h ; 调用10H号显示中断
; 显示换行符(当前行号++)
mov ah, 0Eh ; 功能号
mov al, 0Ah ; 设置AL为换行符LF(ASCII码为0AH)mov bl, 0 ; 对文本方式置0
int 10h ; 调用10H号显示中断
ret ; 从例程返回
; --------------------------------------------------------------------
DispStr: ; 显示字符串例程(需先置串长CX和串地址BP)
; 获取当前光标位置(返回的行列号分别在DH和DL中)
push cx ; 保护CX(进栈)
mov ah, 3 ; 功能号
mov bh, 0 ; 第0页
int 10h ; 调用10H号显示中断
pop cx ; 恢复CX(出栈)
; 在当前位置显示字符串(串长CX和串地址BP已预先设置好了)
mov ah, 13h ; BIOS中断的功能号(显示字符串)
mov al, 1 ; 光标放到串尾
mov bh, 0 ; 页号= 0
mov bl, 0Fh ; 字符颜色= 不闪(0)黑底(000)白字(0111)
int 10h ; 调用10H号显示中断
ret ; 从例程返回
2)源代码:
; GDT(定义全局描述符表)
; 段基址, 段界限, 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符LABEL_DESC_CODE: Descriptor SegCodeBase, SegCodeLen-1, DA_C + DA_32; 代码段LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存数据段; GDT 结束
; 定义48位的GDT参数结构GdtPtr(16位界限+ 32位基地址)
GdtLen equ $ - LABEL_GDT ; GDT长度
GdtPtr dw GdtLen - 1 ; GDT界限
dd 0 ; GDT基地址
……
; 为加载GDTR 作准备
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT ; eax <-- GDT基地址
mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <-- GDT基地址
; 加载GDTR
lgdt [GdtPtr]