嵌入式简单汇编程序实例

合集下载

gcc内嵌汇编详解

gcc内嵌汇编详解

gcc内嵌汇编详解有时候我们希望在C/C++代码中使⽤嵌⼊式汇编,因为C中没有对应的函数或语法可⽤。

⽐如我最近在ARM上写FIR程序时,需要对最后的结果进⾏饱和处理,但gcc没有提供ssat这样的函数,于是不得不在C代码中嵌⼊汇编指令。

1. ⼊门在C中嵌⼊汇编的最⼤问题是如何将C语⾔变量与指令操作数相关联。

当然,gcc都帮我们想好了。

下⾯是是⼀个简单例⼦。

asm(“fsinx %1, %0”:”=f”(result):”f”(angle));这⾥我们不需要关注fsinx指令是⼲啥的;只需要知道这条指令需要两个浮点寄存器作为操作数。

作为专职处理C语⾔的gcc编译器,它是没办法知道fsinx这条汇编指令需要什么样的操作数的,这就要求程序猿告知gcc相关信息,⽅法就是指令后⾯的”=f”和”f”,表⽰这是两个浮点寄存器操作数。

这被称为操作数规则(constraint)。

规则前⾯加上”=”表⽰这是⼀个输出操作数,否则是输⼊操作数。

constraint后⾯括号内的是与该寄存器关联的变量。

这样gcc就知道如何将这条嵌⼊式汇编语句转成实际的汇编指令了:fsinx:汇编指令名%1, %0:汇编指令操作数“=f”(result):操作数%0是⼀个浮点寄存器,与变量result关联(对输出操作数,“关联”的意思就是说gcc执⾏完这条汇编指令后会把寄存器%0的内容送到变量result中)“f”(angle):操作数%1是⼀个浮点寄存器,与变量angle关联(对输⼊操作数,“关联”的意思是就是说gcc执⾏这条汇编指令前会先将变量angle的值读取到寄存器%1中)因此这条嵌⼊式汇编会转换为⾄少三条汇编指令(⾮优化):1> 将angle变量的值加载到寄存器%12> fsinx汇编指令,源寄存器%1,⽬标寄存器%03> 将寄存器%0的值存储到变量result当然,在⾼优化级别下上⾯的叙述可能不适⽤;⽐如源操作数可能本来就已经在某个浮点寄存器中了。

嵌入式实验(汇编和C语言混合编程实验)

嵌入式实验(汇编和C语言混合编程实验)

嵌入式实验(汇编和C语言混合编程实验)汇编和C语言混合编程实验7.1实验目的①掌握C程序中内嵌指令的使用方法。

②理解汇编程序调用C程序函数和变量的方法。

7.2 实验环境①硬件:PC机②软件:ADS1.27.3 实验内容①使用内嵌汇编的方法设计允许和禁止中断程序。

②验证汇编程序调用C程序函数和访问C程序变量的执行过程。

7.4 实验过程1、实验7-1 允许和禁止中断程序本实验使用内嵌汇编的方法完成允许和禁止中断程序设计,这里使用Armulator 作为调试的目标机。

(1)新建ARM工程exp7_1启动ADS开发环境,选择File→New(Project)选项,使用ARM Executable Image工程模板创建一个工程exp5_1.(2) 新建汇编程序文件exp7_1_1.c,并将其添加到工程exp7_1中选择File→New(File)选项,新建汇编源程序文件exp7_1_1.c并添加到工程exp7_1中,exp7_1_1.c源程序的参考代码如下: #include__inline void enable_IRQ(void) {int tmp;__asm {MRS tmp, CPSRBIC tmp, tmp, #0x80 MSR CPSR_c, tmp } }__inline void disable_IRQ(void) {int tmp; __asm{MRS tmp, CPSR ORR tmp, tmp, #0x80 MSR CPSR_c, tmp } }int main(void) {enable_IRQ( ); disable_IRQ( ); return 0;}(3) 设置工程exp7_1的编译和链接选项选择Edit→DebugRel Settings选项,打开DebugRel Settings对话框,设置工程编译和链接选项,在Language Settings→ARM Assembler选项中,选择Target选项卡,修改处理器类型为ARM920T. (4) 编译和链接工程在工程exp7_1窗口中,选择Make工具按钮,编译和链接工程exp7_1,如果有错误提示,请检查修改程序中的语法错误,直到编译和链接通过。

嵌入式汇编语言程序设计.

嵌入式汇编语言程序设计.

