ARM体系下的GCC内联汇编教程详解
<p>在操作系统级的编程中,有时候,C语言并不能完全的使用硬件的功能,这时候就需要嵌入一些汇编代码来实现功能。 有两种方式可以使C语言和assemly语言一起工作,一种是两种语言分开写成两个文件,链接的时候链接成一个文件;另一种就是在C语言中嵌入汇编代码。下面简单介绍一下如何在GCC中嵌入汇编代码。</p><p>GCC规定了一个内联汇编的语法,不同硬件平台上的GCC内联汇编几乎都是这样的:</p>
<div class="jb51code">
<pre class="brush:plain;">
asm(
汇编指令列表
:输出运算符列表
:输入运算符列表
:被更改的资源列表
};</pre>
</div>
<p>在GCC中插入汇编代码,需要以asm关键字开头,中间四个部分用”:”分隔,如果你嵌入的汇编没有输入输出,或者更改资源,后面三项是可以省略的。</p>
<p>下面以一个实例来说明这个语法:</p>
<div class="jb51code">
<pre class="brush:plain;">
void test(void)
{
int tmp;
// some code
__asm__(
" mov r1,%0\n\t"
:
: "r" (tmp)
: "r1"
);
}</pre>
</div>
<p></p>
<p>以上代码的意思就是,将tmp变量的值赋给r1寄存器,%0代表出现在输入运算符列表和输出运算符列表中的第一个值,%1,%2依次类推。由于我们自己的汇编代码改变了r1的值,所以我们要通知GCC编译器,r1的值被我们改变了, 在 “r” (tmp) 表达式中,tmp代表C语言输入到汇编中的变量,”r”代表tmp会通过一个寄存器传递。可以使用的符号有以下几种:</p>
<p>表1 GCC4内联汇编操作符节选</p>
<p>
<table>
<tbody>
<tr>
<td>操作符</td>
<td>含义</td>
</tr>
<tr>
<td>r</td>
<td>通用寄存器R0~R15</td>
</tr>
<tr>
<td>m</td>
<td>一个有效内存地址</td>
</tr>
<tr>
<td>l</td>
<td>数据处理指令中的立即数</td>
</tr>
<tr>
<td>X</td>
<td>被修饰的操作符只能作为输出</td>
</tr>
</tbody>
</table>
</p>
<p>上面一个代码是将C语言的值传递到汇编代码中,也可以将汇编代码输出的结果传给C代码:</p>
<div class="jb51code">
<pre class="brush:plain;">
void test(void)
{
int tmp;
__asm__(
"mov %0, #1\n\t"
: "=r" (tmp)
:
);
}</pre>
</div>
<p>这段代码的意思是,将立即数1赋给变量tmp。 与上面不同的是,输入运算符列表移到了输出运算符列表,”r”前面也多了一个等于号。这个等号被称为约束修饰符,以下是几种修饰符的含义列表:</p>
<p>表2 GCC4中内联汇编修饰符</p>
<p>
<table>
<tbody>
<tr>
<td>修饰符</td>
<td>说明</td>
</tr>
<tr>
<td>无</td>
<td>被修饰的操作符是只读的</td>
</tr>
<tr>
<td>=</td>
<td>被修饰的操作符只写</td>
</tr>
<tr>
<td>+</td>
<td>被修饰的操作符具有可读写的属性</td>
</tr>
<tr>
<td>&</td>
<td>被修饰的操作符只能作为输出</td>
</tr>
</tbody>
</table>
</p>
<p>总结</p>
<p>以上所述是小编给大家介绍的ARM体系下的GCC内联汇编教程详解,希望对大家有所帮助!</p>
<div class="art_xg">
<b>您可能感兴趣的文章:</b><ul><li>ARM汇编解决阶乘及大小写转换的问题</li><li>GNU ARM汇编语法原理及操作解析</li><li>ARM汇编逆向iOS 实战</li><li>使用ARM汇编破解iOS程序基础知识分享</li><li>浅析ARMv8汇编指令adrp和adr</li></ul>
</div>
</div>
<!--endmain-->
頁:
[1]