Keil中C语言调用汇编函数

Keil中C语言调用汇编函数,第1张

1、在 C 文件中要嵌入汇编代码片以如下方式加入汇编代码:

#pragma ASM

; Assembler Code Here

#pragma ENDASM

2、在 Project 窗口中包含汇编代码的 C 文件上右键,选择“Options for ”,点击右边的“Generate Assembler SRC File”

和“Assemble SRC File”,使检查框由灰色变成黑色(有效)状态;

3、根据选择的编译模式,把相应的库文件(如 Small 模式时,是 Keil\C51\Lib\C51SLib)加入工程中, 该文件必须作为工程的最

后文件;

语言混编一般是模块化的,模块之间相对独立的,不能直接调用,必须遵循一定的约定,才能将模块融合为一体;各种编程语言的共通点就是代码编译后最终都成为机器代码,当然也可以用汇编语言作为中间代码,再由汇编代码编译成机器代码;比如说C语言写成dll形式,另的语言调用dll来完成代码共用。要在c语言里调用汇编里的变量,首先要理解汇编里的变量是如何存放的,因为C语言的实现又跟 *** 作系统有关,所以又必须理解C语言在这个系统里是如何实现的。用汇编语言写个call,c语言里按照这个call约定调用这个call,就可以调用call里面的变量了。

不同编译器嵌入汇编的方式不一样,具体如下:

一、Turbo

C ,

也就是所说的TC。

1、使用预处理程序的伪指令#asm和#endasm,#asm用来开始一个汇编程序块,而#endasm指令用于该块的结束。

参考代码:

int mul(int a, int b)

{

/汇编开始/

#asm

mov ax,word ptr 8[bp]

imul ax word ptr 10[bp]

#endasm

/汇编结束。/

}

2、使用asm语句:

格式:asm<汇编语句>

参考代码:

int mul(int a, int b)

{

asm mov ax,word ptr 8[bp]

asm imul ax word ptr 10[bp]

/

每个asm对应一句汇编

注意结尾不需要分号

/

}

二、VC++/VS

格式:

__asm

汇编指令

[

;

]

__asm

{

汇编指令

}

[

;

]

asm前面是两条下划线,后面的方括号内容表示分号可有可无。

使用方法:

1、一条一条地用:

__asm mov al, 2

__asm mov dx, 0xD007

__asm out dx, al

每行一条汇编,

可以有分号,也可以没有。

2、组成一块地用:

__asm {

mov al, 2

mov dx, 0xD007

out dx, al

}

整体作为一个汇编代码块。

3、也可以将多条汇编写在一行:

__asm mov al, 2 __asm mov dx, 0xD007 __asm out dx, al

三、GNU

GCC

GCC对汇编的支持是最丰富的,简单介绍如下:

1、

用到的关键字:

“__asm__”

表示后面的代码为内嵌汇编,“asm”是“__asm__”的别名。

“__volatile__” 表示编译器不要优化代码,后面的指令保留原样,“volatile”是它的别名。

括号里面是汇编指令。

内嵌汇编语法如下:

__asm__(

汇编语句模板:

输出部分:

输入部分:

破坏描述部分)

一个简单的汇编模板:

int a=10,b;

asm("movl %1, %%eax;

movl %%eax, %0;"

:"=r"(b) /输出部/

:"r"(a) /输入部/

:"%eax" /毁坏部/

);

表示C语言里的“b=a;”。

里边r表示使用任意寄存器,%0、%1表示使用两个寄存器,一般只能%0~%9共十个 *** 作数,按输入输出部变量出现顺序进行映射。

寄存器用两个百分号,是因为使用了%0%1这些数字使百分号有了特殊意义,所以在 *** 作数出现的寄存器必须用双百分表示。

毁坏部里边的%eax表示eax寄存器在汇编代码块执行过程中会被改写,在执行前要保护好,这是提交给编译器决定的。

一、 参数传递的基本规则(ATPCS(ARM—Thumb Procedure Call Standard))

1、 参数传递

二、汇编程序、C程序相互调用举例

1、 C程序调用汇编程序

汇编程序的设计要遵守ATPCS(ARM—Thumb Procedure Call Standard),保证程序调用时参数的正确传递。在汇编程序中使用EXPORT 伪 *** 作声明本程序,使得本程序可以被别的程序调用。在C程序使用extern声明该汇编程序。

下面是一个C程序调用汇编程序的例子。其中汇编程序strcopy实现字符串复制功能,C程序调用strcopy完成字符串复制的工作。

//C程序

#include <stdioh>

extern void strcopy(char d, const char s);

int main( )

{

const char srcstr=”First string-source”;

char dststr[ ]=”Second string-destination”;

printf(“Before copying:\n”);

printf(“%s\n %s\n”, srcstr,dststr);

strcopy(dststr,srcstr);

printf(“After copying:\n”);

printf(“%s\n %s\n “,srcstr,dststr);

while(1) ;

}

;汇编程序

AREA Scopy, CODE, READONLY

EXPORT strcopy

Strcopy

LDRB R2, [R1], #1

STRB R2, [R0], #1

CMPR2,#0

BNE Strcopy

MOV PC, LR

END

2、 汇编程序调用C程序

汇编程序的设计要遵守ATPCS,保证程序调用时参数的正确传递。在汇编程序中使用IMPORT伪 *** 作声明将要调用的C程序。下面是一个汇编程序调用C程序的例子。其中在汇编程序中设置好各参数的值。本例中有6个参数,分别使用寄存器R0存放第1个参数,

R1存放第2个参数, R2存放第3个参数, R3存放第4个参数, 第5个、第6个参数利用数据栈传送。由于利用数据栈传递参数,在程序调用结束后要调整数据栈指针。

//C程序g( )返回6个参数的和

int g( int a, int b, int c, int d, int e, int f )

{

printf(“e=%d\n”, e);

printf(“f=%d\n”, f);

return (a+b+c+d+e+f);

}

; 汇编程序调用C程序 g( ) 计算6个整数 i, 2i, 3i, 4i, 5i, 6i的和

EXPORT f

AREA f ,CODE, READONLY

IMPORT g

MOV R0, #1

ADD R1, R0, R0

ADD R2, R1, R0

ADD R3, R2, R0

ADD R4, R3, R0

ADD R5, R4, R0

STR R4, [SP, #-4]!

STR R5, [SP, #-4]!

BL g

ADD SP, SP, #4

ADD SP, SP, #4

STOP B STOP

END

1、打开IAR FOR STM8工程。

2、编一段C语言的延时程序,作为例子。

3、如何在目前实例上,添加我们的汇编。

4、编译一下是否可以编译通过,编译提示OK。

5、进入仿真界面,是否可以运行。把断点设在汇编的程序上,运行后,可以在断点处停止,说明仿真也是正常的。

以上就是关于Keil中C语言调用汇编函数全部的内容,包括:Keil中C语言调用汇编函数、c语言里如何调用汇编里的变量、如何把汇编程序嵌入到C语言中等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9454199.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存