C与汇编语言混合编程
<h1>一、在Keil上调用使用C语言调用汇编程序</h1><p><img src="https://img2020.cnblogs.com/blog/2539071/202110/2539071-20211012203739621-1748308869.png"></p>
<p> </p>
<p>在前面的博客中,我们已经熟悉了Keil中创建项目和keil的一些简单使用,参考链接:https://www.cnblogs.com/LinZJ0423/p/15357620.html</p>
<h2>构建代码</h2>
<p>tets.s中的代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"> AREA My_Function,CODE,READONLY
EXPORT Init_1
Init_1
</span><span style="color: rgba(0, 0, 255, 1)">MOV</span> R1,#<span style="color: rgba(128, 0, 128, 1)">666</span>
<span style="color: rgba(0, 0, 255, 1)">MOV</span> R2,#<span style="color: rgba(128, 0, 128, 1)">888</span><span style="color: rgba(0, 0, 0, 1)">
LOOP
</span><span style="color: rgba(0, 0, 255, 1)">CMP</span> R1,#<span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">
BHS LOOP_END
</span><span style="color: rgba(0, 0, 255, 1)">ADD</span> R2,#<span style="color: rgba(128, 0, 128, 1)">1</span>
<span style="color: rgba(0, 0, 255, 1)">ADD</span> R1,#<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
B LOOP
LOOP_END
</span><span style="color: rgba(0, 0, 255, 1)">NOP</span><span style="color: rgba(0, 0, 0, 1)">
END</span></pre>
</div>
<p>main.c中的代码:</p>
<div class="cnblogs_code">
<pre>#include<stdio.h>
<span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Init_1(<span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> main(){
Init_1();
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
}</span></pre>
</div>
<p> </p>
<p><img src="https://img2020.cnblogs.com/blog/2539071/202110/2539071-20211012204523280-1024188237.png"></p>
<p> </p>
<p> </p>
<p> 可以看见c语言成功调用汇编程序。</p>
<h3>小结</h3>
<p>在C语言中调用汇编函数时,需要在.c文件中用extern Return_Type Function_Name(Datatype parameter); 声明,然后在main函数中调用,在汇编里面用EXPORT Function_Name就可以与.c文件中的函数联系起来。</p>
<h1>二、做些小改动</h1>
<p>在这里我们首先要搞清楚在ARM中参数是如何传递和使用的。<br>在X86平台下:</p>
<h2>1.C语言调用函数传递参数的方法</h2>
<p>C语言调用函数时,在32位程序中使用栈传递,而在64位程序中,传递方式和参数个数有关,当参数个数小于等于6个时,参数会使用寄存器被传递,当参数大于6个时,6个寄存器被分配后,会利用栈来传递多余的参数,且参数的传递都是从右到左压栈或是存入寄存器。<br>验证过程参考:https://blog.csdn.net/m0_55708805/article/details/117388229<br><br></p>
<h2>2.ARM中寄存器用法:</h2>
<ul>
<li>r0-r3 用作传入函数参数,传出函数返回值。在子程序调用之间,可以将 r0-r3 用于任何用途。被调用函数在返回之前不必恢复 r0-r3。—如果调用函数需要再次使用 r0-r3 的内容,则它必须保留这些内容。</li>
<li>r4-r11 被用来存放函数的局部变量。如果被调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器的值。r11 是栈帧指针 fp。</li>
<li>r12 是内部调用暂时寄存器 ip。它在过程链接胶合代码(例如,交互操作胶合代码)中用于此角色。在过程调用之间,可以将它用于任何用途。被调用函数在返回之前不必恢复</li>
<li>r12。</li>
<li>寄存器 r13 是栈指针 sp。它不能用于任何其它用途。sp 中存放的值在退出被调用函数时必须与进入时的值相同。</li>
<li>寄存器 r14 是链接寄存器 lr。如果您保存了返回地址,则可以在调用之间将 r14 用于其它用途,程序返回时要恢复</li>
<li>寄存器 r15 是程序计数器 pc。它不能用于任何其它用途。</li>
</ul>
<p>利用寄存器传递参数时,参数值按顺序放在寄存器R0,R1,R2,R3中,当参数大于4个时,超过的参数值利用栈传递,函数返回时,若有返回值会利用寄存器R0存储返回。</p>
<h2>3.修改代码</h2>
<div class="cnblogs_code">
<pre>#include<stdio.h>
<span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">int</span> Init_1(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> x);
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> main(){
Init_1(</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
}</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"> AREA My_Function,CODE,READONLY
EXPORT Init_1
ENTRY
Init_1
</span><span style="color: rgba(0, 0, 255, 1)">ADD</span> R0,R0,#<span style="color: rgba(128, 0, 128, 1)">100</span><span style="color: rgba(0, 0, 0, 1)">
BX LR
END</span></pre>
</div>
<p>编译调试结果如下:<img src="https://img2020.cnblogs.com/blog/2539071/202110/2539071-20211012205414638-1682382807.png"></p>
<p> </p>
<p> </p>
<p><img src="https://img2020.cnblogs.com/blog/2539071/202110/2539071-20211012205222572-1533078368.png"></p>
<p> </p>
<h3>总结:</h3>
<p>在该实验中,我们的Init_1函数调用时有一个参数的传递,在main函数中我们调用Init_1函数,给了一个参数1,函数执行完毕时,1+100的16进制数为65,我们对函数执行完毕的期望值为65,而在图中寄存器R0的值就是65。</p>
<h1>三.在汇编函数中调用一个C语言写的函数</h1>
<p>在汇编中调用C语言函数XXX,则加上IMPORT XXX,注意Keil工具不允许汇编语句顶格写,否则会报错。</p>
<p>main.c代码:</p>
<div class="cnblogs_code">
<pre>#include<stdio.h>
<span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">int</span> sum(<span style="color: rgba(0, 0, 255, 1)">int</span> a,<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> b);
</span><span style="color: rgba(0, 0, 255, 1)">int</span> sum(<span style="color: rgba(0, 0, 255, 1)">int</span> a,<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> b){
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> c;
a</span>=<span style="color: rgba(128, 0, 128, 1)">100</span><span style="color: rgba(0, 0, 0, 1)">;
b</span>=<span style="color: rgba(128, 0, 128, 1)">100</span><span style="color: rgba(0, 0, 0, 1)">;
c</span>=a+<span style="color: rgba(0, 0, 0, 1)">b;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> c;
}</span></pre>
</div>
<p>test.s代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"> AREA MYDATA, DATA
IMPORT sum
AREA MYCODE, CODE
ENTRY
EXPORT __main
__main
BL sum
BX LR
END</span></pre>
</div>
<p><img src="https://img2020.cnblogs.com/blog/2539071/202110/2539071-20211012205928375-1485077163.png"></p>
<p> </p>
<h1> 心得体会</h1>
<p>汇编语言和C语言的嵌套编程在实现的过程中有一些难度,其中遇到了许多问题查了博客得以解决。在解决的过程中更加深入的了解和体会到了C语言是如何变成汇编语言的,以及了解了底层的执行过程。同时可以使用Cmake去查看GCC是如何把C语言变成汇编语言的。同时对于C语言是如何传递参数和ARM如何使用的过程有了深入了解</p>
<h1>参考链接</h1>
<p>https://blog.csdn.net/m0_55708805/article/details/117388229<br>https://blog.csdn.net/ZHONGkunjia/article/details/51184489<br>http://lionwq.spaces.eepw.com.cn/articles/article/item/17475/<br>https://cloud.tencent.com/developer/article/1593645<br>https://blog.csdn.net/qq_45659777/article/details/120651310</p><br><br>
来源:https://www.cnblogs.com/LinZJ0423/p/15399573.html
頁:
[1]