计算机导论课作业 08 (基于Python)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值