fastcall调用约定是否真的比其他调用约定更快,例如cdecl?是否有任何基准测试表明调用约定会影响性能?
我在理解调用者和被调用者保存的寄存器之间的区别以及何时使用什么方面遇到了一些麻烦.
我使用的是MSP430:
程序:
mov.w #0,R7
mov.w #0,R6
add.w R6,R7
inc.w R6
cmp.w R12,R6
jl l$loop
mov.w R7,R12
ret
Run Code Online (Sandbox Code Playgroud)
上面的代码是被调用者,并且在教科书示例中使用,因此它遵循惯例.R6和R7被呼叫者保存,R12被呼叫者保存.我的理解是被调用者保存的regs不是"全局的",因为在过程中改变它的值不会影响它在程序之外的值.这就是您必须在开头将新值保存到被调用者注册表中的原因.
R12,保存的来电者是"全球性的",因为缺乏更好的词汇.该程序在通话后对R12产生持久影响.
我的理解是否正确?我错过了其他的东西吗?
在Intel 64架构中,有rax..rdx寄存器,它们只是A..D通用寄存器.
但是也有一些名为rsi和rdi的寄存器,它们是"源索引"和"目标索引"寄存器.为什么这些寄存器有实际名称(与A等相比)?
"源索引"和"目标索引"实际上意味着什么?是否有一些惯例说这些寄存器应该在特定情况下使用?
我发现了很多关于这个影子空间的话题,但我找不到答案,所以我的问题是:
在进入程序之前,我需要从堆栈指针中减去多少字节?
我应该在减去"阴影空间"之前将过程参数推送到堆栈吗?
我已经拆解了我的代码,但我找不到逻辑.
根据英特尔在x64中,以下寄存器称为通用寄存器(RAX,RBX,RCX,RDX,RBP,RSI,RDI,RSP和R8-R15)https://software.intel.com/en-us/articles/介绍到x64组装.
在下面的文章中,写了RBP和RSP是专用寄存器(RBP指向当前堆栈帧的基础,RSP指向当前堆栈帧的顶部). https://www.recurse.com/blog/7-understanding-c-by-learning-assembly
现在我有两个相互矛盾的陈述.英特尔声明应该是值得信赖的,但是什么是正确的,为什么RBP和RSP被称为通用目的?
谢谢你的帮助.
强烈建议在创建64位内核(对于x86_64平台)时,指示编译器不要使用用户空间ABI所执行的128字节红区.(对于GCC,编译器标志是-mno-red-zone).
如果启用了内核,则内核不会是中断安全的.
但那是为什么呢?
我正在阅读这本书:"计算机系统 - 程序员视角".我发现,在x86-64架构中,我们仅限于6个积分参数,这些参数将被传递给寄存器中的函数.下一个参数将在堆栈上传递.
而且,第一个最多8个FP或矢量args以xmm0..7传递.
为什么不使用浮点寄存器来存储下一个参数,即使参数不是单/双精度变量?
将数据存储在寄存器中比将其存储到存储器然后从存储器中读取它会更有效(据我所知).
我们是否仍然需要在软件中模拟128位整数,或者现在平均桌面处理器中是否有硬件支持?
我想知道如何将参数传递给C中的函数.存储的值在哪里以及如何检索它们?可变参数传递如何工作?此外,因为它是相关的:返回值怎么样?
我对CPU寄存器和汇编器有基本的了解,但还不足以让我彻底了解GCC向我吐出的ASM.一些简单的注释示例将非常感激.
我会听一些人说__fastcall比这更快__cdecl并且__stdcall导致它将两个参数放入寄存器,而不是其他一个调用; 但是,另一方面,这不是C中使用的标准.
我想知道什么是__fastcall不合适的,就像C中的标准,以及何时我将在我的代码中使用它.