搜索
bottom↓
回复: 2

请教下Linux下C中内嵌汇编

[复制链接]

出0入0汤圆

发表于 2012-6-13 07:42:13 | 显示全部楼层 |阅读模式
本帖最后由 zyp000 于 2012-6-13 13:04 编辑

编译环境:Ubuntu12.04 + arm-linux-gcc-3.4.5-glibc-2.3.6
初学,做了些硬件实验,但大都是单体来做的,现在想把他们整合成一个实验,验证下自己到底搞明白了没。
因为想尽量用C来实现初始化,所以需要用到内嵌汇编,ldr  使用这条指令,编译器报语法错误,但是在汇编源文件里使用是没问题的。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2012-6-13 13:57:50 | 显示全部楼层
1.楼主可否将你的文件贴上来。
2.这是我以前用的资料,可惜出处已经找不到了,内容为:
====================================================
Linux C 嵌入汇编(内联)注意事项-修改版
        一般来讲,在C中内联汇编语句要比纯粹的汇编语言代码复杂的多,需要解决如何分配寄存器、如何与C代码中的变量相结合的问题。
        在Linux下的arm汇编语法格式不同于ADS下面的汇编语法格式,但是arm的指令都遵从于ARM的规范。在Linux下的C程序里面内联汇编代码,特别需要注意格式的问题。
从大的方面来讲,内联的汇编代码在C源文件中的区域标识不同。最基本的格式是:
        __asm__(“asm statements”);
        如果是多条汇编指令的话,需要用”\n\t”将它们隔开。如下所示:
                                        __asm__(
                                                “asm statements\n\t”
                                                “asm statements\n\t”
                                                …
                                                “asm statements”);
完整的内联汇编代码格式如下:
__asm__(“asm statements” : outputs : inputs : registers-modified);
        内联的汇编代码语句被”:”分割为4部分;其中,第一部分为汇编代码本身,通常成为指令部,格式与纯汇编代码是相同的。指令部是必须的,其他部分如果没有必要,可以省略。
        在C中内联汇编,需要处理的一个问题就是如何与C语句中的变量相结合、传入汇编代码、从汇编代码中传出改变的值。在内联汇编代码的指令部中,使用占位符来表示需要使用寄存器的操作数,有几个占位符就表示有几个变量需要和寄存器相结合,汇编器在编译和连接的时候就会相应的根据后面的约束条件进行处理。
        输出约束和输入约束的格式相同,是这样一种结构:
                “constraint”(variable)
        指令部后面紧接著就是输出部,它用来规定输出变量如何与占位符来结合。每一个条件可以成为一个约束,必要的时候可以使用多个约束,相互之间使用逗号隔开。一般情况下,每个输出约束都是以输出修饰符=开始,然后紧跟一个约束代码,最后是相结合的变量名称。如果变量既需要输入又需要输出,那么必须使用修饰符+。
        紧接着就是输入部,它用来规定仅仅作为输入的变量如何与占位符相结合。它与输入部相似,由于只是输入,所以一般是不用输出修饰符(比如上面提到的=和+)的。
        有时进行某些操作的时候,可能还会需要多个寄存器来保存中间的结果,这样就难免会破坏原有寄存器的内容。在gcc内联汇编的格式中的最后一部分可以对将产生副作用的寄存器进行说明,以便gcc能够采用相应的措施。
常见的输入输出修饰符和约束代码介绍
约束代码                                        意义
r                                                        使用任何可用的通用寄存器
m                                                使用变量的内存位置
g                                                使用任何可用的寄存器和内存位置
i                                                        使用立即数的值

输入输出修饰符                         意义
=                                                只能写入操作数
+                                                可读可写操作数
&                                                在内联函数完成之前,可以删除或者重新使用操作数
一个内联汇编的实例
#include <stdio.h>
int main()        {
                int a = 10, b = 0, c = 0;
                __asm__ __volatile__(
                                “mov                r0, %2\n\t”
                                “add                r0, r0, #5\n\t”
                                “mov                %1, r0\n\t”
                                “mov                %0, r0”
                                : “=r”(b), “=r”(c)
                                : “r”(a));
                printf(“b = %d\nc= %d\n”, b, c);
                return 0;
}

出0入0汤圆

 楼主| 发表于 2012-6-26 15:50:26 | 显示全部楼层
本帖最后由 zyp000 于 2012-6-26 15:51 编辑

谢谢LS的朋友。我的代码已经修改了,ldr用了几条mov代替。
伪指令好像都不行,不光是ldr。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-13 14:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表