1.2.3 ARM汇编语言子程序调用
1.2 ARM汇编语言程序格式
1.2.1ARM汇编语言文件格式
1.2 ARM汇编语言程序格式
1.2.2ARM汇编语言程序格式
源文件的组织方式-----段 段的定义-----相对独立的,具有特定名称的,不可分割的指令或者数据序列
段的分类----代码段,数据段
1.2 ARM汇编语言程序格式
1.1.3 ARM汇编语言中的表达式
1.1 ARM汇编语言语句格式
1.1.3 ARM汇编语言中的表达式
表达式的组成 表达式中各元素的优先级
1.1 ARM汇编语言语句格式
1.1.3 ARM汇编语言中的表达式
1.1 ARM汇编语言语句格式
1.1.3 ARM汇编语言中的表达式
1.1 ARM汇编语言语句格式
1.3 ARM汇编语言程序设计举例
伪操作实例
1.3 ARM汇编语言程序设计举例
伪操作实例
字符串变量:Jaldjflj
aljfjlfj
1.3 言中的符号—变量:
变量替换
1.1 ARM汇编语言语句格式
1.1.2ARM汇编语言中的符号—变量:
变量替换
1.1 ARM汇编语言语句格式
1.1.2ARM汇编语言中的符号—数字常量:
数字常量的取值范围
数字常量的声明与赋值
1.1 ARM汇编语言语句格式
1.1.2ARM汇编语言中的符号—标号:
1.1 ARM汇编语言语句格式
9、 FILED
使用示例: MAP 0x100 ; 定义结构化内存表首地址的值为0x100。 A FIELD 16 ; 定义A的长度为16字节,位置为0x100 B FIELD 32 ; 定义B的长度为32字节,位置为0x110 S FIELD 256 ;定义S的长度为256字节,位置为0x130

嵌入式汇编

嵌入式汇编

本节是第一次在内核源程序中接触到C语言中的嵌入式汇编代码。

由于我们在通常的C语言程序的编制过程中一般是不会使用嵌入式汇编程序的,因此这里有必要对其基本格式进行简单的描述,详细的说明可参见GNU gcc手册中[5]第4章的内容(Extensions to the C Language Family),或见参考文献[20](Using Inline Assembly with gcc)。

具有输入和输出参数的嵌入汇编的基本格式为:asm(“汇编语句”: 输出寄存器: 输入寄存器: 会被修改的寄存器);其中,“汇编语句”是你写汇编指令的地方;“输出寄存器”表示当这段嵌入汇编执行完之后,哪些寄存器用于存放输出数据。

此地,这些寄存器会分别对应一C 语言表达式或一个内存地址;“输入寄存器”表示在开始执行汇编代码时,这里指定的一些寄存器中应存放的输入值,它们也分别对应着一C变量或常数值。

下面我们用例子来说明嵌入汇编语句的使用方法。

我们在下面列出了前面代码中第22行开始的一段代码作为例子来详细解说,为了能看清楚我们将这段代码进行了重新编排和编号。

01 #define get_seg_byte(seg,addr) \02 ({ \03 register char __res; \04 __asm__("push %%fs; \05 mov %%ax,%%fs; \06 movb %%fs:%2,%%al; \07 pop %%fs" \08 :"=a" (__res) \09 :"" (seg),"m" (*(addr))); \10 __res;})这段10行代码定义了一个嵌入汇编语言宏函数。

因为是宏语句,需要在一行上定义,因此这里使用反斜杠'\'将这些语句连成一行。

这条宏定义将被替换到宏名称在程序中被引用的地方。

第1行定义了宏的名称,也即是宏函数名称get_seg_byte(seg,addr)。

单片机汇编语言设计实例详解

单片机汇编语言设计实例详解

单片机汇编语言设计实例详解引言:单片机是嵌入式系统中常见的控制器,它具有体积小、功耗低、成本低等特点,被广泛应用于家电、汽车、工业控制等领域。

而汇编语言作为单片机的底层语言,直接操作硬件资源,具有高效性和灵活性。

本文将以一个实例,详细讲解如何使用单片机汇编语言进行设计。

实例背景:假设我们要设计一个温度检测系统,要求实时监测环境温度,并在温度超过某个阈值时触发报警。

硬件准备:1. 单片机:我们选择一款常用的8051单片机作为例子。

2. 温度传感器:我们选择一款数字温度传感器,它可以通过串行通信与单片机进行数据交互。

3. 显示屏:为了方便实时显示温度信息,我们选用一款数码管显示屏。

软件准备:1. Keil C51:这是一款常用的单片机开发软件,支持汇编语言的编写和调试。

