课下测试补交(ch03 ch08)
课下测试补交(ch03 ch08)
课下测试 ch03
1.有关gdb调试汇编,下面说法正确的是(ABCE)
A .
可以用disas反汇编当前函数
B .
以16进制形式打印%rax中内容的命令是 print /x $rax
C .
可以用info registers查看所有寄存器的值
D .
可以用info frame 查看所有栈帧的信息
E .
可以使用up,down切换栈帧
解析:
课本p194
A:disas 反汇编当前函数
B:print /x $rax 以十六进制输出%rax的内容
C:info registers查看所有寄存器的值
D:info frame查看有关当前栈帧的信息,并非所有栈帧的信息,故不对
E:使用 up down ,跳转不同堆栈,查询其中的堆栈简要信息
2.x86-64 Linux汇编中,构建栈帧的语句是( BD )
A .
movq %rbp, %rsp
popq %rbp
B .
enter
C .
leave
D .
pushq %rbp
movq %rsp, %rbp
解析:enter等价于
pushq %rbp
movq %rsp, %rbp
3.Linux汇编中,销毁栈帧的语句是( AB )
A .
movq %rbp, %rsp
popq %rbp
B .
leave
C .
enter
D .
pushq %rbp
movq %rsp, %rbp
解析:leave等价于:
movq %rbp, %rsp
popq %rbp
4.函数调用过程中,栈用来( ABCD )
A .
传递参数
B .
存储返回信息
C .
保存寄存器
D .
局部存储
解析:课本p164
A:“用栈来管理他的过程所需要的存储空间,栈和程序寄存器存放着传递控制和数据、分配内存所需要的信息”即传递参数
B:“当前正在执行的过程的帧总是在栈顶。当过程P调用过程Q时,会把返回地址压入栈中”即存储返回信息
C:“Q的代码会扩展当前栈的边界,分配她的栈帧所需的空间。在这个空间中,他可以保存寄存器的值,分配局部变量空间”即保存寄存器
D:“为了提高空间和时间效率,x86-64过程只分配自己所需要的栈帧部分”即局部存储
5.有关C语言的控制语句和汇编指令的关系说法正确的是(ABD)
A .
可以使用汇编的有条件和无条件跳转来实现C语言的条件分支
B .
可以使用数据的条件转移来实现C语言的条件分支
C .
可以使用数据的条件转移来实现C语言的循环
D .
可以使用条件测试和跳转组合起来实现循环
解析:
A:举例gotodiff_se函数
B:P145 3·6·6一种代替的策略就是使用数据的条件转移,来实现条件分支
C、D:汇编中没有循环结构的指令可以用条件测试和跳转组合来实现循环的效果,故选D
6.下面的跳转指令与ZF有关的是(ABD)
A .
jmp
B .
je
C .
js
D .
ja
E .
jb
F .
jbe
解析:课本p139图3-15
7.假设用ADD指令完成C表达式t=a+b的功能,有关条件码寄存器的说法正确的是(ADF)
A .
若t==0 ,则ZF=1
B .
若t<0, 则CF=1
C .
若t<0, 则SF=1
D .
若(a<0==b<0)&&(t<0 != a<0), 则OF=1
E .
若(a<0==b<0)&&(t<0 != a<0), 则CF=1
F .
leaq指令不影响条件码寄存器
G .
cmp指令不影响条件码寄存器
解析:课本p135
ZF:零标志。最近的操作得出的结果为0,故当t==0,ZF=1,A对
CF:进位标志。最近的操作使最高位产生了进位。B E不对
SF:符号标志。最近的操作得到的结果为负数。
OF:溢出标志。最近的操作导致一个补码溢出——正溢出或负溢出。(a<0==b<0)&&(t<0!=a<0) 有符号溢出,故选D
leaq指令不改变任何条件码,选F
CMP指令根据两个操作数之差来设置条件码。除了只设置条件码而不更新目的寄存器之外,与SUB指令的行为是一样的。
8,.有关移位指令,下面说法正确的是(AC)
A .
SAL和SHL效果一样
B .
移位量只能是一个立即数
C .
移位量可以放在%cl中
D .
移位量可以放在%cx中
E .
SAR和SHR效果一样
解析:课本p131
A:左移指令有俩个名字:SAL和SHL效果一样。
B、C、D:移位量可以是一个立即数,或者放在单字节寄存器%cl中。
E:右移指令不同,SAR执行算术移位,SHR执行逻辑移位
9.对于下面的值,有关算术运算的指令正确的是(ABC)
A .
addq %rcx,(%rax), 目的地址是0x100
B .
addq %rcx,(%rax), 目的地址的内容是0x100
C .
subq %rdx, 8(%rax) 的值是0xA8
D .
incq 16(%rax)值是12
解析:课本p130
10.假设%rax中的值为x, %rcx中的值为y,关于leaq指令,下面正确的(AC)
A .
leaq 6(%rax), %rdx; %rdx中值为6+x
B .
leaq 6(%rax), %rdx; %rdx中值为6x
C .
leaq 7(%rax, %rax,8), %rdx; %rdx中值为9x
D .
leaq 7(%rax, %rax,8), %rdx; %rdx中值为63x
E .
leaq 7(%rax, %rax,8), %rdx; %rdx中值为15x
解析:p129
11.以下代码是将void decode1(long *xp, long *yp, long *zp)反汇编的结果,下面说法正确的是(C)
A .
从汇编代码看出,decode1的参数先入栈的是zp
B .
从汇编代码看出,decode1的参数先入栈的是xp
C .
函数功能等价于 t=x; x=y; y=z; z=t;
D .
函数功能等价于 x=y; y=z; z=x;
解析:课本习题 3.5
xp、yp和zp分别存储在对应的寄存器%rdi、%rsi和%rdx中。
12.x86-64 Linux中,函数调用的返回值存在(A)寄存器中。
A .
%rax
B .
%rbx
C .
%rcx
D .
%rsp
E .
%rbp
解析:课本p120
13.x86-64 Linux中,%rsp的值为0x108, pushq %eax后,%rsp的值为(A)
A .
0x100
B .
0x108
C .
0x110
D .
0x118
解析:课本p128: pushq %rsp-8
14.x86-64 Linux中,%rbp的值为0x108, pushq %eax后,%rbp的值为(B)
A .
0x100
B .
0x108
C .
0x110
D .
0x118
解析:课本p128,push不影响%rbp的值。
15.x86-64 Linux中,有关MOV,下面正确的是(BDEF)
A .
movw $0x50, %eax
B .
movw %bp, %sp
C .
movl ($1234), ($2345)
D .
movb $10, (%rsp)
E .
movq %rax, 4(%rbp)
F .
movb (%rdi, %rcx), %ah
解析:课本p122 ,p123, 注意内存之间不能直接mov,要用寄存器中转。b,w,l,q表示的长度要和寄存器匹配。
16.对于图中内存地址和寄存器的值,下面说法正确的是(ADEF)
A .
%rax的值是0x100
B .
(%rax)的值是0x100
C .
(%rax)的值是0x104
D .
(%rax)的值是0xFF
E .
4(%rax)的值是0xAB
F .
(%rax,%rcx,4)的值是0xAB
G .
(%rax,%rcx,4)的值是0x104
解析:课本p121
%rax :返回值
%rcx:第四个参数
%rdx:第三个参数
17.x86-64 Linux中,操作数的类型有(ABC)
A .
立即数
B .
寄存器
C .
内存引用
D .
IO引用
解析:课本p121
各种不同的操作数被分为三种类型:立即数,寄存器,内存引用
18.x86-64中,(D)寄存器用来保存运行时栈的结束位置(栈顶)
A .
%rax
B .
%rbx
C .
%rbp
D .
%rsp
解析:课本p120
其中最特别的是栈指针%rsp,用来指明运行时栈的结束位置
19.movl一次传送(C)字节的数据
A .
1
B .
2
C .
4
D .
8
解析:课本p119
movl(传送双字)”即传送4字节
20.x86-64 Linux中,push %rbx对应的机器码是(A)
A .
0x53
B .
0xd38948
C .
0x4889d3
D .
0x5b
解析:课本p115
21.x86-64中指令长度是(F)字节
A .
1
B .
2
C .
4
D .
1-4
E .
1-8
F .
1-15
G .
1-16
H .
以上都不对
解析:课本p116
x86-64的指令长度从1到15个字节不等
22.X86-64中虚拟地址的数量目前是(C)个
A .
2^16
B .
2^32
C .
2^48
D .
2^64
解析:p114
在目前的实现中,这些地址的高16位必须设置为0,所以一个地址实际上能够指定的是2^48或64TB范围内的一个字节
23.要实现c中的if,while所需的条件变化,需要(C)寄存器中的信息。
A .
通用
B .
向量
C .
条件码
D .
整数
解析:p114
条件码寄存器保存着最近执行的算数或逻辑指令的状态信息。他们用来实现控制或数据流中的条件变化,比如说用来实现if和while语句
24.程序计数器(PC)
指示将要执行的下一条指令在内存中的地址,X86-64中,PC指(B)
A .
%rsp
B .
%rip
C .
%rbp
D .
%rax
解析:课本p113 程序计数器(通常成为“PC”,在x86-64中用%rip表示)给出将要执行的下一条指令在内存中的地址
25.Linux中,对目标代码code.o进行反汇编的命令是(D)
A .
gcc -c code.o
B .
asm code.o
C .
od code.o
D .
objdump -d code.o
解析:课本p115
在Linux系统中,带‘-d’命令行标志的程序OBJDUMP(表示“object dump”)可以充当这个角色:linux> objdump -d mstore.o
26.对于机器级编程,要深入理解两种抽象(AD)
A .
ISA
B .
进程
C .
文件
D .
虚拟地址
解析:课本p113
对于机器级编程来说,其中两种抽象尤为重要。第一种是有指令集体系结构或指令集结构(ISA)来定义的机器级程序的格式和行为第二种抽象是机器级程序使用的内存地址是虚拟地址
27.Intel的处理模型中(C)首次引入超线程技术。
A .
Pentium III
B .
Pentium 4
C .
Pentium 4E
D .
Core 2
解析:课本p111
Pentium 4E,增加了超线程技术
28.Intel的处理模型中(C)首次将体系结构扩展到32位,增加了平坦寻址模式。
A .
8087
B .
80286
C .
i386
D .
i486
解析:课本p111
i386.将体系结构扩展到32位
课下测试ch08
1.C语言通过( BC )函数提供非本地跳转。
A .
try ...catch
B .
longjmp
C .
setjmp
D .
signal
解析:课本p547 非本地跳转是通过setjmp和longjmp函数来提供的
2.Linux信号处理说法正确的是(ABDEF)
A .
可以用signal()处理信号
B .
一个信号最多只能被接收一次
C .
kill(1)用来杀死进程
D .
kill(1)用来发送信号
E .
可以通过键盘发送信号
F .
可以用sigaction()处理信号
解析:课本8.5
A:p531 通过把处理程序的地址传递到signal函数从而改变默认行为,这叫设置信号处理程序。执行信号处理程序被称为处理信号。
B:p536 每种类型最u多只能有一个未处理的信号,如果两种类型k的信号发给同一个目的进程,第二个信号就简单的被遗弃了。
C、D:p530 kill函数发送信号号码sig给进程pid
E:p529 从键盘发送信号
F:p534图8-33
3.有关exec系列函数,下面说法正确的是(CE)
A .
可以用char[][] 来传递argv
B .
进程调用了exec系列函数后,pid会变
C .
进程调用了exec系列函数后,代码会改变。
D .
system()和exec系列等价。
E .
exec系列函数中带e的要传入环境变量参数
F .
exec系列函数中带v的要传入环境变量参数
解析:不能用char[][] 来传递argv,结尾的0(null)无法处理;system=fork+exec+wait;
4.有关wait类系统调用,说法正确的是(ACD)
A .
wait(&status) 等价于waitpid(-1, &status, 0)
B .
父进程中执行waitpid, 等待集合中的所有子进程结束了才返回
C .
父进程中执行waitpid, 等待集合中的任一子进程结束了才返回
D .
子进程中的退出状态在wait的status参数返回
解析:课本p516 517 518
A:p518 条用wait(&status)等价于调用waitpid(-1,%status,0)
B:p516如果一个父进程终止了,内核会安排init进程成为他的孤儿进程的养父。故错误
。
C:waitpid挂起调用进程的执行,直到他的等待集合中的一个子进程终止。
D:p517 如果statusp参数是非空的,那么waitpid就会在status中放上关于导致返回的子状态信息。
5.关于图中代码,说法正确的是(B)
A .
程序执行2个printf
B .
程序执行3个printf
C .
程序执行5个printf
D .
程序执行4个printf
解析:子2 父1
6.有关fork(),下面说法正确的是(ACD)
A .
一次调用,两次返回
B .
子进程中,fork()返回子进程PID
C .
子进程可以读写父进程中打开的文件
D .
子进程和父进程的用户级虚拟地址空间相同但独立
解析:课本p514
A:p514 调用一次,返回两次
B:p514 在子进程中,fork返回值为0.
C:p515 我们注意到父进程和子进程都把它们的输出显示在屏幕上。原因是子进程继承了父进程所有的打开文件。
D:p515 相同但是独立的地址空间
7.关于代码 int main(){} 说法正确的是(ACE)
A .
返回值是0
B .
返回值不确定
C .
会调用exit(0)
D .
返回值大于0
E .
上面代码运行完,在命令行中运行echo $? 的值是0
解析:main中不调用exit,会补上exit(0)
8.从程序员角度看进程状态有( ACD )
A .
运行
B .
就绪
C .
停止
D .
终止
解析:从程序员的角度,进程总是处于下面三种状态之一:
- 运行
- 停止
- 终止
9.Unix/Linux中通过调用( D )可以获取子进程PID。
A .
getpid()
B .
getppid()
C .
getcpid()
D .
fork()
解析:课本p514 在父进程中,fork返回子进程的PID
10.Unix/Linux中通过调用( B )获取父进程ID。
A .
getppid()
B .
getppid()
C .
getbpid()
D .
getmpid()
解析:课本p513 getpid函数返回调用进程的PID,getppid函数返回她的父进程的PID。
11.进程调度由内核中的( C )处理完成
A .
上下文切换
B .
中断服务程序
C .
调度器
D .
异常处理程序
解析:p511 调度是由内核中的调度器代码处理的。
12.进程调度中的上下文切换包括(ABD)
A .
保存当前进程的上正文
B .
恢复某个先前被抢占的进程被保存的上下文
C .
让当前进程休眠
D .
将控制传递给这个新恢复的进程
解析:课本p511 上下文就是内核重新启动一个被抢占的进程所需的状态。他由一些对象的值组成,这些对象包括通用目的寄存器、浮点寄存器、程序计数器、用户栈、状态寄存器、内核栈和各种内核数据结构。
13.用户进程可以通过(B)访问内核代码和数据
A .
特权指令
B .
系统调用
C .
模式位
D .
程序计数器
解析:用户程序必须通过系统调用接口见解地访问内核代码和数据。
14.x86-64 Linux中,用户模式进程无法访问内核数据结构的内容。B
A .
正确
B .
错误
C .
不确定
解析: /proc /sys
15.x86-64 Linux进程中,代码段是从( C )开始的。
A .
0
B .
2^48-1
C .
0x400000
D .
2^64-1
解析:课本p510 地址空间底部是保留给用户程序的,包括通常的代码、数据、堆和栈段。代码段总是0x400000开始。
16.三个进程的起始和结束时间如下图,互为并发的是(AC)
A .
AB
B .
AC
C .
BC
D .
以上都是
解析:p509 8.1 如果两个流并发的运行在不同的处理器和或者计算机上,那我们称他们并发的运行。
17.进程提供给应用程序的关键抽象让我们的程序感觉独占了处理器和内存。(C)提供了独占处理器的假象。
A .
地址空间
B .
虚拟内存
C .
逻辑控制流
D .
指令控制流
解析:p508 即使在系统中通常有许多程序在运行,进程也可以像每个程序提供一种假象,好像他在独占的使用处理器。这个PC的序列叫做逻辑控制流。
18.有关异常,下面说法正确的是(CD)
A .
系统中的异常由异常名唯一确定
B .
异常表中存放的是异常处理程序
C .
异常表的起始地址存放在异常表基址寄存器中
D .
异常处理程序运行在内核模式下
解析:课本p503
A:系统中可能的每种类型的异常都分配了一个唯一的非负整数的异常号。
B:异常表是一张跳转表,其中表目k包含异常k的处理程序代码的地址。
C:异常表的起始地址存放在异常表基址寄存器中。
D:异常处理程序运行在内核模式下。
19.进程上下文包括程序的(ABCDEF )
A .
代码和数据
B .
栈
C .
通用寄存器中的内容
D .
程序计数器
E .
环境变量
F .
打开的文件描述符的集合
解析:课本p508 上下文是由程序正确运行所需的状态组成的。这个状态包括存放在内存中的程序的代码和数据,它的栈、通用目的寄存器的内容、程序计数器、环境变量以及打开文件描述符的集合。
20.X86-64结构,Linux中系统调用(函数调用)的返回值放在()
A .
%rcx
B .
%r11
C .
%rax
D .
%rbx
解析:课本p506 从系统调用返回时,寄存器%rax包含返回值。
21.图中第(D)行给出write(2)要写的字节数
A .
9
B .
10
C .
11
D .
12
解析:p507 第10~12行设置参数列表
22.图中代码用到的系统调用是(C)
A .
open(2)
B .
read(2)
C .
write(2)
D .
close(2)
解析:课本p507 第9~13行调用write函数
23.x86-64中,Linux系统调用的系统调用号是通过(B)传递的。
A .
栈
B .
%rax
C .
%rdi
D .
%rbp
E .
%rsp
解析:课本p506 寄存器%rax包含系统调用号
24.调用fork(2)的系统调用号是(D)
A .
0
B .
2
C .
3
D .
57
解析:课本p507 编号:57
函数名称:fork
描述:创建进程
25.调用fork(2)的系统调用号是(A)
A .
0
B .
2
C .
3
D .
57
解析:课本p506 C程序用syscall函数可以直接调用任何系统调用。
26.异步异常是同处理器外部的I/O设备中的事件产生的(硬件产生),同步异常是执行一条指令的直接产物(软件产生)。下面是同步异常的是(BCD)
A .
中断
B .
陷阱
C .
故障
D .
终止
解析:p504 陷阱是有意的异常,是执行一条指令的结果;故障由错误情况引起,他可能能够被故障处理程序修正;中之事不可恢复的致命错误造成的结果,通常是一些硬件错误。
27.系统调用属于异常中的(B)
A .
中断
B .
陷阱
C .
故障
D .
终止
解析:课本pp504 p501 系统调用的处理:陷阱处理程序将控制返回值给应用程序控制流中的下一条指令。
28.Linux中,信号(Signal)是一种(C)异常控制流。
A .
硬件层
B .
操作系统层
C .
用户层
D .
网络层
解析:p501 在应用层,一个进程可以发送信号到另一个进程
29.中断是(A)的异常控制流。
A .
硬件层
B .
操作系统层
C .
应用层
D .
网络层
解析:在硬件层,硬件检测到的事件会触发控制突然转移到她的另一个信号处理程序,即中断。