浅谈单片机中C语言与汇编语言的转换
一、单片机课设题目要求与软件环境介绍
做了一单片机设计,要用C语言与汇编语言同时实现,现将这次设计的感受和收获,还有遇到的问题写下,欢迎感兴趣的朋友交流想法,提出建议。
单片机设计:基于51单片机的99码表设计
软件环境:Proteus8.0 + Keil4
要求:1,开关按一下,数码管开始计时。2,按两下,数码管显示静止。3,按三下,数码管数值清零。
二、C语言程序
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
uchar shi,ge,aa,keycount=,temp;
sbit anjian=P1^;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void display(shi,ge);
void key ();
void init();
void delay(uint z);
/*-----主程序-----*/
void main()
{
init(); //初始化
while()
{
key ();
if(keycount==)
TR0=; //开中断
if(keycount==)
TR0=;
if(keycount==)
{
temp=;
keycount=;
}
if(aa==){aa=;
if(temp<=)
{
temp++;display(shi,ge);
}
else
temp=;}
}
} /*------初始化程序-------*/
void init()
{
keycount=;
temp=;
TMOD=0x01;
TH0=(-)/;
TL0=(-)%;
EA=;
ET0=;
//TR0=0;
}
/*-----定时器中断-----*/
void timer0() interrupt
{
TH0=(-)/;
TL0=(-)%;
aa++;
}
/*-----显示子程序-----*/
void display(shi,ge)
{
shi=temp/;
ge=temp%;
P0=table[shi];;delay();
P2=table[ge]; ;delay();
}
/*-----按键检测子程序-----*/
void key ()
{
if(anjian==)
{
delay(); //消抖
if(anjian==)
keycount++;
}
//while(anjian==0);
//display(shi,ge); //等待按键弹起
}
/*-----延时子程序-----*/
void delay(uint z) //延时约1ms
{
uint x,y;
for(x=z;x>;x--)
for(y=;y>;y--);
}
电路仿真结果如下:
三、C语言转汇编语言步骤
好了,那么接下来我们就开始C语言——>汇编语言之旅
(1)C语言1-10行改为
ORG 0000H //汇编起始伪指令,功能是规定程序存储器中源程序或数据块存放的起始地址
ajmp STAR //ajmp无条件跳转指令
ORG 000bh
ajmp timer0
anjian equ P1. //位定义
keycount equ 40h
shi equ 41h
gewei equ 42h
aa equ 43h
temp equ 44h
tab: db 3fh,6h,5bh,4fh,66h //建表
db 6dh,7dh,7h,7fh,6fh
(2)C语言中的初始化函数 12-14行和39-49行改为
STAR:
acall init //子程序近程调用指令,功能是主程序调用子程序,调用子程序的范围为2kb
init:
mov keycount,# //keycount=
mov temp,# //temp=
mov tmod,#01h //TMOD=0x01
mov TH0,#
mov TL0,#
setb EA //位置位指令,对操作数所指出的位进行置1操作
setb ET0
setb TR0
ret
acall为子程序近程调用指令,返回用ret。
(3)C语言中15-35行是个while循环,逻辑比较繁琐,注意了!
START:
acall display
inc temp //加1指令,将操作数所指定的单元或寄存器中的内容加1
acall delay70 //近程调用delay70
x8: mov r0,keycount
cjne r0,#,F1 //cjne比较跳转指令,若r0=2则跳转到x8,否则跳转到F1。
ajmp x8
F1: mov r0,temp
cjne r0,#,START //若r0<99时,重复循环,否则temp=
mov temp,#
ajmp START
F9:
acall key
mov r0,keycount
cjne r0,#,F2 //keycount=0顺序执行,否则跳转到F1
CLR P1. //清0
SETB TR0 F2: mov r0,keycount //第二次按键
cjne r0,#,F2
clr TR0
reti
mov r0,keycount //第三次按键
cjne r0,#,F3
mov temp,#
mov keycount,#
inc 增量指令,功能是将操作数所指定的单元或寄存器中的内容加1,其结果返还回原操作数单元中。
clr 位复位,功能是对操作数所指出的位进行清“0”操作。
或者在中断函数中
timer0:
w1:
acall key
mov TH0,#
mov TL0,#
cpl p1.
JB keycount,x2
ajmp x3
x2:
ajmp START
clr p1.
ajmp w1
ajmp w1 x3: mov r0,keycount
cjne r0,#,w1 //若r0=3则顺序执行,否则跳转到w1
mov temp,#
mov keycount,#
ret
(4)C语言58-64行display函数改为
display:
mov a,temp
mov b,#
div ab //除法指令,实现两个八位无符号数的除法操作。
mov r2,A
mov r3,B
mov dptr,#tab //16位数据传送使用方式
mov a,r2
movc a,@a+dptr //查表,先将累加器A的内容与数据指针寄存器DPTR的内容相加,再以其结果为地址,将该地址的结果送入A中
mov P0,a
acall delay70
nop //空指令
mov a,r3
movc a,@a+dptr
mov P2,a
nop
acall delay70
ret
div为除法指令,功能是实现两个8位无符号数的除法操作,一般被除数放在累加器A中,除数放在寄存器B中。指令执行后,商放在A中,余数放在B中。
movc为查表指令,先将累加器A的内容与数据指针寄存器DPTR的内容相加,再以其结果为地址,将该地址的内容送入A中。
nop为空操作指令,它不作任何操作,但要占用一个机器周期(即12个振荡周期)的时间,常用于延时或等待。(有些程序执行的效果由于延时时间太短,在人眼视觉暂时作用下无法辨认清楚)
此段程序的作用在于将一个两位数分别分在一个十位上的数码管和一个个位上的数码管显示。
(5)C语言66-76行key函数改为
key:
jb anjian,F6 //若anjian=0则顺序执行,否则跳转到F6
ACALL delay5
inc keycount //keycount++
F6:
ret
jb为位条件转移指令,功能是若直接寻址的位bit=1,则程序转移到指定的目标地址去执行,若bit=0,则程序顺序执行。
(6)C语言78-83行delay函数改为
delay70:
mov r6,#
D2: mov R7,#
d1: djnz R7,d1 //*70次
djnz R6,D2
ret delay5:
mov r6,# //消抖。
F7: mov R7,#
F8: djnz r7,F8 //*5次
djnz r6,F7
ret
注意:248=28 ,约等于1ms。delay为延时程序。
温馨提示:在汇编中程序代码的大小写不受影响,但在C语言中就有影响了。
四、思考
思考1:ret 和 reti都是程序返回指令,有什么区别?
我的回答:ret是子程序返回指令,reti是中断子程序返回指令。区别在于如果是acall 、lcall指令调用的子程序,返回指令就用ret;如果地址是0003,0013,000B,001B,0023调用的子程序,返回指令就用reti。
思考2:mov 20h,#0h 和 setb 20h 都是加1,用什么区别?
我的回答:mov指令中的20h指字节,setb中的20h是位。
五、感受
还记得前段时间我一直纠结于汇编语言中的各种指令的语法和功能,直到一个阳光明媚的中午,我一手拿着已经写好的两页半的C语言代码,一手拿着一本单片机的汇编指令查询手册,开始一行一行的翻译,可能汇编代码会在调试中有所错误,但基本逻辑是对的。而且这次C——>汇编,使我更加深入地理解了数据在计算机中的存储与调用。在此期间班主任和同学也给我答疑解惑,相信在以后的道路上,我会更加更深入地理解计算机。
至今记得班主任对我说的一段话,在此转述如下:这辈子你可能都不会用汇编语言写代码,但我要求你们用C语言转汇编,是让你们体会数据在底层的存储过程,这样在以后你们用高级语言写程序时,不会犯看似低级但又无法避免的错误(大概意思就是这样)。
感谢我的老师,如果没有他的指引,我估计就无法体会计算机底层蕴含的神奇之处。
浅谈单片机中C语言与汇编语言的转换的更多相关文章
- 浅谈Linux中的信号处理机制(二)
首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...
- 浅谈Java中的对象和引用
浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...
- 浅谈C中的malloc和free
转自http://bbs.bccn.net/thread-82212-1-1.html非常感谢作者 浅谈C中的malloc和free 在C语言的学习中,对内存管理这部分的知识掌握尤其重要!之前对C中的 ...
- 【转】浅谈Java中的hashcode方法(这个demo可以多看看)
浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...
- 浅谈Java中的final关键字
浅谈Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...
- 【转】浅谈Java中的hashcode方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个 ...
- 浅谈.net中数据库操作事务
.net中的事务 关键几点 概念:1:什么是事务 2:什么时候用事务 3:基本的语法 (1): 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常 ...
- 浅谈 .NET 中的对象引用、非托管指针和托管指针 理解C#中的闭包
浅谈 .NET 中的对象引用.非托管指针和托管指针 目录 前言 一.对象引用 二.值传递和引用传递 三.初识托管指针和非托管指针 四.非托管指针 1.非托管指针不能指向对象引用 2.类成员指针 五 ...
- 浅谈Java中的hashcode方法(转)
原文链接:http://www.cnblogs.com/dolphin0520/p/3681042.html 浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地 ...
随机推荐
- Java多线程基础学习(一)
1. 创建线程 1.1 通过构造函数:public Thread(Runnable target, String name){} 或:public Thread(Runnable target ...
- C# 注册 Windows 热键
闲扯: 前几日,一个朋友问我如何实现按 F1 键实现粘贴(Ctrl+V)功能,百度了一个方法,发给他,他看不懂(已经是 Boss 的曾经的码农),我就做了个Demo给他参考.今日得空,将 Demo 整 ...
- 用CIL写程序:你好,沃尔德
前言: 项目紧赶慢赶总算在年前有了一些成绩,所以沉寂了几周之后,小匹夫也终于有时间写点东西了.以前匹夫写过一篇文章,对CIL做了一个简单地介绍,不过不知道各位看官看的是否过瘾,至少小匹夫觉得很不过瘾. ...
- Oracle碎碎念~2
1. 如何查看表的列名及类型 SQL> select column_name,data_type,data_length from all_tab_columns where owner='SC ...
- 一个表缺失索引发的CPU资源瓶颈案例
背景 近几日,公司的应用团队反应业务系统突然变慢了,之前是一直比较正常.后与业务部门沟通了解详情,得知最近生意比较好,同时也在做大的促销活动,使得业务数据处理的量出现较大的增长,最终系统在处理时出现瓶 ...
- Velocity笔记--使用Velocity获取动态Web项目名的问题
以前使用jsp开发的时候,可以通过request很轻松的获取到根项目名,现在换到使用velocity渲染视图,因为已经不依赖servlet,request等一些类的环境,而Web项目的根项目名又不是写 ...
- HTML学习笔记
HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...
- 微信小程序开发日记——高仿知乎日报(下)
本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP 要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该 ...
- Android Weekly Notes Issue #234
Android Weekly Issue #234 December 4th, 2016 Android Weekly Issue #234 本期内容包括: ConstraintLayout的使用; ...
- Atitit.研发团队的管理原则---立长不立贤与按资排辈原则
Atitit.研发团队的管理原则---立长不立贤与按资排辈原则 1. 组织任命原则概述1 2. 历史的角度看,大部分组织使用的立长不立贤原则1 3. 论资排辈 立长不立贤原则1 3.1. 资格和辈分是 ...