第三章习题-ddg 联系客服

发布时间 : 星期四 文章第三章习题-ddg更新完毕开始阅读

1 int func(int x, int y) 2 { 3 int z = ; 4 if ( ) { 5 if ( ) 6 z = ; 7 else 8 z = ; 9 } else if ( ) 10 z = ; 11 return z; 12 }

14.已知函数do_loop的C语言代码如下:

1 short do_loop(short x, short y, short k) { 2 do { 3 x*=(y%k) ; 4 k--; 5 } while ((k>0) && (y>k)); 6 return x; 7 }

函数do_loop的过程体对应的汇编代码如下:1 movw 8(?p), %bx 2 movw 12(?p), %si 3 movw 16(?p), %cx 4 .L1:

5 movw %si, %dx 6 movw %dx, %ax 7 sarw $15, %dx 8 idiv %cx 9 imulw %dx, %bx 10 decw %cx

11 testw %cx, %cx 12 jle .L2

13 cmpw %cx, %si 14 jg .L1 15 .L2:

16 movswl %bx, êx

请回答下列问题或完成下列任务:

1 movl 8(?p), êx 2 movl 12(?p), íx 3 cmpl $-100, êx 4 jg .L1 5 cmpl êx, íx 6 jle .L2

7 addl íx, êx 8 jmp .L3 9 .L2:

10 subl íx, êx 11 jmp .L3 12 .L1:

13 cmpl $16, êx 14 jl .L4 15 andl íx, êx 16 jmp .L3 17 .L4:

18 imull íx, êx 19 .L3:

(1)给每条汇编指令添加注释,并说明每条指令执行后,目的寄存器中存放的是什么信息? (2)上述函数过程体中用到了哪些被调用者保存寄存器和哪些调用者保存寄存器?在该函数过程体前面的准备

阶段哪些寄存器必须保存到栈中?

(3)为什么第7行中的DX寄存器需要算术右移15位?

15.已知函数f1的C语言代码框架及其过程体对应的汇编代码如下,根据对应的汇编代码填写C代码中缺失部分,

并说明函数f1的功能。

1 int f1(unsigned x) 2 { 3 int y = 0 ; 4 5 6 7 while ( ) { } return ; ; 1 movl 8(?p), íx 2 movl $0, êx 3 testl íx, íx 4 je .L1 5 .L2: 6 xorl íx, êx 7 shrl $1, íx 8 jne .L2 9 .L1:

10 andl $1, êx

8 }

16.已知函数sw的C语言代码框架如下:

int sw(int x) { int v=0; switch (x) { /* switch语句中的处理部分省略 */

}

return v; }

对函数sw进行编译,得到函数过程体中开始部分的汇编代码以及跳转表如下:

1 movl 8(?p), êx 2 addl $3, êx 3 cmpl $7, êx 4 ja .L7

5 jmp *.L8( , êx, 4) 6 .L7: 7 …… 8 ……

1 .L8: 2 .long 3 .long 4 .long 5 .long 6 .long 7 .long 8 .long 9 .long

.L7

.L2 .L2 .L3 .L4 .L5 .L7 .L6

回答下列问题:函数sw中的switch语句处理部分标号的取值情况如何?标号的取值在什么情况下执行default

分支?哪些标号的取值会执行同一个case分支?

17.已知函数test的入口参数有a、b、c和p,C语言过程体代码如下: *p = a; return b*c;

函数test过程体对应的汇编代码如下:

1 2

movl 20(?p), íx movsbw 8(?p), %ax

3 movw %ax, (íx)

4 movzwl 12(?p), êx 5 movzwl 16(?p), ìx 6 mull ìx, êx

写出函数test的原型,给出返回参数的类型以及入口参数a、b、c和p的类型和顺序。

18.已知函数funct的C语言代码如下:

1 int funct(viod) { 2 int x, y; 3 scanf(“%x %x”, &x, &y); 4 return x-y; 5 }

函数funct对应的汇编代码如下: 1 funct: 2 3 4 5 6 7 8 9 10

push l movl subl leal movl leal movl movl call

?p

%esp, ?p $40, %esp

-8(?p), êx êx, 8(%esp) -4(?p), êx êx, 4(%esp) $.LC0, (%esp) scanf

//将指向字符串“%x %x”的指针入栈 //假定scanf执行后x=15,y=20

11 movl -4(?p), êx 12 subl -8(?p), êx 13 leave 14 ret

假设函数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语言代码框架如下:

1 2 3 4 5 6

int refunc(unsigned x) { if ( ) return ; unsigned nx = ; int rv = refunc(nx) ; return ;

7 }

上述递归函数过程体对应的汇编代码如下:

1

movl

8(?p), ?x

2 movl $0, êx 3 testl ?x, ?x 4 je .L2 5 movl ?x, êx 6 shrl $1, êx 7 movl êx, (%esp) 8 call refunc 9 movl ?x, íx 10 andl $1, íx 11 leal (íx, êx), êx 12 .L2: …… ret

根据对应的汇编代码填写C代码中缺失部分,并说明函数的功能。

20.填写表3.14,说明每个数组的元素大小、整个数组的大小以及第i个元素的地址。

表3.14 题20用表 数组 char A[10] int B[100] short *C[5] short **D[6] long double E[10] long double *F[10] 元素大小(B) 数组大小(B) 起始地址 &A[0] &B[0] &C[0] &D[0] &E[0] &F[0] 元素i的地址

21.假设short型数组S的首地址AS和数组下标(索引)变量i(int型)分别存放在寄存器EDX和ECX中,下列

给出的表达式的结果存放在EAX或AX中,仿照例子填写表3.15,说明表达式的类型、值和相应的汇编代码。

表3.15 题21用表 表达式 S S+i S[i] &S[10] &S[i+2] &S[i]-S S[4*i+4] *(S+i-2) 类型 short short * 值 M[AS+2*i] AS+2*i+4 movw (íx, ìx, 2), %ax leal 4(íx, ìx, 2), êx 汇编代码

22.假设函数sumij的C代码如下,其中,M和N是用#define声明的常数。

1 int a[M][N], b[N][M]; 2

3 int sumij(int i, int j) {