题目
解答
f:
pushl %ebp //保存old %ebp
movl %esp, %ebp //%ebp=%esp
movl 8(%ebp), %eax //%eax值变为x
movl %eax, %edx //%edx值变为x
imull 8(%ebp), %edx //%edx和x做有符号乘,结果x*x保存在%edx中
movl 12(%ebp), %ecx //%ecx值变为y
movl $0, %eax
subl %ecx, %eax //%eax-%ecx,结果-y保存在%eax中
addl %eax, %eax //%eax=-2*y
addl %edx, %eax //%eax=-2y+x*x
popl %ebp //栈的恢复
ret //返回值保存在%eax
由上述分析可知int f(int x,int y)函数返回值是x*x-2y。
main:
pushl %ebp
movl %esp, %ebp
subl $56, %esp
movl $3, -44(%ebp) //从%ebp-44到%ebp-9保存int 数组a[]
movl $-5, -40(%ebp)
movl $6, -36(%ebp)
movl $7, -32(%ebp)
movl $2, -28(%ebp)
movl $-8, -24(%ebp)
movl $10, -20(%ebp)
movl $2, -16(%ebp)
movl $4, -12(%ebp)
movl $0, -8(%ebp) //%ebp-8位置保存i,初值为0
movl $8, -4(%ebp) //%ebp-4位置保存j,初值为8
movl $0, -8(%ebp)
jmp.L3 //直接跳转到.L3
.L3:
movl -8(%ebp), %eax //将i赋值给%eax
cmpl -4(%ebp), %eax //将i和j比较,i-j改变条件码
jl .L7 //如果i<j跳转到.L7,否则顺序执行
movl $0, %eax
leave //结束main函数
ret
当i<j时,跳转到.L7:
.L7:
movl -8(%ebp), %eax //%eax=i
movl -44(%ebp,%eax,4), %eax //数组的访问,将a[i]写入%eax
testl %eax, %eax //%eax&%eax,改变条件码
js .L8 //SF=1,证明a[i]<0就跳转到.L8
当a[i]<0时跳转到.L8:
.L8:
nop //空指令
.L5:
addl $1, -8(%ebp) //i++
subl $1, -4(%ebp) //j--
.L3:
由汇编代码可知,当a[i]<0时跳转到.L8执行i++和j—操作,然后又执行判断,判断是否循环,所以对应c程序中的:
第一空for循环的判断条件为i<j,第二空则为i++,j–,第一个if语句判断条件为a[i]<0,如图:
当执行.L7中的jl .L7时,如果a[i]>0,不跳转,执行其后的汇编:
.L4:
movl -8(%ebp), %eax //%eax值变为i
movl -44(%ebp,%eax,4), %edx //%edx值变为a[i]
movl %edx, %eax
addl %eax, %eax //%edx值变为2*a[i]
addl %eax, %edx //%edx值变为3*a[i]
movl -8(%ebp), %eax
movl -44(%ebp,%eax,4), %ecx //%ecx=a[i]
movl -8(%ebp), %eax
addl $1, %eax //i=i+1
movl -44(%ebp,%eax,4), %eax //%eax=a[i+1]
addl %ecx, %eax //%eax=a[i]+a[i+1]
movl %edx,4(%esp)
//将3*a[i]放入esp+4到esp+7的内存中,做传递的第二个参数
movl %eax, (%esp)
//将a[i]+a[i+1]放入esp到esp+3的内存中,做传递的第一个参数
call f //调用f函数
movl -4(%ebp), %edx //%edx=j
movl -44(%ebp,%edx,4), %edx //%edx=a[j]
cmpl %edx, %eax //比较调用函数后得到的返回值和a[j]的大小并改变条件码
jle.L6 //如果f(a[i]+a[i+1],3*a[i])<a[j]就跳转到.L6
movl -8(%ebp), %eax //%eax=i
movl %eax, %edx //%edx=i
imull -4(%ebp), %edx //%edx=i*j
movl -8(%ebp), %eax
movl %edx, -44(%ebp,%eax,4) //a[i]=i*j
jmp.L5
.L6:
movl -8(%ebp), %eax
movl -8(%ebp), %edx
movl %edx, -44(%ebp,%eax,4) //a[i]=i
jmp.L5
由上述分析可知,如果f(a[i]+a[i+1],3a[i])<a[j]就跳转到.L6执行a[i]=i,对应C程序中的else分支,如果f(a[i]+a[i+1],3a[i])>a[j]执行a[i]=i*j.
所以for循环内部填空为:
综上,本题答案为: