嵌入式技术基础与实践-第二章学习作业

main.s文件94~101行语句的C语言描述

#include <stdio.h>
static int mMainLoopCount = 65545;
void main()
{
    for(int i = 0;i<mMainLoopCount;++i);
}

第一行显示“广州大学字样”

修改main.s文件,添加需要输出的字符串

在main函数内进行printf输出

编写1+2+...+10的程序

求和结果存入“sumresult”的内存单元,并将求和结果通过printf显示

定义使用的变量sumresult

编写循环,达到循环次数时退出循环

打印计算值

实验结果

代码

//=====================================================================
//文件名称:main.s
//功能概要:汇编编程调用GPIO构件控制小灯闪烁(利用printf输出提示信息)
//版权所有:SD-ARM(sumcu.suda.edu.cn)
//版本更新:20180810-20191018
//=====================================================================
.include "include.inc"    //头文件中主要定义了程序中需要使用到的一些常量
//(0)数据段与代码段的定义
//(0.1)定义数据存储data段开始,实际数据存储在RAM中
.section .data
//(0.1.1)定义需要输出的字符串,标号即为字符串首地址,\0为字符串结束标志
hello_information:           //字符串标号
    .ascii "-------------------------------------------------------\n"
    .ascii "金葫芦提示:                                             \n"
    .ascii "1、本程序用来示范如何输出指令所在flash单元的地址以及指令  \n"
    .ascii "所对应的机器码。                                        \n"
    .ascii "2、Debug文件夹中的.lst文件可搜索汇编指令找到对应的机器码。\n"
    .ascii "3、printf函数可根据输出格式输出参数的值。                \n"
    .ascii "------------------------------------------------------\n\0"
data_format:
    .ascii "%d\n\0"                 //printf使用的数据格式控制符

data_format1:
    .ascii "%08x:%02x\n\0"                 //printf使用的数据格式控制符,其中8表示输出位数,
                                         //0表示将输出的前面补上0,直到占满指定列宽为止
 
 /添加//

show_guangda:
    .ascii "\n广州大学\n\0"  //显示广州大学字样
result_show:
    .ascii "\n32106200054\n1+2+...+10=\0"
 
light_show1:
	.ascii "LIGHT_BLUE:ON--\n\0"    //灯亮状态提示   
light_show2:
	.ascii "LIGHT_BLUE:OFF--\n\0"   //灯暗状态提示
light_show3:
	.ascii "闪烁次数mLightCount=\0"  //闪烁次数提示
//(0.1.2)定义变量
.align 4               //.word格式四字节对齐
mMainLoopCount:		   //定义主循环次数变量
	.word 0
mFlag:				   //定义灯的状态标志,1为亮,0为暗
	.byte 'A'	
.align 4
mLightCount:
    .word 0

//定义sumresult
.align 4
sumresult:
    .word 0

//(0.2)定义代码存储text段开始,实际代码存储在Flash中
.section   .text
.syntax unified        //指示下方指令为ARM和thumb通用格式
.thumb                 //Thumb指令集
.type main function    //声明main为函数类型                     
.global main           //将main定义成全局函数,便于芯片初始化之后调用
.align 2               //指令和数据采用2字节对齐,兼容Thumb指令集

//--------------------------------------------------------------------                        
//main.c使用的内部函数声明处

//--------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程,参见书稿)
main:
//(1)======启动部分(开头)主循环前的初始化工作======================
//(1.1)声明main函数使用的局部变量

//(1.2)【不变】关总中断
	cpsid i   
//(1.3)给主函数使用的局部变量赋初值
	
//(1.4)给全局变量赋初值
	
//(1.5)用户外设模块初始化
//  初始化蓝灯, r0、r1、r2是gpio_init的入口参数
	ldr r0,=LIGHT_BLUE     //r0指明端口和引脚(用=,因常量>=256,需用ldr)
	mov r1,#GPIO_OUTPUT    //r1指明引脚方向为输出
	mov r2,#LIGHT_OFF       //r2指明引脚的初始状态为亮
	bl  gpio_init          //调用gpio初始化函数
//  初始化串口UART_User1
	mov r0,#UART_User       //串口号
	ldr r1,=UART_BAUD       //波特率
	bl uart_init            //调用uart初始化函数
//(1.6)使能模块中断
    mov r0,#UART_User       //串口号
    bl  uart_enable_re_int  //调用uart中断使能函数

//(1.7)【不变】开总中断
	cpsie  i  
