ARM之---在C语言中内嵌汇编语言

发布者:MysticMoon最新更新时间:2016-08-04 来源: eefocus关键字:ARM  C语言  内嵌汇编语言 手机看文章 扫描二维码
随时随地手机看文章
开发Arm程序的时候,大多数时候使用C/C++语言就可以了,但汇编语言在某些情况下能够实现一些C语言无法实现的功能,这时候就要调用一些汇编语言的程序.我们需要大概了解一下在C语言中如何嵌入汇编语言.

    1.内嵌汇编语言的语法:

    __asm

    {

        指令[;指令]   

        ......

        [指令]

    }

 

    2.举例:使能/禁止IRQ中断

    __inline void enable_IRQ(void)

    {

        int tmp;

        __asm                        //嵌入汇编代码

        {

            MRS  tmp,CPSR            //读取CPSR的值

            BIC  tmp,tmp,#0x80       //将IRQ中断禁止位I清零,即允许IRQ中断

            MSR  CPSR_c,tmp          //设置CPSR的值

        }

    }

 

    __inline void disable_IRQ(void)

    {

        int tmp;

        __asm

        {

            MRS  tmp,CPSR

            ORR  tmp,tmp,#Ox80

            MSR  CPSR_c,tmp

        }

    }

 

    3.举例:字符串复制

    void my-strcpy(const char *src,char *dst)

    {

        int ch;

        __asm

        {

        loop:

    #ifndef __thumb

        LDRB ch,[src],#1

        STRB ch,[dst],#1

    #else

        LDRB ch,[src]

        ADD  src,#1

        STRB ch,[dst]

        ADD  dst,#1

    #endif

        CMP ch,#0

        BNE loop

        }

    }

 

    int main(void)

    {

        const char *a="Hello world!";

        char b[20];

        __asm

        {

             MOV  R0,a

             MOV  R1,b

             BL my_strcpy,{R0,R1}

        }

        return(0);

    }

 

    4.内嵌汇编的指令用法:

    .操作书: 内嵌的汇编指令中作为操作数的寄存器和常量可以是C表达式.这些表达式可以是char,short或int等类型,而且这些表达式都是作为无符号数进行操作的.若要有符号数,用户需要自己处理与符号有关的操作.编译器将会计算这些表达式的值,并为其分配寄存器.

    .物理寄存器:内嵌汇编中使用物理寄存器是有限制的:

        _ 不能直接向PC(程序计数器)寄存器中赋值,程序跳转只能通过B或BL指令来实现.

        _ 使用物理寄存器的指令中,不要使用过于复杂的C表达式

        _ 尽可能少的使用物理寄存器

    .常量: 在内嵌汇编指令中,常量前面的"#"可以省略

    .标号: C程序中的标号可以被内嵌的汇编指令使用.但是只有指令B可以使用C程序中的标号,而指令BL则不能使用.

    .内存单元的分配:所有内存分配均由C编译器完成,分配的内存单元通过变量供内嵌汇编器使用.内嵌汇编器不支持内嵌汇编程序中用于内存分配的伪指令.

   

    5.内嵌汇编注意事项:

    .必须小心使用物理寄存器,如R0~R3,IP,LR,CPSR中的标志位,避免发生冲突.

    例如:

        __asm

        {

            MOV  R0,x

            ADD  y,R0,x/y

        }

        改成下面代码会比较妥当:

        __asm

        {

            MOV var,x

            ADD y,var,x/y

        }

    .不要使用寄存器代替变量.

    .使用内嵌汇编无需保存和恢复寄存器.事实上,除了CPSR,SPSR寄存器,对物理寄存器先读后写都会引起汇编报错.

    .汇编语言中","号作为操作数分隔符.如果有C表达式作为操作数,若表达式中包含有",",则必须使用()将其规约为一个汇编操作数,例如:

    __asm
    {

        ADD x,y,(f(),z)    //"f(),z"为带有","的C表达式.

    }

 

    6.不同数据类型对应的汇编指令:

    unsigned char    LDRB/STRB

    unsigned short   LDRH/STRH

    unsigned int       LDR/STR

    char                   LDRSB/STRSB

    short                  LDRSH/STRSH

 

    7.访问C程序的变量:

    AREA    globals,CODE,READONLY

    EXPORT  asmsubroutine

    IMPORT  globalvar        ;声明的外部变量

asmsubroutine

    LDR  R1,=blobalval

    LDR  R0,[R1]

    ADD  R0,R0,#1

    STR  R0,[R1]

    MOV  PC,LR

    END

关键字:ARM  C语言  内嵌汇编语言 引用地址:ARM之---在C语言中内嵌汇编语言

上一篇:ARM学习之---看门狗(WatchDog)
下一篇:Arm指令集寻址方式

推荐阅读最新更新时间:2024-03-16 15:03

ARM-Linux嵌入式系统的Boot Loader分析与设计
0 引言 由Boot Loader和固化在固件(firmware)中的Boot代码(可选)共同组成一个嵌入式系统的引导加载程序。它的作用和功能就像固化到计算机内主板上的一个ROM芯片程序BIOS(basic input output system)。但是它一般不配置像BIOS那样的固件程序,这是因为要考虑经济方面的原因,因此必须自己完成这方面的工作。Boot Loader可以初始化硬件设备,建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。它的实现严重地依赖于硬件,特别是在嵌入式系统中,即使基于同一个CPU的Boot Loader,对于不同的板子,也有很大的不同。 1 Bo
[嵌入式]
ARM7单片机(学习ing)—(四)、定时器—01
大晚上的~~ 直接把文件给整理一下~~ 然后剩下的历程明天再说吧~~ 四、定时器 四—(01)、定时器相关应用和寄存器的介绍~~ 定时器0和定时器1出了外设基地址以外,其它都相同~~ 2、应用以及相关的描述: 3、管脚描述 4、寄存器描述: a、中断寄存器 b、定时器控制寄存器 c、定时器计数器 d、预分频寄存器 e、预分频计数器寄存器 f、匹配寄存器 g、匹配控制寄存器 h、捕获寄存器 i、捕获控制寄存器 j、外部匹配寄存器
[单片机]
<font color='red'>ARM</font>7单片机(学习ing)—(四)、定时器—01
TQ2440 学习笔记—— 11、嵌入式编程基础知识【arm-linux-objcopy、objdump选项】
1、arm-linux-objcopy 选项 arm-linux-objcopy 被用来复制一个目标文件的内容到另一个文件中,可以使用不同于源文件的格式来输出目的文件,即可以进行格式转换。 常用arm-linux-objcopy 来将ELF格式的可执行文件转换为二进制文件。 arm-linux-objcopy 的使用格式如下: 2、arm-linux-objdump 选项 arm-linux-objdump 用于显示二进制文件信息,常用来查看反汇编代码 使用格式如下:
[单片机]
TQ2440 学习笔记—— 11、嵌入式编程基础知识【<font color='red'>arm</font>-linux-objcopy、objdump选项】
STM32学习第四课:STM32 c语言学习基础4
1.结构体的参数传递 在进行传值的时候,用结构体封装有利于函数的传递。 用指向结构体变量的指针作为函数参数。 结构体做函数参数有三种传递方式: 一:是传递结构体变量,这是值传递 二:是传递结构体指针,这是地址传递 三:是传递结构体成员,当然这也分为值传递和地址传递。 以传引用调用方式传递结构比用传值方式传递结构效率高。以传值方式传递结构需要对整个结构做一份拷贝。 下面看一个列子,student结构体中包含该学生的各种信息,我们在change函数中对其进行部分修改,再在主函数中输出其结果 1.下面传递结构体变量 #include stdio.h #include string.h #define format %dn
[单片机]
STM32学习第四课:STM32 <font color='red'>c语言</font>学习基础4
ARM存储器结构、映射以及重新映射
ARM存储器结构 ARM存储器:片内Flash、片内静态RAM、片外存储器 存储器映射(Memory Map) 映射就是一一对应的意思。重映射就是重新分配这种一一对应的关系。 我们可以把存储器看成一个具有输出和输入口的黑盒子。输入量是地址,输出的是对应地址上存储的数据。当然这个黑盒子是由很复杂的半导体电路实现的,具体的实现的方式我们现在不管。存储单位一般是字节。这样,每个字节的存储单元对应一个地址,当一个合法地址从存储器的地址总线输入后,该地址对应的存储单元上存储的数据就会出现在数据总线上面。 普通的单片机把可执行代码和数据存放到存储器中。单片机中的CPU从储器中取指令代码和数据
[单片机]
<font color='red'>ARM</font>存储器结构、映射以及重新映射
arm堆栈-(堆栈起始地址的选择)
堆栈寄存器起始地址的设置: 程序刚启动并没有启动内存管理单元MMU,真正的内存地址如下S3C2440的储存空间映射图: ARM 使用统一编址,所以,我们得把堆栈指针设置到内存地址范围内; NAND FLASH 启动时: 堆栈寄存器可以设为片内RAM 的最大地址:0x1000(4K)-4096 或者64MSDRAM的最大地址0x34000000(64M SDRAM的地址空间映射到BANK6,那么内存地址范围就是 0x30000000~0x34000000)。 之所以选择最大地址是因为栈的生长方向是向下的,所以选最高地址作为栈的起始地址可以预防堆栈增长而覆盖数据域;
[单片机]
<font color='red'>arm</font>堆栈-(堆栈起始地址的选择)
plc pic arm dsp 51 有什么关系?他们都是单片机吗
1、51是八位的单片机 3、PLC分为固定式和组合式(模块式)两种。固定式PLC包括CPU板、I/O板、显示面板、内存块、电源等,这些元素组合成一个不可拆卸的整体。模块式PLC包括CPU模块、I/O模块、内存、电源模块、底板或机架,这些模块可以按照一定规则组合配置。 就是说PLC里面包括了单片机,但他本身不是单片机,而是构成一个控制器 3、DSP译过来就是数字信号处理,是一门学科啊,你说的可能是DSP处理器,就是用来处理数字信号的芯片。 4、ARM指的是16/32位单片机 5、至于PIC,这么跟你说吧。。应该说有三个主要特点: (1)总线结构:MCS-51单片机的总线结构是冯-诺依曼型,计算机在同一个存储空间取指令和数据,两者不能同
[单片机]
ARM发布REALVIEW实时软件库
全新优化的软件组件将加速 32 位微控制器应用的开发 今天 ARM 公司 宣布推出高度优化的 ARM RealView 实时 软件 库,该 软件 库包含有快速开发需要实时控制、网络、 USB 和 CAN 连接功能的产品所需的最关键的组件。 ARM 微控制器开发工具总监 Reinhard Keil 表示:“消费、商用和工业领域的嵌入式系统对多重通信接口以及网络性能和互联网连接性提出越来越高的要求。在过去的十几年中,我们处于市场领先地位的 RTX51 操作系统核心一直是帮助 8 位工程师快速开发应用的关键组件。我们现在已经开始现货提供优化的组件,以此满足先进的 32 位嵌入式应用最
[新品]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved