【ARM汇编子程序】求三个数的阶乘并求和

在这里插入图片描述

在这里插入图片描述

每篇前言

☀️作者简介:大家好我是汤姆凯特,大家可以叫我汤姆
🐋个人主页:IM汤姆凯特的CSDN博客
🎁系列专栏:【ARM嵌入式基础】
🌱每日一句:

不要试图鹤立鸡群,离开那群鸡。



在这里插入图片描述

求三个数的阶乘并求和

求解这个问题的目的是:练习汇编中子程序的建立和调用。

想求三个数的阶乘并求和,一共分为两个步骤,先对三个阶乘分别求阶乘,然后将三个数求和并输出,下面分步骤详解。

一、用子程序求阶乘

1.确定子程序的输入值

先定义全局变量

.data 
    a:.word 2
    b:.word 3
    c:.word 4

将r0作为子程序的输入,因此每次都先将待求阶乘的数取到寄存器r0

    ldr r0,=a 
    ldr r0,[r0]

然后用跳转指令进入子程序

	bl fact

2.循环累乘求解

先给子程序构建框架

fact:
    push {lr}
	......
    pop {lr}
    mov pc,lr
.end

累乘的值存到寄存器r8,给r8赋初始值

    mov r8,#1

用待求阶乘数作为循环递减变量

loop:
    mul r8,r0
    sub r0,#1
    cmp r0,#0
    bne loop

3.确定返回主程序的返回值

累乘后的值存放在r8,因此可以直接将r8作为返回值

二、3个数分别调用子程序

1.从内存取到值作为子程序输入

3个值存放在内存变量中分别叫“a,b,c”

    ldr r0,=a 
    ldr r0,[r0]
        bl fact

    ldr r0,=b 
    ldr r0,[r0]
        bl fact

    ldr r0,=c 
    ldr r0,[r0]
        bl fact

2.将3个数暂存到r1~r3

将“a,b,c”三个还没有求阶乘的数,在进入子程序前暂存到r1~r3用于输出(可以看到输出的格式串中有四个数据,所以最后一个数据需要用到压栈)

.data
	fmt:.asciz "\n %d!+ %d!+ %d!=%d\n"
main:
    mov r1,r0
        bl fact
    mov r2,r0
        bl fact
    mov r3,r0
        bl fact    

3.将返回值存到指定寄存器

每一个调用子程序求完的值都在r8,要先将这个值暂存到3个寄存器中用于求和

        bl fact
    mov r4,r8
        bl fact
    mov r5,r8
        bl fact
    mov r6,r8    
   

三、三个数求和

1.两两求和

现在三个求完阶乘的数据分别存放在r4~r6,对这三个数相加并放到r8中

    add r8,r4,r5
    add r8,r8,r6

2.压栈输出,出栈结束

在输出格式串中用到了四个数据,所以需要把第四个数据压到栈顶,然后输出完r1~r3之后,输出栈顶数据。那因此就是将r8压入栈顶。

//fmt:.asciz "\n %d!+ %d!+ %d!=%d\n"
	    push {r8}
	ldr r0,=fmt
    bl printf
    	pop {r8}

完整代码

.data 
    a:.word 2
    b:.word 3
    c:.word 1
fmt:.asciz "\n %d!+ %d!+ %d!=%d\n"
.text
.globl main 
 main:
    push {lr}
    //调用3次子程序
    ldr r0,=a 
    ldr r0,[r0]
    mov r1,r0
        bl fact
    mov r4,r8
    ldr r0,=b 
    ldr r0,[r0]
    mov r2,r0
        bl fact
    mov r5,r8
    ldr r0,=c 
    ldr r0,[r0]
    mov r3,r0
        bl fact
    mov r6,r8
 	//三个数求和存到r8   
    add r8,r4,r5
    add r8,r8,r6
    push {r8}
    ldr r0,=fmt
    bl printf
    mov r0,#0
    pop {lr}
    mov pc,lr
//子程序fact
//r0作为子程序的入口参数
//r8作为返回值
fact:
    push {lr}
    mov r8,#1
loop:
    mul r8,r0
    sub r0,#1
    cmp r0,#0
    bne loop
    pop {lr}
    mov pc,lr
.end

运行结果

在这里插入图片描述

在这里插入图片描述


本期就结束了,如果对您有帮助,点赞+评论支持一下博主再走吧
还没有关注汤姆的朋友,点个关注每天学一点汇编
下期预告: 【ARM汇编】冒泡排序

在这里插入图片描述

评论 119
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IM汤姆凯特

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值