2015-2016学年下学期期中
2015-2016学年下学期期中试卷(A)(含答案)
一、选择题(每小题 2 分,共 30 分)
-
我们通常所说的“字节”由( )个二进制位构成。
A. 1
B. 8
C. 16
D. 32
答案:
B
-
IA32 的 CPU 中有一个程序计数器(又称指令计数器)。它用于存储( )。
A. 保存将要执行的下一条指令在主存中的地址
B. 保存当前 CPU 所要访问的内存单元地址
C. 暂时存放 ALU 运算结果的信息
D. 保存当前正在执行的一条指令
答案:
A
-
逻辑运算
!!0x21的结果用十六进制表示为( )。A.
0x00B.
0x21C.
0x12D.
0x01答案:
D
-
考虑程序片段:
short int x=-12345; unsigned short int y=x;则y的真值为( )。A. -12345
B. 12345
C. 53190
D. 53191
答案:
D
-
位移运算:对参数
x = 0x85,则x >> 4(算术右移)的结果是( )。A.
0x08B.
0x50C.
0xf8D.
0x5f答案:
C
-
sizeof(int)的值为( )。A. 2
B. 4
C. 8
D. 4 或 8
答案:
B
-
定义变量:
int x=0x01234567;采用小端法存储数据,x的起始地址为0x1000,则x的存储形式为( )。A.
地址 0x10000x10010x10020x1003值 0x670x450x230x01B.
地址 0x10000x10010x10020x1003值 0x010x230x450x67C.
地址 0x10000x10010x10020x1003值 0x450x670x010x23D.
地址 0x10000x10010x10020x1003值 0x670x450x000x00答案:
A
-
(3.14+1e10)-1e10在计算机中的运算结果为( )。A. 0
B. 3.14
C.
1e10D. 0.0
答案:
D
-
R[Ea]寻址方式属于( )。A. 立即数寻址
B. 寄存器寻址
C. 绝对寻址
D. 间接寻址
答案:
B
-
假设初始值:
%dh=CD,%eax=98765432,则执行指令MOVB %dh,%al后,%eax的值为多少?( )A.
%eax=987654CDB.
%eax=CD765432C.
%eax=FFFFFFCDD.
%eax=000000CD答案:
A
-
假设寄存器
%eax的值为x,%ecx的值为y,则执行汇编指令leal (%eax,%ecx,2),%edx后,存储在寄存器%edx中的值为( )。A.
2xB.
2yC.
x+2yD.
2x+y答案:
C
-
条件码 ZF 表示( )。
A. 零标志
B. 符号标志
C. 溢出标志
D. 进位标志
答案:
A
-
某硬盘有五个盘片,每个扇区 512 字节,每个面 20000 条磁道,每条磁道平均 400 个扇区,则这个磁盘容量是( )GB。
A. 20.48
B. 40.96
C. 163.84
D. 327.68
答案:
B
-
假设某磁盘的旋转速率为 15000RPM,,每条磁道的平均扇区数为 500,则这个磁盘上一个扇区的访问时间为( )ms。
A. 8
B. 9
C. 10
D. 11
答案:
C
-
与传统旋转式硬盘相比,下面不是固态硬盘的特点的是( )。
A. 更快速
B. 低能耗
C. 读写速度相当
D. 写访问比读访问慢 10 倍
答案:
C
二、填空题(每小题 2 分,共 10 分)
-
在 IA32 体系结构机器中,存储
long int型变量需要 ______ 个字节,而 X86-64 体系结构机器中,存储long int型变量又需要 ______ 个字节。答案:
4;8
-
处理同样字长的有符号数和无符号数之间的转换规则是:位模式 ______(改变/不变),数值重新解析。
答案:
不变
-
浮点加法运算 (满足/不满足)交换律,(满足/不满足)结合律。
答案:
满足;不满足
-
IA32 架构机器中,执行
push %eax指令,栈指针(%esp)______(加/减)4 后,再存储%eax的值到%esp位置。答案:
减
-
嵌套数组中元素采用 ______(行优先/列优先)顺序排列。
答案:
行优先
三、分析、计算题(共 60 分)
-
(8 分)假设某存储器及寄存器存储的数据如下表所示:
存储器地址 值 寄存器名称 值 0x2000xFF%eax0x2000x2040xAB%ecx0x10x2080x13%edx0x30x20c0x11试给出如下所示操作数的值。
操作数 值 %eax(%eax)0x204$0x2040x1fc(,%ecx,4)(%eax,%edx,4)1(%eax,%edx)516(%ecx,%edx)答案:
操作数 值 %eax0x200(%eax)0xFF0x2040xAB$0x2040x2040x1fc(,%ecx,4)0xFF(%eax,%edx,4)0x111(%eax,%edx)0xAB516(%ecx,%edx)0x13
-
(8 分)考虑一个 8 位补码表示的有符号整型数据,填写下表(基于 8 位补码加减法运算规则执行加减法运算):
数 二进制表示 Zero(零) TMax(最大有符号整数) TMin(最小有符号整数) TMin + TMin TMin + 1 TMax + 1 -TMax -TMin 答案:
数 二进制表示 Zero(零) 0000 0000TMax(最大有符号整数) 0111 1111TMin(最小有符号整数) 1000 0000TMin + TMin 0000 0000TMin + 1 1000 0001TMax + 1 1000 0000-TMax 1000 0001-TMin 1000 0000
-
(8 分)定义变量:
float x;试填写下表:x 二进制表示 十进制表示 最大规格化正数 最小规格化正数 最大规格化负数 最小规格化负数 答案:
x 二进制表示 十进制表示 最大规格化正数 0 11111110 111...111最小规格化正数 0 00000001 000...000最大规格化负数 1 00000001 000...000最小规格化负数 1 11111110 111...111
-
(15 分)库函数中
memcpy和copy_from_kernel的定义如下所示:/* Declaration of library function memcpy */
void *memcpy(void *dest, void *src, unsigned int n);
/* Kernel memory region holding user-accessible data */
#define KSIZE 1024
char kbuf[KSIZE];
/* Copy at most maxlen bytes from kernel region to user buffer */
int copy_from_kernel(void *user_dest, int maxlen) {
/* Byte count len is minimum of buffer size and maxlen */
int len = KSIZE < maxlen ? KSIZE : maxlen;
memcpy(user_dest, kbuf, len);
return len;
}某应用程序片段如下所示:
#define MSIZE 528
void getstuff() {
char mybuf[MSIZE];
copy_from_kernel(mybuf, -MSIZE);
...
}- 试分析该程序的潜在危害。
- 如何消除其潜在危害?
答案:
-
函数
copy_from_kernel是要将一些操作系统内核维护的数据(最多 1024 字节)复制到指定的用户可以访问的存储器区域。假设有些怀有恶毒的程序员在调用copy_from_kernel的代码中对maxlen使用了负数值,则会把这个值赋给len,然后len会作为参数n被传递给memcpy(参数n是被声明为数据类型unsigned int的),则memcpy会把它当作一个非常大的正整数,并且试图将这样多字节的数据从内核区域复制到用户的缓冲区,这样程序还是能读到没有被授权的内核存储器区域,发生信息泄露。 -
将
copy_from_kernel的参数maxlen声明为类型unsigned int,也就是与memcpy的参数n一致。同时,将本地变量len和返回值声明为unsigned int。
-
(12 分)考虑如下 C 程序片段,其中去掉了
switch语句的主体,请根据给出的汇编代码及跳转表,补充完整 C 语言程序片段中的switch语句主体。long switch_eg(long x, long y, long z)
{
long w = 1;
switch (x) {
/* Fill in code here */
...
}
return w;
}汇编代码如下:
switch_eg:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax # eax = x
cmpl $6, %eax
ja .L2
jmp *.L7(,%eax,4)
.L2:
movl $2, %eax
jmp .L8
.L5:
movl $1, %eax
jmp .L9
.L3:
movl 16(%ebp), %eax # eax = z
imull 12(%ebp), %eax
jmp .L8
.L4:
movl 12(%ebp), %edx # edx = y
movl %edx, %eax
sarl $31, %edx
idivl 16(%ebp)
.L9:
addl 16(%ebp), %eax
jmp .L8
.L6:
movl $1, %eax
subl 16(%ebp), %eax
.L8:
popl %ebp
ret跳转表如下:
.section .rodata
.align 4
.L7:
.long .L2
.long .L3
.long .L4
.long .L5
.long .L2
.long .L6
.long .L6答案:
long switch_eg(long x, long y, long z)
{
long w = 1;
switch (x) {
case 1:
w = y * z;
break;
case 2:
w = y / z;
/* Fall Through */
case 3:
w += z;
break;
case 5:
case 6:
w -= z;
break;
default:
w = 2;
}
return w;
}
-
(9 分)考虑如下 C 程序片段:
int main(void) {
union {
unsigned char c[8];
unsigned short s[4];
unsigned int i[2];
unsigned long k[1];
} dw;
int j;
for (j = 0; j < 8; j++)
dw.c[j] = 0xc0 + j;
printf("Shorts 0-3=[0x%x,0x%x,0x%x,0x%x]\n", dw.s[0], dw.s[1], dw.s[2], dw.s[3]);
printf("Ints 0-1= [0x%x,0x%x]\n", dw.i[0], dw.i[1]);
printf("Long 0= [0x%lx]\n", dw.k[0]);
}试分析该程序在 IA32 架构机器中运行后的输出结果。
答案:
Shorts 0-3 == [0xc1c0,0xc3c2,0xc5c4,0xc7c6]
Ints 0-1 == [0xc3c2c1c0,0xc7c6c5c4]
Long 0 == [0xc3c2c1c0]