本文介绍了链接是否意味着堆栈或注册?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在大多数语言中,堆栈中包含的C用于函数调用.这就是为什么如果不小心递归会出现堆栈溢出"错误的原因.(不打算打双关).

In most languages, C included the stack is used for function calls. That's why you get a "Stack Overflow" error if you are not careful in recursion. (Pun not intended).

如果是这样,那么 asmlinkage GCC指令有何特别之处.

If that is true then what is so special about the asmlinkage GCC directive.

它说,来自 #kernelnewbies

我的意思是我认为寄存器不用于常规函数调用.

更奇怪的是,当您了解它是在x86上使用GCC regparm函数属性实现的.

What is even more strange is that when you learn it is implemented using GCC regparm function attribute on x86.

regparm 如下:

这基本上与 asmlinkage 尝试做的事情相反.

This basically saying opposite of what asmlinkage is trying do.

那会发生什么?它们在堆栈还是寄存器中.

So what happens ? Are they on the stack or the registers.

我要去哪里错了?

信息不是很清楚.

推荐答案

通常,为了使调用更快(取决于体系结构),编译器可以选择通过寄存器传递一些参数,以避免将它们分别复制到堆栈中或从堆栈中复制出来.时间.对于未导出的私有函数尤其如此,因此私有私有函数不需要遵循ABI定义的调用约定即可进行进一步优化.

Normally, to make calls faster (depending on the architecture), the compiler can choose to pass some parameters through registers to avoid copying them to/from the stack each time. This is particularly true for private functions that are not exported and therefore not required to obey the calling conventions defined by the ABI, in order to be further optimized.

某些ABI实际上需要参数要在寄存器中传递.System V AMD64 ABI调用约定(Linux x86-64上的默认设置)就是一个很好的例子:它指示应通过RDI,RSI,RDX,RCX,R8,R9,[XYZ] MM0-7传递函数参数,因此堆栈很少使用.

Some ABIs actually require parameters to be passed in registers. The System V AMD64 ABI calling convention (default on Linux x86-64) is a great example of this: it dictates that function parameters should be passed through RDI, RSI, RDX, RCX, R8, R9, [XYZ]MM0–7, so the stack is very rarely used.

现在,在Linux中进行系统调用时,内核会在堆栈上复制用户空间寄存器以保留它们,然后调用相应的syscall函数.这些函数应直接从堆栈上已保存的用户寄存器中获取参数,因此必须编译为仅 始终从堆栈中获取参数.

Now, when making a syscall in Linux, the kernel copies userspace registers on the stack in order to preserve them, and then calls the appropriate syscall function. These functions should take the parameters directly from the already saved user registers on the stack and must therefore be compiled to only and always take parameters from the stack.

在x86 32位中, asmlinkage 扩展为 __ attribute __((regparam(0))),这基本上告诉GCC 没有参数应该通过寄存器传递( 0 是重要的部分).在x86 64位上,它扩展为更具体的 __ attribute __((syscall_linkage)).最终结果是相同的:该函数被迫从堆栈中获取参数.在其他总是在堆栈上传递参数的体系结构上,甚至不需要特殊的 __ attribute __ .

In x86 32bit, the asmlinkage macro expands to __attribute__((regparam(0))), which basically tells GCC that no parameters should be passed through registers (the 0 is the important part). On x86 64bit, it expands to the more specific __attribute__((syscall_linkage)) instead. The end result is the same: the function is forced to take parameters from the stack. On other architectures that always pass parameters on the stack, no special __attribute__ is even needed.

这篇关于链接是否意味着堆栈或注册?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 06:38