//显示hello_information定义的字符串
	ldr r0,=hello_information   //待显示字符串首地址
	bl  printf		            //调用printf显示字符串
	
	//bl .   //在此打桩(.表示当前地址),理解发光二极管为何亮起来了?


//打印“广州大学”字样
    ldr r0,=show_guangda  // 待显示字符串首地址
    bl printf  // 调用printf显示字符串
    
// 计算1+2+...+10
    // 循环次数
    mov r0,#10
    // 初始化值
    mov r1,#0
loop:
    add r1,r1,r0   //r1=r1+r0
    // r0=r0-1
    sub r0,r0,#1
    // 如果r0大于0,继续循环
    cmp r0,#0
    bne loop
    //循环结束,将结果放入sumresult
    //将sumresult的首地址放入r0
    ldr r2,=sumresult
    str r1,[r2] //存数
    
    //显示结果
    ldr r0,=result_show
    bl  printf	
    ldr r0,=data_format //规定输出格式
    ldr r1,=sumresult
    ldr r1,[r1]
    bl printf
    bl .  //打桩



//(1)======启动部分(结尾)=======================================
 
//(2)======主循环部分(开头)=====================================
main_loop:                      //主循环标签(开头)
//(2.1)主循环次数变量mMainLoopCount+1
		ldr r2,=mMainLoopCount     //r2←mMainLoopCount的地址
		ldr r1, [r2]
		add r1,#1
		str r1,[r2]	
//(2.2)未达到主循环次数设定值,继续循环
        ldr r2,=MainLoopNUM
		cmp r1,r2
		blO  main_loop     //未达到,继续循环
//(2.3)达到主循环次数设定值,执行下列语句,进行灯的亮暗处理

//测试代码部分[理解机器码存储]
Label:	
	MOV  R0,#0xDE               //立即数范围为0x00~0xFF
	
	ldr r0,=data_format1        //输出格式送r0 
	ldr r1,=Label               //r1中是Label地址
	ldrb r2,[r1]                //r2中是Label地址中的数据
	bl  printf	
	
	ldr r0,=data_format1         //输出格式送r0 
	ldr r1,=Label+1              //r1中是Label+1地址
	ldrb r2,[r1]                 //r2中是Label+1地址中的数据
	bl  printf	
	
	ldr r0,=data_format1         //输出格式送r0 
	ldr r1,=Label+2              //r1中是Label+2地址
	ldrb r2,[r1]                 //r2中是Label+2地址中的数据
	bl  printf	
	
	ldr r0,=data_format1         //输出格式送r0 
	ldr r1,=Label+3              //r1中是Label+3地址
	ldrb r2,[r1]                 //r2中是Label+3地址中的数据
	bl  printf	

//(2.3.1)清除循环次数变量
		ldr r2,=mMainLoopCount     //r2←mMainLoopCount的地址
		mov r1,#0
		str r1,[r2]	
//(2.3.2)如灯状态标志mFlag为'L',灯的闪烁次数+1并显示,改变灯状态及标志	
		//判断灯的状态标志
		ldr r2,=mFlag		   
		ldr r6,[r2]
		cmp r6,#'L'			
		bne main_light_off	   //mFlag不等于'L'转
		//mFlag等于'L'情况
		ldr r3,=mLightCount	   //灯的闪烁次数mLightCount+1
		ldr r1,[r3]
		add r1,#1				
		str r1,[r3]
		ldr r0,=light_show3   //显示“灯的闪烁次数mLightCount=”
		bl  printf				
		ldr r0,=data_format    //显示灯的闪烁次数值
		ldr r2,=mLightCount
		ldr r1,[r2]
		bl  printf	
		ldr r2,=mFlag           //灯的状态标志改为'A'
		mov r7,#'A'
		str r7,[r2]             
		ldr r0,=LIGHT_BLUE      //亮灯
		ldr r1,=LIGHT_ON
		bl  gpio_set          
		ldr r0, =light_show1    //显示灯亮提示
		bl  printf	
		//mFlag等于'L'情况处理完毕,转
		b main_exit  
//(2.3.3)如灯状态标志mFlag为'A',改变灯状态及标志
main_light_off:
        ldr r2,=mFlag		   //灯的状态标志改为'L'        
		mov r7,#'L'
		str r7,[r2]   
        ldr r0,=LIGHT_BLUE      //暗灯
		ldr r1,=LIGHT_OFF
		bl  gpio_set  
        ldr r0, =light_show2    //显示灯暗提示
		bl  printf	
main_exit:
	b main_loop                 //继续循环
//(2)======主循环部分(结尾)=====================================
.end     //整个程序结束标志(结尾)

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值