概述
目录
1.栈上的局部存储
2.函数调用时的参数传递
3.函数的递归调用2
4.函数的递归调用1
5.简单的函数调用
1.栈上的局部存储
题目描述
下面的汇编代码是函数func1和func2编译后生成的:
func1:
movl (%rdi), %edx
movl (%rsi), %eax
leal (%rax,%rdx), %ecx
movl %ecx, (%rdi)
subl %eax, %edx
movl %edx, (%rsi)
ret
func2:
subq $16, %rsp
movl %edi, 12(%rsp)
movl %esi, 8(%rsp)
leaq 8(%rsp), %rsi
leaq 12(%rsp), %rdi
call func1
movl 12(%rsp), %edx
movl 8(%rsp), %eax
imull %eax, %eax
imull %edx, %edx
addl %edx, %eax
addq $16, %rsp
ret
main函数已经写好了,请根据上述汇编代码设计等价的func1和func2函数:
int main(){
int a,b;
scanf("%d%d",&a,&b);
printf("%dn",func2(a,b));
return 0;
}
输入描述
输入整型数a和b
输出描述
main函数调用func2函数并输出函数的返回值,func2会嵌套调用func1函数
提示
你需要提交完整的程序,请将上面的main函数复制到你的程序中。
思路:由于我们是汇编转C,我们的C代码中不会出现像汇编中寄存器不够用的情况需要入栈等操作,翻译时出现函数的调用,一般都要push某些值入栈,然后再被调用函数中使用,体现在我们的C代码种就是直接调用函数不需要那么多多余的变量。
做题技巧:注意调用前后值的变化
AC code:
#include<stdio.h>
#define L long
void func1(int* a, int* b)
{
int t = *a;
*a = *b + *a;
*b = t - *b;
}
int func2(int a, int b)
{
//%edi
%esi
func1(&a, &b);
return b * b + a * a;
}
int main()
{
int a, b;
scanf("%d%d", &a, &b);
printf("%dn", func2(a,b));
return 0;
}
2.函数调用时的参数传递
题目描述
下面的汇编代码是函数func编译后生成的:
func:
leal (%rcx,%rdx), %edx
movslq %edx, %rdx
leaq (%rsi,%rdi), %rdi
movq %rdx, %rsi
imulq %rdi, %rsi
movswl %r9w, %r9d
movswl %r8w, %r8d
addl %r8d, %r9d
movslq %r9d, %r9
imulq %r9, %rsi
movsbl 16(%rsp), %edx
movsbl 8(%rsp), %eax
leal (%rdx,%rax), %eax
cltq
imulq %rsi, %rax
ret
main函数已经写好了,请根据上述汇编代码设计一个等价的C函数:
int main(){
int a,b;
scanf("%d%d",&a,&b);
printf("%ldn",func(a,b,a+b,a-b,a*a,b*b,a*b,a*a-b));
return 0;
}
输入描述
按照main函数的要求,输入2个整型数
输出描述
main函数调用func函数并输出函数的返回值
提示
你需要提交完整的程序,请将上面的main函数复制到你的程序中。
难点:参数太多,注意程序未给出入栈操作,所以出现栈指针的时候,所代表参数即是比6多的那些在栈种的参数。
AC code:
#include<stdio.h>
#define Int long
int func(Int a, Int b, Int c, Int d, Int e, Int f, Int g, Int h)
{
//%edi
%esi
%edx
%ecx
%r8d
%r9d
return (c + d) * (a + b) * (e + f) * (h + g);
}
int main()
{
int a, b;
scanf("%d%d", &a, &b);
printf("%ldn", func(a, b, a + b, a - b, a * a, b * b, a * b, a * a - b));
return 0;
}
3.函数的递归调用2
题目描述
下面的汇编代码是函数func编译后生成的:
func:
pushq %rbx
movl %edi, %ebx
movl $1, %eax
testl %edi, %edi
jle .L3
shrl $31, %edi
addl %ebx, %edi
sarl %edi
call func
leal 3(%rax,%rbx), %eax
.L3:
popq %rbx
ret
main函数已经写好了,请根据上述汇编代码设计一个等价的C函数:
int main(){
int a;
scanf("%d",&a);
printf("%dn",func(a));
return 0;
}
输入描述
输入整型数a
输出描述
main函数调用func函数并输出函数的返回值
提示
你需要提交完整的程序,请将上面的main函数复制到你的程序中。
本题要用到第二章关于除以2的k次幂的优化方法的知识点
技巧:找到递归结束条件,除去多余变量
AC code:
#include<stdio.h>
#define Int long
int func(int a)
{
//%edi
if(a <= 0) return 1;//递归结束条件
return func(a >> 1) + a + 3;
}
int main()
{
int a;
scanf("%d", &a);
printf("%dn", func(a));
return 0;
}
4.函数的递归调用1
题目描述
下面的汇编代码是函数func编译后生成的:
func:
pushq %rbx
movl %edi, %ebx
movl $1, %eax
cmpl $1, %edi
jle .L3
leal -1(%rbx), %edi
call func
imull %ebx, %ebx
addl %ebx, %eax
.L3:
popq %rbx
ret
main函数已经写好了,请根据上述汇编代码设计一个等价的C函数:
int main(){
int a;
scanf("%d",&a);
printf("%dn",func(a));
return 0;
}
输入描述
输入整型数a
输出描述
main函数调用func函数并输出函数的返回值
提示
你需要提交完整的程序,请将上面的main函数复制到你的程序中。
技巧:找到递归结束条件
AC code:
#include<stdio.h>
#define Int long
int func(int a)
{
//%edi
if(a <= 1) return 1;//递归结束条件
return func(a - 1) + a * a;
}
int main()
{
int a;
scanf("%d", &a);
printf("%dn", func(a));
return 0;
}
5.简单的函数调用
题目描述
下面的汇编代码是函数func1和func2编译后生成的:
func1:
leal (%rsi,%rdi), %edi
movl %edx, %eax
imull %edi, %eax
ret
func2:
leal (%rsi,%rdi), %edx
addl $2, %esi
addl $1, %edi
call func1
rep
ret
main函数已经写好了,请根据上述汇编代码设计等价的func1和func2函数:
int main(){
int a,b;
scanf("%d%d",&a,&b);
printf("%dn",func2(a,b));
return 0;
}
输入描述
输入整型数a和b
输出描述
main函数调用func2函数并输出函数的返回值,func2会嵌套调用func1函数
提示
你需要提交完整的程序,请将上面的main函数复制到你的程序中
技巧:嵌套调用
AC code:
#include<stdio.h>
#define Int long
int func1(int a, int b, int t)
{
//%edi
//%esi
//%edx
return t * (a + b);
}
int func2(int a, int b)
{
//%edi
//%esi
return
func1(a + 1, b + 2, a + b);
}
int main()
{
int a, b;
scanf("%d%d", &a, &b);
printf("%dn", func2(a, b));
return 0;
}
ending.
最后
以上就是冷酷酸奶为你收集整理的深入理解计算机系统作业2的全部内容,希望文章能够帮你解决深入理解计算机系统作业2所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复