用GCC的C函数生成汇编语言函数,可以从汇编语言程序中调用汇编语言函数吗?我知道gcc将C编译成机器代码(可以很容易地分解成汇编语言),而且我已经知道inline assembly language functions in C是可能的,但是我还没有找到从汇编语言程序调用C函数的方法,这基本上是相反的。
在这里,我试图在x86程序中内联一个C函数。如果内联是不可能的,那么还有其他方法从汇编语言程序调用C函数吗?
.686p
.model flat,stdcall
.stack 2048
.data
.code
start:
invoke ExitProcess, 0
printSomething PROC ;now I'm attempting to inline a C function here
void printSomething(thingToPrint){
printf("This is a C function that I want to invoke from an assembly language program.");
printf("There must be some way to do this - is it possible somehow?");
}
printSomething ENDP
end start发布于 2013-04-28 13:43:21
我要从这里回忆起来,所以我可能会在一两个细节上稍微偏离方向。然而,我希望这足以让你朝着正确的方向前进。
您需要告诉GCC汇编程序,您的常规printSomething()没有在程序集文件中定义。在'C‘中,您将使用extern关键字。对于程序集,需要使用.globl。
.globl printSomething如果您使用的汇编程序与GCC的不同,关键字可能是不同的。
下一个大问题是“我该如何传递论点”?这在很大程度上取决于处理器和操作系统。由于问题的标题表示x86,我将假设您使用的是16位或32位模式和标准x86 ABI (与x86-64不同,x86-64在x86和Linux之间也不同)。C参数通过将它们推到堆栈上传递给调用的例程。它们从右向左推到堆栈上。
因此,
printSomething (arg1, arg2, arg3, arg4);翻译成..。
pushl arg4
pushl arg3
pushl arg2
pushl arg1
call printSomething
addl $0x10, %esp你可能会问自己,这是什么?
addl $0x10, %esp?我们将四个32位参数传递给例程(也就是推到堆栈上)。尽管例程知道需要这些参数,但它并不负责将它们从堆栈中弹出。打电话的人对此负责。因此,在我们从例程返回后,我们调整堆栈指针,以丢弃我们先前推到堆栈上的四个32位参数。
在上面的例子中,我假设我们是在32位模式下工作.如果是16位模式的话.
pushw arg4
pushw arg3
pushw arg2
pushw arg1
call printSomething
addw $0x8, %sp我意识到在您的示例中,printSomething()只使用一个(1)参数,在我的示例中使用了四个(4)。只要调整我的例子是必要的。
对于最后的步骤,您需要将C文件和程序集文件编译成对象文件,链接对象文件,然后执行。
我希望这能帮到你。
发布于 2019-05-27 15:17:15
对于x86_64,请注意,您必须小心处理一些额外的事情:
push %rbp。
这把我带到了这里,例如:64 assembly function lead to segmentation fault (SIGSEGV) instead of an abort signal?call (TODO为什么要这样做?)你必须担心:- marking all the non-callee saved registers as clobbered
- the red zone for your argumentshttps://stackoverflow.com/questions/16255608
复制相似问题