Excel表格网

汇编怎样调用C?

205 2024-02-28 09:18 admin   手机版

一、汇编怎样调用C?

汇编调用C,要按照函数调用规范来传递参数(即压栈),常用的函数调用规范有stdcall,cdecl等,cdecl是通常的缺省调用规范。如果是cdecl,清栈动作是由调用者来处理的,也就是汇编在c函数返回后要清栈。

另外汇编调用C,还要abi来处理返回值,常用的ARM abi有oabi,eabi等,涉及到返回值在哪个寄存器中。

C调用汇编,汇编除了按以上的函数调用规范和abi规范来处理参数以及返回值之外,要使用mov pc,lr来返回C,即C调用发生时,LR中有调用的返回地址

二、在c语言里怎么调用汇编函数?

把汇编写在另一个文件里 在main写个原型声明 再把两个文件同时编译可不可以。我的gcc编译器里是这样写的汇编文件m.s.file "stdio.h"#hellowrold.s print "hello,world!".section .data output: .ascii "%d %d %d\0".section .text.globl _fun_fun: pushl %ebp movl %esp, %ebp subl $16, %esp movl 0x8(%ebp), %eax movl %eax, 0x4(%esp) movl 0xc(%ebp), %eax movl %eax, 0x8(%esp) movl 0x10(%ebp), %eax movl %eax, 0xc(%esp) movl $output, %eax movl %eax, (%esp) call _printf movl %ebp, %esp popl %ebp ret.end主函数前的原型声明 extern int fun(int i, int j, int k);

三、python调用c函数?

在Python中调用C函数,你可以使用C语言的扩展库来实现。以下是一种常见的方法,使用Python的ctypes模块来调用C函数:

1. 编写C函数的源代码文件,例如`example.c`,其中包含你要调用的C函数的定义和实现。例如,以下是一个简单的示例:

```c

// example.c

#include <stdio.h>

int add(int a, int b) {

    return a + b;

}

```

2. 使用C编译器将C源代码编译为共享库(或动态链接库)。例如,在命令行中执行以下命令:

```bash

gcc -shared -o example.so example.c

```

这将生成一个名为`example.so`的共享库文件。

3. 在Python中,使用ctypes模块加载共享库,并调用其中的C函数。例如:

```python

import ctypes

# 加载共享库

lib = ctypes.CDLL('./example.so') # 或者使用绝对路径

# 调用C函数

result = lib.add(2, 3)

print(result) # 输出:5

```

在上述示例中,`ctypes.CDLL`函数用于加载共享库文件,然后你可以使用`.`操作符来调用其中的C函数。

请注意,上述示例仅适用于简单的C函数。对于更复杂的情况,可能需要更多的设置和参数配置。此外,还有其他的方法和工具可以实现Python与C的交互,如使用Cython、SWIG等。选择适合你需求的方法,并参考相应的文档和教程进行操作。

四、汇编语言调用c语言?

如果keil5的话,在汇编内调用c语言的变量,可以IMPORT(变量名)LDRr0,=(变量名)//获得该变量地址到r0LDRr0,[r0]//将r0其值作为地址,获取其地址指向的值这样c中变量的值就传递到r0了

五、c语言中什么是调用函数和被调用函数?

调用函数就是计算机编译或运行时,使用某个函数来完成相关命令。对无参函数调用时则无实际参数表。实际参数表中的参数可以是常数、变量或其它构造类型数据及表达式。各实参之间用逗号分隔。 这两个定义是相对的,比如说你自己定义编写了一个函数,然后在后面的编写语句中要用到你之前编写的函数,你引用了,那个函数就是被调用函数,你正在写的那个主函数就是调用函数。

六、c语言调用函数写法?

C语言中,函数调用的一般形式为:函数名(实际参数表)对无参函数调用时则无实际参数表。实际参数表中的参数可以是常数、变量或其它构造类型数据及表达式。各实参之间用逗号分隔。

#include<stdio.h>

int fun(int x, int y); // 函数声明,如果函数写在被调用处之前,可以不用声明

void main()

{

int a=1, b=2, c;

c = fun(a, b); // 函数的调用,调用自定义函数fun,其中a,b为实际参数,传递给被调用函数的输入值

}

// 自定义函数fun

int fun(int x, int y) // 函数首部

