3、 (20 points)请用SEAL写出和执行汇编语言程序。输入一个正整数,放在寄存器R0中,请用最简单的方式计算出它的二进制数有多少个1,将结果放在R1中,并打印。例如 move R0, 13, 结果是3。
请在注释中写出你的Python对应代码,把你的全部代码拷贝到word报告中,并将程序的运行结果截图粘贴到报告中。
a = 13
b = 0
while(a!=0):
if(a%2):
b+=1
a//=2
print(b)
SEAL代码:
mov R0,13
mov R1,2
mov R15,0
L1:
div R2,R0,2 #R2就是R0//2的情况
mul R3,R2,2 #R3是R2的两倍
sub R3,R0,R3 #R3变成了R0 mod 2的情况
beqz R3,L2 #R3是0,说明不用+1
add R15,R15,1
mov R0,R2 #R2的数值给R0
beqz R0,L3 #R0没了去L3
goto L1
L2:
mov R0,R2 #R2的数值给R0
beqz R0,L3 #R0没了去L3
goto L1
L3:
_pr R15
4、(20 points)请用SEAL写出和执行汇编语言程序。输入一个整数列表,计算整数列表中为偶数并且大于10的数值和,以_data的形式输入,此数组中的第一个数代表列表的长度,然后是列表的整数值,例如整数列表[5,2,8,11,30,25,100],在_data1的形式是:_data 1, [7,5,2,8,11,30,25,100]。第一个数7代表后面有7个整数,因为列表中符合的数是30与100,所以它们的和是130,将结果放在R1中,并打印。
请在注释中写出你的Python对应代码,把你的全部代码拷贝到word报告中,并将程序的运行结果截图粘贴到报告中。
L=[5,2,8,11,30,25,100]
a = 0
for i in range(len(L)):
if(L[i]>10):
if(L[i]%2==0):
a+=L[i]
print(a)
汇编代码
_data 0,[7,5,2,8,11,30,25,100]
mov R10,0
mov R11,1
load R2,(0)
L1:
load R1,0(R11)
#先判断R11是否达到7了
sle R3,R11,R2
beqz R3,L10
sle R3,R1,10 #R1>10的话R3变成0
beqz R3,L4
goto L2
L2:
add R11,R11,1
goto L1
L3:
add R10,R10,R1
add R11,R11,1
goto L1
L4:
div R3,R1,2
mul R3,R3,2
sub R3,R1,R3
beqz R3,L3
goto L2
L10:
_pr R10
5、(20 points)请完全按照SEAL的函数调用方式,描述主函数是如何调用子函数F()时,建立栈帧的过程,以及如何返回。请忠实写出SEAL的汇编代码,不要做任何简化,你只要写出调用函数和离开函数时那部分的汇编代码就可以了。注意,F函数的x, y 是局部变量,在栈帧中是有位置的。
def F(a,b,c):
if a>b:
x=1
else:
x=2
y=a+b+c-x
return(y)
F(1,2,3) #_pr 结果
call L10
L10:
#R1,R2,R0代表a,b,c 并在新的函数中开启新的局部变量
mov R3,R1
mov R4,R2
mov R5,R0
slt R6,R4,R3 #R3表示a R4表示b a>b,R6变成0
beqz R6 L11
mov R11 2
goto L12
L11:
mov R11 1
goto L12
L12:
add R7,R3,R4
add R7,R7,R5
sub R7,R7,R11
ret
6、(A)(5 points)请分析如下的Python递归函数factors(), 假如去掉break会有什么问题?请用factors(18)为例,你若将break去除掉,会打印出什么结果?(B)(15 points)请用SEAL写出如下的函数。请完全按照SEAL中所描述的函数栈帧建立的方式。可用SEAL中的_pr打印。
def factors(x): #找到x的因数
y=x//2
for i in range(2,y+1):
if (x %i ==0): #发现i是x的因数
print("Factor:",i);
factors(x//i) #递归调用自己,参数变小是x//i
break #跳出for循环,为什么?
else: #假如没有碰到break,代表x是什么?
print("Prime Factor:",x)
#print("参数x:%d, 变量y:%d" %(x,y))
return
factors(18)
请在注释中写出你的Python对应代码,把你的全部代码拷贝到word报告中,并将程序的运行结果截图粘贴到报告中。
mov R1,18
call L1
L10:
L1:
div R2,R1,2 #R2代表第一层的y
mov R10,2 #
sle R9,R10,R2 #R10>R2 R9变成0,就可以停了
beqz R9,L10
div R3,R2,R10 #R10在第一层是2,然后让R2去除以R10来检验是否模2为0
mul R3,R3,R10
sub R3,R2,R3#如果是0,说明modR10确实是0
beqz R3,L2#如果是0,那么去下一个地区,否则进行else的语句
_pr R1
sub R10,R10,1
goto L1 #弄完了一个循环让R10+1然后回到L1
L2:
_pr R10
div R4,R1,2 #让x//2然后进行开下一个栈进行递归
call L3
add R10,R2,1 #实现break语句,
ret
L3:#类似L1的情况
div R5,R4,2 #R2代表第二层的y
mov R11,2 #
sle R12,R11,R4
beqz R12,L10
div R6,R4,R11
mul R6,R6,R11
sub R6,R4,R6
beqz R6,L4
_pr R1
sub R11,R11,1
ret