《中山大学授予学士学位工作细则》第六条
考试作弊不授予学士学位
计算机科学系2011第二学期
《操作系统原理实验》期末考试试题(A) 任课教师:李才伟&凌应标考试形式:开卷考试时间:2小时
年级:10 班别:AB网安专业:计科&网工&信安姓名:_____ 学号:_成绩_ 注意:答案一定要写在答卷中,写在本试题卷中不给分。本试卷要和答卷一起交回。
一.填空题(每小题2分,共30分)
1.实验中使用过的虚拟机软件有___。
2.引导扇区是磁盘的第___个物理扇区,其最后两个字节的十六进制值为___。
3.Windows下可用于写软盘映像的软件工具有___。
4.创建软盘映像文件的Bochs程序为___,Bochs虚拟机的配置文件为___。
5.FAT的英文原文是___,中文译文为___。
6.通常FAT12软盘的每个簇有___个扇区,每个扇区有___个字节。
7.PC机的中断控制器和可编程计时器的型号分别为___和___。
8.IA-32中描述符和选择符的大小分别为___B和___B。
9.IA-32的特权级有__个级别和___种类型。
10.段选择符的低三位全为0表示___,全为1表示___。
11.打开和关闭可屏蔽中断的CPU指令分别为___和___。
12.在实模式和保护模式下,默认的时钟中断号分别为___和___。
13.IA-32采用的主要虚拟内存管理方法为___,基本的页面大小为___。
14.将程序的入口安排在指定位置的汇编操作符为___、链接选项为___。
15.在Make文件中,$@ 和$< 分别表示___和___。
二.问答题(每小题5分,共30分)
1.列出在Windows下OS编程实验所用的软件工具,并给出它们各自的主要功用。
2.说明用WinHex将大小为800字节的文件https://www.wendangku.net/doc/5e1930938.html,写入FAT12软盘映像a.img中的主要步骤和参数。3.给出GDT、LDT、IDT、TSS的英文原文和中文译文及其主要功用。
4.进入保护模式的主要步骤有哪些?
5.给出在保护模式下从特权级0的内核程序切换到特权级3的用户进程的思路、步骤和代码段。
6.写出在Linux中,先创建挂载目录/mnt/floppy、再挂载软盘映像a.img、然后将当前目录中的https://www.wendangku.net/doc/5e1930938.html,文件
复制到挂载目录、接着列出挂载目录中的文件、最后卸载软盘映像的系列命令。
三.编程题(每小题10分,共40分)
1.编写可编译成COM文件的完整汇编程序,利用BIOS中断实现在屏幕中央显示黑底红字的字符串“OS Principles”。
2.编写创建只含FAT12分区BPB与EPBP数据(不显示字符串)的引导扇区,并设置名为“OS Test”的卷标条目的完整汇编程序。
3.编写将时钟中断号设置成40h,再将时间间隔设置成每秒24次的汇编代码段。
4.从下面的两个小题中任选一题:
1)编写可编译成COM文件的完整汇编程序,获取并显示当前系统的内存信息,要求只保存和显示OS
可用类型的部分,8字节整数用高位在前的十六进制数显示。
2)编写定义和装入GDT的相关汇编代码段。其中的GDT含3个段描述符:空白(系统要求)、CODE
(代码段)和VIDEO(彩色文本窗口对应的显存数据段),代码段的基址和长度分别为SegCodeBase 和SegCodeLen。表示代码段、可读写数据段、32位段的符号常量分别为DA_C、DA_DRW和DA_32。
《操作系统原理实验》试题参考答案
一.填空题(每小题2分,共30分)
1.VMware、Bochs
2.1、55 AA
3.DiskWriter/FloppyWriter、WinImage、WinHex
4.Disk Image Creation Tool(bximage.exe)、bochsrc[.bxrc]
5.File Allocation Table、文件分配表
6.1、512
7.8259A、8253
8.8、2
9.4、3
10.GDT/特权级0、LDT/特权级3
11.STI、CLI
12.8、32(20h)
13.段页式、4KB
14.org、-Ttext
15.目标、首个先决条件(源代码文件)
二.问答题(每小题5分,共30分)
1.NotePad++:编写源程序、NASM:编译汇编程序、WinHex:编辑软盘映像和U盘、DiskWriter/FloppyWriter:将引导扇区等写入软盘映像、WinImage:将文件复制进FAT12软盘映像、Debug:调试汇编程序、Bochs 虚拟机:运行测试、DOS软盘映像:运行测试
2.操作步骤和参数:
a)启动WinHex、打开https://www.wendangku.net/doc/5e1930938.html,和a.img文件
b)创建文件条目:在a.img中定位到根目录区(起始地址为2600h),找到一个空白的文件条目(每个
条目20h/32B,起始字节的值为0的为空白条目),在条目开始处写入8+3的文件名(全大写,不足的补空格符20h)“HELLO COM”、接着是文件属性20h(普通档案文件)、保留10B(全设为0)、时间、日期、首簇号(?)、文件大小800(20h 03h)等
c)设置FAT项:定位到a.img的FAT#1区(起始地址为200h),找到2个相连的空白FAT项(每项12
位/1个半字节,值为0的为空白项),置第1个FAT项的值=第2个FAT项的序号,置第2个FAT 项的值=FFh(表示文件结束)。FAT项的序号的计算方法:项序号=项首地址相对于FAT#1区起始地址的偏移量/1.5。例如,若第1个FAT项的地址为203h,则序号=3/1.5=2,第2个FAT项的序号自然=3(4.5[4的高4位]/1.5)。再定位到a.img的FAT#2区(起始地址为1400h),将对应的FAT项填上同样的值
d)填写文件条目的首簇号:再一次定位到a.img的根目录区(起始地址为2600h),在刚才创建的文件
条目的偏移1Ah处,填上上面算得的第1个FAT项的序号
e)写入文件数据:由首簇号计算文件数据区的首地址= (首簇号+31)*512 [= (3 +31 )*512 = 17408 =
4400h],定位到a.img的该地址处,(切换到https://www.wendangku.net/doc/5e1930938.html,文件)选中并复制(Ctrl+A、Ctrl+C)https://www.wendangku.net/doc/5e1930938.html, 的全部内容,(再切换回a.img文件)粘贴到文件数据区的首地址处(Ctrl+B)
f)保存a.img文件,关闭WinHex
3.
a)GDT:Global Descriptor Table,全局描述符表,含有(系统程序的代码段和数据段的)段描述符和
LDT、IDT、TSS、任务门等描述符表项,用于(系统)程序和LDT、IDT、TSS、任务等的寻址
b)LDT:Local Descriptor Table,局部描述符表,含有程序代码段、数据段和堆栈段的段描述符,用于
应用程序的寻址
c)IDT:Interrupt Descriptor Table,中断描述符表,包含中断向量的入口地址,用于中断处理
d)TSS:Task-State Segment,任务状态段,包含用于保护任务运行现场的数据结构,用于任务切换4.准备GDT、用LGDT指令将GDT参数加载到寄存器GDTR、打开A20地址线、置CR0寄存器的PE位、跳转进入保护模式
5.思路:利用远程调用的返回过程来实现从高特权级0到低特权级为3的代码转移
步骤:先将用户进程的SS、ESP、CS和EIP依次压栈,再利用远调用返回指令RETF实现代码转移,同时也完成了从特权级0的内核程序到特权级3的用户进程的转换
代码:
push SelectorStack3 ; SS
push TopOfStack3 ; ESP
push SelectorCodeRing3 ; CS
push 0 ; EIP
retf ; Ring0 -> Ring3
6.sudo mkdir /mnt/floppy、sudo mount -o loop a.img /mnt/floppy、sudo cp https://www.wendangku.net/doc/5e1930938.html, /mnt/floppy、dir/ls /mnt/floppy、sudo umount /mnt/floppy
三.编码题(每小题10分,共40分)
1.源代码:
org 100h ; 告诉编译器程序加载到100H处
mov ax,cs ; 置DS和ES = CS
mov ds,ax
mov es,ax
call DispStr ; 调用显示字符串函数
jmp $ ; 无限循环
DispStr: ; 显示字符串例程
mov ax,BootMsg
mov bp,ax ; ES:BP=串地址
mov cx,13 ; CX=串长
mov ah,13h ; AH=BIOS中断的功能号
mov al,01h ; AL=1表示光标放到串尾
mov bh,0 ; BH=页号
mov bl,0ch ; BL=颜色(黑底红字)
mov dh,12 ; DH=行号
mov dl,33 ; DL=列号
int 10h ; 调用10h号中断
ret ; 函数返回
BootMsg: ; 显示用的字符串
db "OS Principles"
2.源代码
; 引导扇区
jmp short LABEL_START ; Start to boot.
nop ; 这个nop 不可少
; FAT12的BPB与EPBP
BS_OEMName DB 'MY-OS1.0' ; OEM String, 必须8 个字节(不足补空格)
BPB_BytsPerSec DW 512 ; 每扇区字节数
BPB_SecPerClus DB 1 ; 每簇多少扇区
BPB_RsvdSecCnt DW 1 ; Boot记录占用多少扇区
BPB_NumFATs DB 2 ; 共有多少FAT 表
BPB_RootEntCnt DW 224 ; 根目录文件数最大值
BPB_TotSec16 DW 2880 ; 逻辑扇区总数
BPB_Media DB 0xF0 ; 介质描述符
BPB_FATSz16 DW 9 ; 每FAT扇区数
BPB_SecPerTrk DW 18 ; 每磁道扇区数
BPB_NumHeads DW 2 ; 磁头数(面数)
BPB_HiddSec DD 0 ; 隐藏扇区数
BPB_TotSec32 DD 0 ; wTotalSectorCount为0时这个值记录扇区数
BS_DrvNum DB 0 ; 中断13 的驱动器号
BS_Reserved1 DB 0 ; 未使用
BS_BootSig DB 29h ; 扩展引导标记(29h)
BS_V olID DD 12345678h; 卷序列号
BS_V olLab DB 'MyOS System'; 卷标, 必须11 个字节(不足补空格)
BS_FileSysType DB 'FAT12 ' ; 文件系统类型, 必须8个字节(不足补空格)LABEL_START:
times 510-($-$$) db 0 ; 用0填充剩下的空间
db 55h, 0aah ; 引导扇区结束标志
; 填充两个FAT表的头两个项(每个FAT占9个扇区)
db 0f0h, 0ffh, 0ffh ; 介质描述符(F0h)和Fh、结束簇标志项FFFh
times 512*9-3 db 0 ; 用0填充FAT#1剩下的空间
db 0f0h, 0ffh, 0ffh ; 介质描述符(F0h)和Fh、结束簇标志项FFFh
times 512*9-3 db 0 ; 用0填充FAT#2剩下的空间
; 根目录中的卷标条目
db 'OS Test ' ; 卷标, 必须11 个字节(不足补空格)
db 8 ; 文件属性值(卷标条目的为08h)
dw 0,0,0,0,0 ; 10个保留字节
dw 0,4070h ; 创建时间,设为2012年3月16日0时0分0秒
dw 0 ; 开始簇号(卷标条目的必需为0)
dd 0 ; 文件大小(也设为0)
3.源代码:
; 初始化8259A,将时钟中断号设置成40h ------------------------------------------------------------------- Init8259A:
mov al, 11h
out 20h, al ; 主8259A, ICW1.
call io_delay
out 0A0h, al ; 从8259A, ICW1.
call io_delay
mov al, 40h; IRQ0对应中断向量0x20
out 21h, al ; 主8259A, ICW2.
call io_delay
mov al, 48h; 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计数器,将时间间隔设置成每秒24次
SetTimer:
mov al,34h ; 设控制字值
out 43h,al ; 写控制字到控制字寄存器
mov ax,1193182/24; 每秒24次中断(41.67ms一次)
out 40h,al ; 写计数器0的低字节
mov al,ah ; AL=AH
out 40h,al ; 写计数器0的高字节
ret
4.
1)源代码:
org 100h ; 可汇编成COM文件
mov ax,cs ; DS = CS, SS = CS
mov ds,ax
mov ss,ax
mov sp,100h-4 ; 可汇编成COM文件
mov es,ax ; ES = CS
mov ebx,0 ; EBX = 0 (初始值)
mov di,Buf ; ES:DI = 返回值的缓冲区起始地址
LB_loop: ; 调用15h中断的E820h功能获取内存容量
mov eax,0E820h ; 功能号
mov ecx,20 ; 缓冲区大小
mov edx,534D4150h ; "SMAP" 校验标志
int 15h ; 中断调用
jc LB_fail ; 出错跳转
cmp byte [di+16],1 ; 是否类型为1?
jne LB_not1 ; != 1时跳转
add di,20 ; 缓冲区指针后移20个字节
inc word [Numb] ; 内存分段数加一
LB_not1:
cmp ebx,0 ; EBX = 0?
jne LB_loop ; EBX != 0:继续调用
mov di, Buf ; EBX = 0:结束,DI = 缓冲区起始地址(用于显示)
jmp LB_OK ; 跳转到LB_OK,开始显示返回值
LB_fail: ; 调用失败时显示“Failed!”字符串
mov bp,FailMsg ; BP=当前串的偏移地址
mov ax,ds ; ES:BP = 串地址
mov es,ax ; 置ES=DS
mov cx,7 ; CX = 串长(=9)
mov ax,1301h ; AH = 13h(功能号)、AL = 01h(光标置于串尾)
mov bx,000Fh ; 页号为0(BH = 0) 黑底白字(BL = 0Fh)
mov dx,0 ; 列号=0(DL=0) 行号=0(DH=0)
int 10h ; 显示中断
mov word [Numb],0 ; 置内存分段数=0(不显示返回值)ret ; 退出程序
LB_OK: ; 循环显示返回段值
cmp word [Numb],0 ; Numb = 0?
je LB_out ; Numb = 0:退出程序
call Disp8B
call DispSP
add di,8
mov eax,[Size1]
add eax,[di]
mov[Size1],eax
jno LB_NoOF
inc dword [Size2]
LB_NoOF:
mov eax,[Size2]
add eax,[di+4]
mov[Size2],eax
call Disp8B
call DispCrnl ; 回车换行
add di,12
dec dword [Numb] ; Numb--
jnz LB_OK ; 显示下一个内存段值
LB_out: ; 退出程序
mov di,Size1 ; 显示内存总容量
call Disp8B
call DispCrnl ; 回车换行
ret ; 返回
; 显示8字节整数
Disp8B:
mov si,8
LB_lloop:
mov bx,di
mov al, byte [bx+si-1] ; AL = 当前字节值
call DispByte ; 调用显示字节十六进制值的函数
call DispSP
dec si
jnz LB_lloop ; 字段内循环
ret
; 显示空格符
DispSP:
mov al,20h ; AL = 空格符
mov ah,0Eh ; 功能号(以电传方式显示单个字符)
mov bl,0 ; 对文本方式置0
int 10h ; 调用10H号中断
ret
; 显示回车换行符
DispCrnl:
mov al,0Ah ; AL = 换行符
mov ah,0Eh ; 功能号(以电传方式显示单个字符)
mov bl,0 ; 对文本方式置0
int 10h ; 调用10H号中断
mov al,0Dh ; AL = 回车符
mov ah,0Eh ; 功能号(以电传方式显示单个字符)
mov bl,0 ; 对文本方式置0
int 10h ; 调用10H号中断
ret
; 显示字节数据值十六进制串函数
DispByte: ; 显示字节数值串(以AL为传递参数)
mov dl,al ; 保存传递参数AX的值
; 显示高4位
and al,0F0h ; 取出高4位
shr al,4 ; 右移4位
call ShowChar ;调用显示字符函数
; 显示低4位
mov al,dl ; 恢复传递参数AX的值
and al,0Fh ; 取出低4位
call ShowChar ;调用显示字符函数
ret
; 显示单个十六进制字符函数
ShowChar: ; 显示一个十六进制数字符:0~9、A~F(以AL为传递参数)cmp al,10 ; AL < 10 ?
jl digital ; AL < 10:跳转到digital
add al,7 ; AL >= 10:显示字母(= 数值+=37h)
digital: ; 数字
add al,30h ; 数字字符= 数值+=30h
mov ah,0Eh ; 功能号(以电传方式显示单个字符)
mov bl,0 ; 对文本方式置0
int 10h ; 调用10H号中断
ret
; 定义变量和缓冲区
Numb dw 0 ; 内存分段数,初值=0
Size1 dd 0 ; 内存总数低双字
Size2 dd 0 ; 内存总数高双字
FailMsg: db "Failed!" ; 中断调用失败时显示的字符串
Buf: times 160 db 0 ; 存放中断返回值的缓冲区
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]