{ // {}中的语言为函数体

return x>y ? x : y; // 返回x和y中较大的一个数

}

函数实参

函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因此要求该函数必须是有返回值的。例如: printf("%d",max(x,y)); 即是把max调用的返回值又作为printf函数的实参来使用的。在函数调用中还应该注意的一个问题是求值顺序的问题。

所谓求值顺序是指对实参表中各量是自左至右使用呢,还是自右至左使用。对此,各系统的规定不一定相同。介绍printf 函数时已提到过,这里从函数调用的角度再强调一下。

七、C语言如何调用函数?

在C语言中,要调用一个函数,首先需要在函数声明或定义之后的地方直接写函数名并且加上括号,括号内可以带有参数。函数调用可以在任何地方进行,只要是在函数声明或定义之后的地方。在调用函数时,如果函数拥有返回值,可以将函数调用表达式放在赋值语句的右侧,将返回值赋给一个变量。如果函数不需要参数,则直接写括号即可。另外,也可以使用指针来调用函数。这种方式需要声明一个函数指针,并将指针指向需要调用的函数,然后通过指针来调用函数。

八、c语言函数调用规则?

在参数传递中,有两个重要的问题必须要明确说明:

1. 当参数个数多于一个时,按照什么顺序把参数压入堆栈;

2. 函数调用后,由谁来把堆栈恢复原状。

在高级语言中,就是通过函数的调用方式来说明这两个问题的。常见的调用方式有:

stdcall cdecl fastcall thiscall thiscall naked call

下面就分别介绍这几种调用方式:

1. stdcall

stdcall调用方式又被称为Pascal调用方式。在Microsoft C++系列的C/C++编译器中,使用PASCAL宏,WINAPI宏和CALLBACK宏来指定函数的调用方式为stdcall。

stdcall调用方式的函数声明为:

int _stdcall function(int a, int b);

stdcall的调用方式意味着:

(1) 参数从右向左一次压入堆栈

(2) 由被调用函数自己来恢复堆栈

(3) 函数名自动加前导下划线,后面紧跟着一个@,其后紧跟着参数的尺寸

上面那个函数翻译成汇编语言将变成:

push b 先压入第二个参数

push a 再压入第一个参数

call function 调用函数

在编译时,此函数的名字被翻译为_function@8

2. cdecl

cdecl调用方式又称为C调用方式,是C语言缺省的调用方式,它的语法为:

int function(int a, int b) // 不加修饰符就是C调用方式

int _cdecl function(int a, int b) // 明确指定用C调用方式

cdecl的调用方式决定了:

(1) 参数从右向左依次压入堆栈

(2) 由调用者恢复堆栈

(3) 函数名自动加前导下划线

由于是由调用者来恢复堆栈,因此C调用方式允许函数的参数个数是不固定的,这是C语言的一大特色。

此方式的函数被翻译为:

push b // 先压入第二个参数

push a // 在压入第一个参数

call funtion // 调用函数

add esp, 8 // 清理堆栈

在编译时,此方式的函数被翻译成:_function

3. fastcall

fastcall 按照名字上理解就可以知道,它是一种快速调用方式。此方式的函数的第一个和第二个DWORD参数通过ecx和edx传递,

后面的参数从右向左的顺序压入栈。

被调用函数清理堆栈。

函数名修个规则同stdcall

其声明语法为:

int fastcall function(int a, int b);

4. thiscall

thiscall 调用方式是唯一一种不能显示指定的修饰符。它是c++类成员函数缺省的调用方式。由于成员函数调用还有一个this指针,因此必须用这种特殊的调用方式。

thiscall调用方式意味着:

参数从右向左压入栈。

如果参数个数确定,this指针通过ecx传递给被调用者;如果参数个数不确定,this指针在所有参数压入栈后被压入栈。

参数个数不定的,由调用者清理堆栈,否则由函数自己清理堆栈。

可以看到,对于参数个数固定的情况,它类似于stdcall,不定时则类似于cdecl。

5. naked call

是一种比较少见的调用方式,一般高级程序设计语言中不常见。

函数的声明调用方式和实际调用方式必须一致,必然编译器会产生混乱。

函数名字修改规则:

1. C编译时函数名修饰约定规则:

__stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个“@”符号和其参数的字节数,格式为_function@8。

__cdecl调用约定仅在输出函数名前加上一个下划线前缀,格式为_function。

