发布时间 : 星期五 文章第三章习题-ddg更新完毕开始阅读
4 return a[i][j] + b[j][i]; 5 }
已知函数sumij的过程体对应的汇编代码如下: 1 movl 8(?p), ìx 2 movl 12(?p), íx 3 leal (,ìx, 8), êx 4 subl ìx, êx 5 addl íx, êx 6 leal (íx, íx, 4), íx 7 addl ìx, íx 8 movl a(, êx, 4), êx 9 addl b(,íx, 4), êx
根据上述汇编代码,确定M和N的值。
23.假设函数st_ele的C代码如下,其中,L、M和N是用#define声明的常数。
1 int a[L][M][N]; 2
3 int st_ele(int i, int j, int k, int *dst) { 4 *dst = a[i][j][k]; 5 return sizeof(a); 6 }
已知函数st_ele的过程体对应的汇编代码如下: 1 movl 8(?p), ìx 2 movl 12(?p), íx 3 leal (íx,íx, 8), íx 4 movl ìx, êx 5 sall $6, êx 6 subl ìx, êx 7 addl êx, íx 8 addl 16(?p), íx 9 movl a(, íx, 4), êx 10 movl 20(?p), íx 11 movl êx, (íx) 12 movl $4536, êx
根据上述汇编代码,确定L、M和N的值。
24.假设函数trans_matrix的C代码如下,其中,M是用#define声明的常数。
1 void trans_matrix(int a[M][M]) { 2 int i, j, t; 3 for (i = 0; i < M; i++) 4 for (j = 0; j < M; j++) { 5 t = a[i][j]; 6 a[i][j] = a[j][i]; 7 a[j][i] = t; 8 } 9 }
已知采用优化编译(选项-O2)后函数trans_matrix的内循环对应的汇编代码如下: 1 .L2: 2 movl (?x), êx 3 movl (%esi, ìx, 4), íx 4 movl êx, (%esi, ìx, 4) 5 addl $1, ìx 6 movl íx, (?x) 7 addl $76, ?x 8 cmpl íi, ìx 9 jl .L2
根据上述汇编代码,回答下列问题或完成下列任务。
(1)M的值是多少?常数M和变量j分别存放在哪个寄存器中? (2)写出上述优化汇编代码对应的函数trans_matrix的C代码。
25.假设结构类型node的定义、函数np_init的C代码及其对应的部分汇编代码如下:
struct node { int *p; struct { int x; int y; } s;
struct node *next; };
void np_init(struct node *np) { np->s.x = ; np->p = ; np->next= ; } movl 8(?p), êx movl 8(êx), íx movl íx, 4(êx) leal 4(êx), íx movl íx, (êx) movl êx, 12(êx)
回答下列问题或完成下列任务。
(1)结构node所需存储空间有多少字节?成员p、s.x、s.y和next的偏移地址分别
为多少?
(2)根据汇编代码填写np_init中缺失的表达式。
26.假设联合类型utype的定义如下: typedef union { struct { int x; short y; short z; } s1 struct { short a[2]; int b;
char *p;
} s2 } utype;
若存在具有如下形式的一组函数:
viod getvalue(utype *uptr, TYPE *dst) { *dst = EXPR;
}
该组函数用于计算不同表达式EXPR的值,返回值的数据类型根据表达式的类型确定。假设函数getvalue的入口参数uptr和dst分别被装入寄存器EAX和EDX中,仿照例子填写下表,说明在不同的表达式下的TYPE类型以及表达式对应的汇编指令序列(要求尽量只用EAX和EDX,不够用时再使用ECX)。
表达式EXPR uptr->s1.x uptr->s1.y &uptr->s1.z uptr->s2.a uptr->s2.a[uptr->s2.b] *uptr->s2.p TYPE类型 int 汇编指令序列 movl (êx), êx movl êx, (íx)
27.给出下列各个结构类型中每个成员的偏移量、结构总大小以及在IA-32/Linux下结构起始位置的对齐要求。 (1)struct S1 {short s; char c; int i; char d;};
(2)struct S2 {int i; short s; char c; char d;}; (3)struct S3 {char c; short s; int i; char d;}; (4)struct S4 {short s[3]; char c; };
(5)struct S5 {char c[3]; short *s; int i; char d; double e;}; (6)struct S6 {struct S1 c[3]; struct S2 *s; char d;};
28.以下是结构test的声明:
struct { char c; double d;
int i;
short s;
char *p;
long l; long long g; void *v; } test;
假设在Windows平台上编译,则这个结构中每个成员的偏移量是多少?结构总大小为多少字节?如何调整成员的先后顺序使得结构所占空间最小?
29.以下是函数getline存在漏洞和问题的C语言代码实现,右边是其对应的反汇编部分结果:
char *getline() {
char buf[8]; char *result; gets(buf);
result=malloc(strlen(buf)); strcpy(result, buf); return result; }
1 0804840c
push mov sub mov mov mov lea mov call ?p
%esp, ?p $0x28, %esp
?x, -0xc(?p) %esi, -0x8(?p) íi, -0x4(?p) -0x14(?p), %esi %esi, (%esp) 80483c9
假定有一个调用过程P调用了函数getline,其返回地址为0x80485c8,为调用getline函数而执行完call指令
时,部分寄存器的内容如下:R[ebp]=0xbffc0800,R[esp]=0xbffc07f0,R[ebx]=0x5,R[esi]=0x10,R[edi]=0x8。执行程序时从标准输入读入的一行字符串为“0123456789ABCDEF0123456789A”,此时,程序会发生段错误(segmentation fault)并中止执行,经调试确认错误是在执行getline的ret指令时发生的。回答下列问题或完成下列任务。
(1)分别画出执行第7行和第10行汇编指令后栈中的信息存放情况。要求给出存储地址和存储内容,并指
出存储内容的含义(如返回地址、EBX旧值、局部变量、入口参数等)。
(2)当执行到getline的ret指令时,假如程序不发生段错误,则正确的返回地址是什么?发生段错误是因
为执行getline的ret指令时得到了什么样的返回地址? (3)执行完第10行汇编指令后,哪些寄存器的内容已被破坏?
(4)除了可能发生缓冲区溢出以外,getline的C代码还有哪些错误?
08 04 85 c8 返回P的地址 bf fc 08 00 EBP在P中旧值 00 00 00 08 00 00 00 10 00 00 00 05 被调用者保存寄存器在P中的旧值 buf[7]~ buf[4] buf[3]~ buf[0]
08 41 39 38 返回P的地址 37 36 35 34 EBP在P中旧值 33 32 31 30 46 45 44 43 42 41 39 38 37 36 35 34 buf[7]~ buf[4] 33 32 31 30 buf[3]~ buf[0]
被调用者保存寄存器在P中的旧值
EBP EBP ESP a) 执行第7行后的栈
ESP bf fc 07 d8 gets入口参数
b) 执行第10行后的栈
30.假定函数abc的入口参数有a、b和c,每个参数都可能是带符号整数类型或无符号整数类型,而且它们的长
度也可能不同。该函数具有如下过程体:
*b += c; *a += *b;
在x86-64机器上编译后的汇编代码如下:
1 abc: 2 addl (%rdx), íi 3 movl íi, (%rdx) 4 movslq íi, %rdi 5 addq %rdi, (%rsi) 6 ret
分析上述汇编代码,以确定三个入口参数的顺序和可能的数据类型,写出函数abc可能的4种合理的函数
原型。
31.函数lproc的过程体对应的汇编代码如下:
1 2 3 4
movl movl movl movl
8(?p), íx 12(?p), ìx $255, %esi
$-2147483648, íi