第三章习题ddg概要Word文件下载.docx
《第三章习题ddg概要Word文件下载.docx》由会员分享,可在线阅读,更多相关《第三章习题ddg概要Word文件下载.docx(21页珍藏版)》请在冰豆网上搜索。
(6)movl%bx,%eax
(7)andl%esi,%esx
(8)movw8(%ebp,,4),%ax
5.假设变量x和ptr的类型声明如下:
src_typex;
dst_type*ptr;
这里,src_type和dst_type是用typedef声明的数据类型。
有以下一个C语言赋值语句:
*ptr=(dst_type)x;
若x存储在寄存器EAX或AX或AL中,ptr存储在寄存器EDX中,则对于表3.12中给出的src_type和dst_type的类型组合,写出实现上述赋值语句的机器级代码。
要求用AT&
T格式汇编指令表示机器级代码。
表3.12题5用表
src_type
dst_type
机器级表示
char
int
unsigned
short
unsignedchar
6.假设某个C语言函数func的原型声明如下:
voidfunc(int*xptr,int*yptr,int*zptr);
函数func的过程体对应的机器级代码用AT&
T汇编形式表示如下:
1movl8(%ebp),%eax
2movl12(%ebp),%ebx
3movl16(%ebp),%ecx
4movl(%ebx),%edx
5movl(%ecx),%esi
6movl(%eax),%edi
7movl%edi,(%ebx)
8movl%edx,(%ecx)
9movl%esi,(%eax)
请回答下列问题或完成下列任务。
(1)在过程体开始时三个入口参数对应实参所存放的存储单元地址是什么?
(提示:
当前栈帧底部由帧指针寄存器EBP指示)
(2)根据上述机器级代码写出函数func的C语言代码。
7.假设变量x和y分别存放在寄存器EAX和ECX中,请给出以下每条指令执行后寄存器EDX中的结果。
(1)leal(%eax),%edx
(2)leal4(%eax,%ecx),%edx
(3)leal(%eax,%ecx,8),%edx
(4)leal0xC(%ecx,%eax,2),%edx
(5)leal(,%eax,4),%edx
(6)leal(%eax,%ecx),%edx
8.假设以下地址以及寄存器中存放的机器数如表3.13所示。
表3.13题8用表
地址
机器数
寄存器
0x8049300
0xfffffff0
EAX
0x08049300
0x8049400
0x80000008
EBX
0x00000100
0x8049384
0x80f7ff00
ECX
0x00000010
0x8049380
0x908f12a8
EDX
0x00000080
分别说明执行以下指令后,哪些地址或寄存器中的内容会发生改变?
改变后的内容是什么?
条件标志OF、SF、ZF和CF会发生什么改变?
(1)addl(%eax),%edx
(2)subl(%eax,%ebx),%ecx
(3)orw4(%eax,%ecx,8),%bx
(4)testb$0x80,%dl
(5)imull$32,(%eax,%edx)
(6)decw%cx
9.假设函数operate的部分C代码如下:
1intoperate(intx,inty,intz,intk)
2{
3intv=;
4returnv;
5}
以下汇编代码用来实现第3行语句的功能,请写出每条汇编指令的注释,并根据以下汇编代码,填写operate函数缺失的部分。
1movl12(%ebp),%ecx
2sall$8,%ecx
3movl8(%ebp),%eax
4movl20(%ebp),%edx
5imull%edx,%eax
6movl16(%ebp),%edx
7andl$65520,%edx
8addl%ecx,%edx
9subl%edx,%eax
10.假设函数product的C语言代码如下,其中num_type是用typedef声明的数据类型。
1voidproduct(num_type*d,unsignedx,num_typey){
2*d=x*y;
3}
函数product的过程体对应的主要汇编代码如下:
1movl12(%ebp),%eax
2movl20(%ebp),%ecx
3imull%eax,%ecx
4mull16(%ebp)
5leal(%ecx,%edx),%edx
6movl8(%ebp),%ecx
7movl%eax,(%ecx)
8movl%edx,4(%ecx)
请给出上述每条汇编指令的注释,并说明num_type是什么类型。
11.已知IA-32是小端方式处理器,根据给出的IA-32机器代码的反汇编结果(部分信息用x表示)回答问题。
(1)已知je指令的操作码为01110100,je指令的转移目标地址是什么?
call指令中的转移目标地址0x80483b1是如何反汇编出来的?
804838c:
7408jexxxxxxx
804838e:
e81e000000call80483b1<
test>
(2)已知jb指令的操作码为01110010,jb指令的转移目标地址是什么?
movl指令中的目的地址如何反汇编出来的?
8048390:
72f6jbxxxxxxx
8048392:
c60500a8040801movl$0x1,0x804a800
8048399:
000000
(3)已知jle指令的操作码为01111110,mov指令的地址是什么?
xxxxxxx:
7e16jle80492e0
89d0mov%edx,%eax
(4)已知jmp指令的转移目标地址采用相对寻址方式,jmp指令操作码为11101001,其转移目标地址是什么?
8048296:
e900ffffffjmpxxxxxxx
804829b:
29c2sub%eax,%edx
12.已知函数comp的C语言代码及其过程体对应的汇编代码如下:
要求回答下列问题或完成下列任务。
(1)给出每条汇编指令的注释,并说明为什么C代码只有一个if语句而汇编代码有两条条件转移指令。
(2)按照书中图3.22给出的“if()goto…”语句形式写出汇编代码对应的C语言代码。
13.已知函数func的C语言代码框架及其过程体对应的汇编代码如下,根据对应的汇编代码填写C代码中缺失的表达式。
14.已知函数do_loop的C语言代码如下:
1shortdo_loop(shortx,shorty,shortk){
2do{
3x*=(y%k);
4k--;
5}while((k>
0)&
&
(y>
k));
6returnx;
7}
函数do_loop的过程体对应的汇编代码如下:
1movw8(%ebp),%bx
2movw12(%ebp),%si
3movw16(%ebp),%cx
4.L1:
5movw%si,%dx
6movw%dx,%ax
7sarw$15,%dx
8idiv%cx
9imulw%dx,%bx
10decw%cx
11testw%cx,%cx
12jle.L2
13cmpw%cx,%si
14jg.L1
15.L2:
16movswl%bx,%eax
请回答下列问题或完成下列任务:
(1)给每条汇编指令添加注释,并说明每条指令执行后,目的寄存器中存放的是什么信息?
(2)上述函数过程体中用到了哪些被调用者保存寄存器和哪些调用者保存寄存器?
在该函数过程体前面的准备阶段哪些寄存器必须保存到栈中?
(3)为什么第7行中的DX寄存器需要算术右移15位?
15.已知函数f1的C语言代码框架及其过程体对应的汇编代码如下,根据对应的汇编代码填写C代码中缺失部分,并说明函数f1的功能。
16.已知函数sw的C语言代码框架如下:
intsw(intx){
intv=0;
switch(x){
/*switch语句中的处理部分省略*/
}
returnv;
}
对函数sw进行编译,得到函数过程体中开始部分的汇编代码以及跳转表如下:
回答下列问题:
函数sw中的switch语句处理部分标号的取值情况如何?
标号的取值在什么情况下执行default分支?
哪些标号的取值会执行同一个case分支?
17.已知函数test的入口参数有a、b、c和p,C语言过程体代码如下:
*p=a;
returnb*c;
函数test过程体对应的汇编代码如下:
1movl20(%ebp),%edx
2movsbw8(%ebp),%ax
3movw%ax,(%edx)
4movzwl12(%ebp),%eax
5movzwl16(%ebp),%ecx
6mull%ecx,%eax
写出函数test的原型,给出返回参数的类型以及入口参数a、b、c和p的类型和顺序。
18.已知函数funct的C语言代码如下:
1intfunct(viod){
2intx,y;
3scanf(“%x%x”,&
x,&
y);
4returnx-y;
5}
函数funct对应的汇编代码如下:
1funct:
2pushl%ebp
3movl%esp,%ebp
4subl$40,%esp
5leal-8(%ebp),%eax
6movl%eax,8(%esp)
7leal-4(%ebp),%eax
8movl%eax,4(%esp)
9movl$.LC0,(%esp)//将指向字符串“%x%x”的指针入栈
10callscanf//假定scanf执行后x=15,y=20
11movl-4(%ebp),%eax
12subl-8(%ebp),%eax
13leave
14ret
假设函数funct开始执行时,R[esp]=0xbc000020,R[ebp]=0xbc000030,执行第10行call指令后,scanf从标准输入读入的值为0x16和0x100,指向字符串“%x%x”的指针为0x804c000。
回答下列问题或完成下列任务。
(1)执行第3、10和13行的指令后,寄存器EBP中的内容分别是什么?
(2)执行第3、10和13行的指令后,寄存器ESP中的内容分别是什么?
(3)局部变量x和y所在存储单元的地址分别是什么?
(4)画出执行第10行指令后funct的栈帧,指出栈帧中的内容及其地址。
19.已知递归函数refunc的C语言代码框架如下:
1intrefunc(unsignedx){
2if()
3return;
4unsignednx=;
5intrv=refunc(nx);
6return;
7}
上述递归函数过程体对应的汇编代码如下:
1movl8(%ebp),%ebx
2movl$0,%eax
3testl%ebx,%ebx
4je.L2
5movl%ebx,%eax
6shrl$1,%eax
7movl%eax,(%esp)
8callrefunc
9movl%ebx,%edx
10andl$1,%edx
11leal(%edx,%eax),%eax
12.L2:
……
ret
根据对应的汇编代码填写C代码中缺失部分,并说明函数的功能。
20.填写表3.14,说明每个数组的元素大小、整个数组的大小以及第i个元素的地址。
表3.14题20用表
数组
元素大小(B)
数组大小(B)
起始地址
元素i的地址
charA[10]
A[0]
intB[100]
B[0]
short*C[5]
C[0]
short**D[6]
D[0]
longdoubleE[10]
E[0]
longdouble*F[10]
F[0]
21.假设short型数组S的首地址AS和数组下标(索引)变量i(int型)分别存放在寄存器EDX和ECX中,下列给出的表达式的结果存放在EAX或AX中,仿照例子填写表3.15,说明表达式的类型、值和相应的汇编代码。
表3.15题21用表
表达式
类型
值
汇编代码
S
S+i
S[i]
M[AS+2*i]
movw(%edx,%ecx,2),%ax
S[10]
S[i+2]
short*
AS+2*i+4
leal4(%edx,%ecx,2),%eax
S[i]-S
S[4*i+4]
*(S+i-2)
22.假设函数sumij的C代码如下,其中,M和N是用#define声明的常数。
1inta[M][N],b[N][M];
2
3intsumij(inti,intj){
4returna[i][j]+b[j][i];
已知函数sumij的过程体对应的汇编代码如下:
1movl8(%ebp),%ecx
2movl12(%ebp),%edx
3leal(,%ecx,8),%eax
4subl%ecx,%eax
5addl%edx,%eax
6leal(%edx,%edx,4),%edx
7addl%ecx,%edx
8movla(,%eax,4),%eax
9addlb(,%edx,4),%eax
根据上述汇编代码,确定M和N的值。
23.假设函数st_ele的C代码如下,其中,L、M和N是用#define声明的常数。
1inta[L][M][N];
2
3intst_ele(inti,intj,intk,int*dst){
4*dst=a[i][j][k];
5returnsizeof(a);
6}
已知函数st_ele的过程体对应的汇编代码如下:
3leal(%edx,%edx,8),%edx
4movl%ecx,%eax
5sall$6,%eax
6subl%ecx,%eax
7addl%eax,%edx
8addl16(%ebp),%edx
9movla(,%edx,4),%eax
10movl20(%ebp),%edx
11movl%eax,(%edx)
12movl$4536,%eax
根据上述汇编代码,确定L、M和N的值。
24.假设函数trans_matrix的C代码如下,其中,M是用#define声明的常数。
1voidtrans_matrix(inta[M][M]){
2inti,j,t;
3for(i=0;
i<
M;
i++)
4for(j=0;
j<
j++){
5t=a[i][j];
6a[i][j]=a[j][i];
7a[j][i]=t;
8}
9}
已知采用优化编译(选项-O2)后函数trans_matrix的内循环对应的汇编代码如下:
1.L2:
2movl(%ebx),%eax
3movl(%esi,%ecx,4),%edx
4movl%eax,(%esi,%ecx,4)
5addl$1,%ecx
6movl%edx,(%ebx)
7addl$76,%ebx
8cmpl%edi,%ecx
9jl.L2
根据上述汇编代码,回答下列问题或完成下列任务。
(1)M的值是多少?
常数M和变量j分别存放在哪个寄存器中?
(2)写出上述优化汇编代码对应的函数trans_matrix的C代码。
25.假设结构类型node的定义、函数np_init的C代码及其对应的部分汇编代码如下:
回答下列问题或完成下列任务。
(1)结构node所需存储空间有多少字节?
成员p、s.x、s.y和next的偏移地址分别
为多少?
(2)根据汇编代码填写np_init中缺失的表达式。
26.假设联合类型utype的定义如下:
typedefunion{
struct{
intx;
shorty;
shortz;
}s1
shorta[2];
intb;
char*p;
}s2
}utype;
若存在具有如下形式的一组函数:
viodgetvalue(utype*uptr,TYPE*dst){
*dst=EXPR;
}
该组函数用于计算不同表达式EXPR的值,返回值的数据类型根据表达式的类型确定。
假设函数getvalue的入口参数uptr和dst分别被装入寄存器EAX和EDX中,仿照例子填写下表,说明在不同的表达式下的TYPE类型以及表达式对应的汇编指令序列(要求尽量只用EAX和EDX,不够用时再使用ECX)。
表达式EXPR
TYPE类型
汇编指令序列
uptr->
s1.x
movl(%eax),%eax
movl%eax,(%edx)
s1.y
s1.z
s2.a
s2.a[uptr->
s2.b]
*uptr->
s2.p
27.给出下列各个结构类型中每个成员的偏移量、结构总大小以及在IA-32/Linux下结构起始位置的对齐要求。
(1)structS1{shorts;
charc;
inti;
chard;
};
(2)structS2{inti;
shorts;
(3)structS3{charc;
(4)structS4{shorts[3];
};
(5)structS5{charc[3];
short*s;
doublee;
(6)structS6{structS1c[3];
structS2*s;
28.以下是结构test的声明:
struct{
charc;
doubled;
inti;
shorts;
char*p;
longl;
longlongg;
void*v;
}test;
假设在Windows平台上编译,则这个结构中每个成员的偏移量是多少?
结构总大小为多少字节?
如何调整成员的先后顺序使得结构所占空间最小?
29.以下是函数getline存在漏洞和问题的C语言代码实现,右边是其对应的反汇编部分结果:
假定