2. 串口调试助手:用于测试串口通信功能。

设计步骤:1. 硬件连接:将单片机与温度传感器、显示屏连接起来。

注意接线的正确性和稳定性。

2. 编写初始化程序:使用汇编语言编写单片机的初始化程序,包括端口初始化、中断向量表设置、定时器初始化等。

3. 串口通信设置:通过串口与温度传感器进行数据交互,需要设置串口通信的波特率、数据位数、停止位等参数。

4. 温度检测程序:编写汇编语言程序,实时读取温度传感器的数据,并将数据送至显示屏进行显示。

5. 温度报警程序:在温度超过设定阈值时,触发报警程序,可以通过蜂鸣器等外设发出警报信号。

6. 调试与测试:使用Keil C51进行程序调试,通过串口调试助手测试串口通信和温度显示、报警功能。

设计思路:1. 初始化程序设计:先设置端口的输入输出方向,再设置中断向量表,最后初始化定时器。

这样可以确保程序的稳定性和可靠性。

2. 串口通信设置:根据温度传感器的通信协议,设置串口的波特率、数据位数、停止位等参数。

注意要与传感器的通信规范保持一致。

3. 温度检测程序设计:通过串口读取温度传感器的数据,并进行相应的处理。

常见的嵌入式编程案列

常见的嵌入式编程案列

常见的嵌入式编程案列
【1】用#define声明一个常数,用以表示一年中有多少秒
#define SECONDS_PER_YEAR (60*60*24*365)UL
说明:首先,末尾#define语法末尾不能有分号;
其次,计算式最好带括号;
第三,这个表达式会使16位机的整型数溢出,因此需要用长整型符号L告诉编译器这个常数是长整型数,末尾用UL(无符号长整型)。

【2】用C编写死循环
第一种方案:while(1){}
第二种方案:for(;;){}
第三种方案:Loop:
goto Loop; //这种方案是用汇编写的
【3】访问特定内存位置:
在某工程中,一个整型变量的绝对地址是0x67a9,请将其设置为0xaa55,并且已知编译器是一个纯粹的ANSI编译器,请编写代码
int* ptr;
ptr=(int*)0x67a9;
*ptr=0xaa55;
【4】对中断服务代码的评论
以上程序有如下几个错误:
1、ISR不能返回一个值;
2、ISR不能传递参数,即不能有形参;
3、在许多处理器或编译器中,浮点数一般是不可重入的。

有些处理器或编译器需要使用额外的寄存器入栈,有些处理器或编译器是不允许在ISR中做浮点运算。

此外,ISR应该。

Gcc嵌入式汇编

Gcc嵌入式汇编

2.6.3 Gcc嵌入式汇编在Linux的源代码中,有很多C语言的函数中嵌入一段汇编语言程序段,这就是gcc提供的“asm”功能,例如在include/asm-i386/system.h中定义的,读控制寄存器CR0的一个宏read_cr0():#define read_cr0() ({ \unsigned int __dummy; \__asm__( \"movl %%cr0,%0\n\t" \:"=r" (__dummy)); \__dummy; \})这种形式看起来比较陌生,这是因为这不是标准C所定义的形式,而是gcc 对C语言的扩充。

其中__dummy为C函数所定义的变量;关键词__asm__表示汇编代码的开始。

括弧中第一个引号中为汇编指令movl,紧接着有一个冒号,这种形式阅读起来比较复杂。

一般而言,嵌入式汇编语言片段比单纯的汇编语言代码要复杂得多,因为这里存在怎样分配和使用寄存器,以及把C代码中的变量应该存放在哪个寄存器中。

为了达到这个目的,就必须对一般的C语言进行扩充,增加对编译器的指导作用,因此,嵌入式汇编看起来晦涩而难以读懂。

1. 嵌入式汇编的一般形式:__asm__ __volatile__ ("<asm routine>" : output : input : modify);其中,__asm__表示汇编代码的开始,其后可以跟__volatile__(这是可选项),其含义是避免“asm”指令被删除、移动或组合;然后就是小括弧,括弧中的内容是我们介绍的重点:·"<asm routine>"为汇编指令部分,例如,"movl %%cr0,%0\n\t"。

数字前加前缀“%“,如%1,%2等表示使用寄存器的样板操作数。

可以使用的操作数总数取决于具体CPU 中通用寄存器的数量,如Intel可以有8个。

实验二 ARM嵌入式系统应用 汇编语言编程一

实验二   ARM嵌入式系统应用   汇编语言编程一

