在下面的C++源代码的汇编中.为什么RAX被推入堆栈?
正如我从ABI理解的那样,RAX可以包含来自调用函数的任何内容.但是我们将它保存在这里,然后将堆栈移回8个字节.所以堆栈上的RAX,我认为只与std::__throw_bad_function_call()操作相关......?
代码:-
#include <functional>
void f(std::function<void()> a)
{
a();
}
Run Code Online (Sandbox Code Playgroud)
gcc.godbolt.org使用Clang 3.7.1 -O3 输出:
f(std::function<void ()>): # @f(std::function<void ()>)
push rax
cmp qword ptr [rdi + 16], 0
je .LBB0_1
add rsp, 8
jmp qword ptr [rdi + 24] # TAILCALL
.LBB0_1:
call std::__throw_bad_function_call()
Run Code Online (Sandbox Code Playgroud)
我确定原因很明显,但我很难弄清楚.
这是一个没有std::function<void()>包装器的尾部调用,用于比较:
void g(void(*a)())
{
a();
}
Run Code Online (Sandbox Code Playgroud)
琐碎的:
g(void (*)()): # @g(void (*)())
jmp rdi # TAILCALL
Run Code Online (Sandbox Code Playgroud) 我正在阅读http://www.realworldtech.com/sandy-bridge/,我在理解一些问题时面临一些问题:
专用堆栈指针跟踪器也存在于Sandy Bridge中并重命名堆栈指针,消除了串行依赖性并删除了多个uop.
什么是dedicated stack pointer tracker实际?
对于Sandy Bridge(和P4),英特尔仍然使用术语ROB.但重要的是要理解,在这种情况下,它只引用了飞行中uops的状态数组
事实上它意味着什么?请说清楚.
假设我有一个像这样的 nasm 函数:
inc:
mov rax,[rsp + 8]
add [rax],BYTE 1
ret
Run Code Online (Sandbox Code Playgroud)
我这样调用这个函数:
push some_var
call inc
Run Code Online (Sandbox Code Playgroud)
我想通过堆栈将参数传递给函数,因此我压入some_var然后调用我的函数。在函数中,我的项目位于堆栈中的第二个,因此我将其视为:mov rax,[rsp+8]
我的问题是:调用函数后我应该以某种方式从堆栈中弹出我的参数吗?如果是这样,我可以以某种方式从堆栈中删除它,我的意思是弹出它,但不注册?(因为我不再需要这个论点了。)
更新:我发现我可以简单地add rsp,8从堆栈中删除项目。但这是好的做法吗?调用函数后从堆栈中删除参数?
给定寄存器中的数字(二进制整数),如何将其转换为十六进制ASCII数字字符串?
数字可以存储在存储器中或即时打印,但存储在存储器中并一次打印通常更有效.(您可以修改存储的循环,而不是一次打印一个循环.)
我们能否有效地处理与SIMD并行的所有半字节?(SSE2或更高版本?)