__fastcall调用约定在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数,格式为@function@8。

它们均不改变输出函数名中的字符大小写,这和PASCAL调用约定不同,PASCAL约定输出的函数名无任何修饰且全部大写。

2. C++编译时函数名修饰约定规则:

__stdcall调用约定:

(1)以“?”标识函数名的开始,后跟函数名;

(2)函数名后面以“@@YG”标识参数表的开始,后跟参数表;

(3)参数表以代号表示:

X--void ,

D--char,

E--unsigned char,

F--short,

H--int,

I--unsigned int,

J--long,

K--unsigned long,

M--float,

N--double,

_N--bool,

....

PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以“0”代替,一个“0”代

表一次重复;

(4)参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;

(5)参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。

其格式为“?functionname@@YG*****@Z”或“?functionname@@YG*XZ”,例如

int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z”

void Test2() -----“?Test2@@YGXXZ”

__cdecl调用约定:

规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YA”。

__fastcall调用约定:

规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YI”。

VC++对函数的省缺声明是"__cedcl",将只能被C/C++调用。

九、c语言调用函数原则?

一、C语言函数

1.概念:函数是一组一起执行一个任务的语句,每个c程序都必须有一个main函数,程序员可以把代码划分到不同的函数当中去,在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。c标准库提供了可以大量调用的库函数,比如,printf,strcmp等。

2.函数的定义

c语言中函数的一般定义如下:

return_type Function_name(Parameter List)

{

The function body

}

在c语言中,函数由一个函数头和一个函数主体组成,组成有以下方面:

函数名称:上面的函数名称即为max。

函数的返回类型:一个函数可以返回一个值,这里的max函数的返回值是一个int型的整数,函数也可以没有返回值,例如void max(),void代表该函数是一个没有返回值的函数。

注意函返回类型的值以该函数的返回类型一致,具体表现为:

函数的参数:当一个函数被调用时可以向该函数的参数传递一个值,这个值叫做实际参数,简称实参,函数的参数叫形式参数,简称形参。当然,一个函数也可以没有参数。

函数主体:其包括该函数里执行任务的语句,例子中的函数主体就是return a>b?a:b;

下面是一个定义一个比较大小函数的实例:

3.函数在定义时会有两种情况

在main函数之前定义,程序在这种情况下不需要再main函数里声明。

在main函数之后定义,这时需要在main函数里声明该函数,比如,声明Max函数时

int main()

{

int Max(int a,int b);

}

二、函数的调用

1.定义函数时会定义这个函数要做什么,然后通过调用该函数来完成定义的任务。当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。下面是一个具体调用函数的例子:

2.函数的嵌套调用与递归

函数的嵌套调用:简单来说就是在一个定义的函数里在调用另一个函数;

下面是一个比较三个数大小的例子:

函数的递归调用:递归是一种特殊的函数调用方式,简单来说就是在一个函数里再调用它自身为递归调用,函数递归会不断调用自己,每调用自己一次就进入新的一层,当最内层函数执行完后然后一层层向外退出。

以上可以看出递归的代码量比较少,但递归会占用较大的内存,而且运行时间长,所以如果不是什么特殊问题需要用递归解决尽量少用递归。

3.函数的传参

函数传递参数会有两种方式:

1.传值调用:该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。(该方式在函数内部不会改变实参的值),比如下面的例子可以说明这点:

在函数调用过程中,系统会为形参重新申请内存,函数调用完后形参会被释放掉。

2.引用调用:通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

十、c#调用matlab函数?

matlab程序如下:

[plain] view plain copy

function y=raicos(t)

result=2t;

end

2.在C#中调用matlab的函数,使用上面的4个步骤,添加引用之后,C#程序如下

[csharp] view plain copy

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using MathWorks.MATLAB.NET.Arrays;//系统dll文件

using Demodll;//自己生成的dll文件

namespace WebApplication1

{

public partial class WebForm26 : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

demo h = new demo();//demo为class名称,h为定义的成员函数

MWArray x;//定义x为矩阵变量,将普通数转化为matlab能识别的类型

x = demo.raicos((MWArray)i);//调用matlab里的raicos函数

}

}

}

顶一下
(0)
0%
踩一下
(0)
0%
相关评论
我要评论
用户名: 验证码:点击我更换图片
上一篇:返回栏目