实验二
实验项目名称:ARM处理器寻址方式:
实验目的和要求:对ARM处理器的六种寻址方式进行练习。

实验原理:根据不同寻址方式,运行ARM指令,观察运行结果。

主要仪器设备:台式计算机、windows操作系统、应用软件等。

实验方法与步骤:1、根据6种寻址方式,输入ARM指令。

2、运行软件例程,观察结果。

实验数据记录、处理及结果分析:
寄存器寻址方式(P37---P40 每种寻址方式写出一条指令即可)
1、寄存器寻址:
2、立即寻址:
3、寄存器间接寻址:
4、变址寻址:
5、寄存器移位寻址:
6、多寄存器寻址:
综合练习:
(P43 指令示例运行结果观察:共8条指令选4条指令)
LDR R3, [R4] ;写出目标寄存器中的结果,如R3=0x?
…….
LDR R3, [R1], R2, LSL #3。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ARM实验报告
姓名:郭健傧学号:L2101898
1.实验目的
(1)了解ADS1.2集成开发环境及ARMulator软件仿真;
(2)熟悉ARM的乘法指令和逻辑指令;
(3)结合ARM处理器硬件特性,比较处理函数的特性;
2.实验设备
硬件:pc机一台;
软件:Windowsxp系统,ADS1.2集成开发环境;
3.实验内容
(1)建立一个新的工程;
(2)建立一个汇编文件,并添加到工程;
(3)根据所给的两个C语言函数编写相应的汇编程序,并比较一下代码中fact1和fact2两个函数的特性;
4.实验步骤
(1)启动ADS1.2IDE集成开发环境,使用ARM Executable Image 工程模块建立一个工程heiye。

(2)建立汇编源文件test.s,编写程序实验,并添加到工程heiye中。

(3)设置工程连接地址Ro Base为0x40000000,RWBase为0x40003000。

设置调试入口地址Image entry point为0x40000000。

(4)编译链接工程,并启动AXD进行软件仿真调试。

5.编写程序如下:
C程序源代码:
int fact1(int limit)
{ int fact=1;
for(i=1;i<limit;i++)
fact*=i;
return fact;}
int fact2(int limit)
{int fact=1;
for(i=limit;i!=0;i--)
fact*=i;
return fact;}
(1)编写相应的汇编代码1:
;n!arithmetic
AREA heiye1,CODE,READONLY
CODE32
ENTRY
Main
LDR R0,limit ;装载limit
LDR R1,fact ;装载fact
MOV R2,R1 ;把r2设置为1
BL CYCLE ;调用循环程序
STR R1,result ;将结果存储到内存
MOV R0,#0x18 ;执行中止
SWI 0x123456
CYCLE
MUL R3,R1,R2
MOV R1,R3
ADD R2,R2,#1
CMP R0,R2 ;比较R0和R2的大小并修改状态位
BNE CYCLE
MOV PC,LR
AREA NUM,DATA,READWRITE ;定义数据段
fact DCD 1
limit DCD 0x0000000A
result DCD 0
END
(2)编写相应的汇编程序2:
;n!arithmetic
AREA heiye2,CODE,READONLY
CODE32
ENTRY
Main
LDR R0,limit ;装载limit
LDR R1,fact ;装载fact
BL CYCLE ;调用循环程序
STR R1,result ;将结果存储到内存
MOV R0,#0x18 ;执行中止
SWI 0x123456
CYCLE
MUL R3,R1,R0
MOV R1,R3
SUBS R0,R0,#1
BNE CYCLE ;判断R0是否为零
MOV PC,LR
AREA NUM,DATA,READWRITE ;定义数据段
fact DCD 1
limit DCD 0x0000000A
result DCD 0
END
6.程序中出现的问题
(1)刚开始时,由于马虎把result也写成了resule,导致(STR R1,result)时提示出错,经过仔细查看才发现。

程序入口ENTRY和程序结束END前没按Tab
键,编译时提示没有程序入口,这些地方要特别注意!
(2)仔细比较两个程序的运行结果会发现,第一个汇编程序运算的是(limit-1)!,第二个汇编程序运算的是(limit)!。

但当limit的取值较大时,结果溢出,暂时未能解决!请老师给予指导!
7.程序演示过程
可以单步运行程序,可以设置/取消断点,或者全程运行程序,停止运行程序,调试观看寄存器和0x40000000地址上的值,运行结果如下:
(程序1的单步运行演示)
(程序1的全程运行结果)
(程序2的单步运行演示)(程序2的全程运行结果)。

相关文档
最新文档