把caller 的栈顶的内存地址(存在 rsp 寄存器中)赋值到 rbp 寄存器。 sub$0x20,%rsp 把rsp再减去0x20,也就是地址再向下移动32个单元(字节),用于main函数局部变量和参数的存储。这里预留少空间,在编译期就计算好了。当前实验是10个参数,如果我们改为13个参数,则会是sub $0x50,%rsp,所以生成的汇编代码,在运行...
%rdi 【参数】六个寄存器用于存储函数调用时的6个参数 %rsi 【参数】六个寄存器用于存储函数调用时的6个参数 %rdx 【参数】六个寄存器用于存储函数调用时的6个参数 %rcx 【参数】六个寄存器用于存储函数调用时的6个参数 %r8 【参数】六个寄存器用于存储函数调用时的6个参数 %r9 【参数】六个寄存器用于...
x86-64 中,有 6 个寄存器来存储参数,如前面第二个表所示,依次为%rdi、%rsi、%rdx、%rcx、%r8、%r9,如下表所示,如果多于 6 个参数,依然还是通过入栈实现,如上面的图4图5中的param部分所示,所以从性能的角度上来看,我们设计的函数参数最好不超过六个,这样参数就都会直接通过寄存器传递,而不用通过栈传递。
## 关于64位汇编的参数传递 当参数少于7个时, 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9。 当参数为7个以上时, 前 6 个与前面一样, 但后面的依次从 “右向左” 放入栈中,即和32位汇编一样。参数个数大于 7 个的时候 ``` H(a, b, c, d,
0x04:参数传递的不同 (1)6个寄存器用来传递参数(见前文); (2)剩下的寄存器按照之前的方式传递(不过是与rsp相关了,ebp不再作为栈帧指针,并且从rsp开始第7个参数,rsp+8开始第8个,以此类推); (3)调用时,rsp向下移动8位(存入返回地址),寄存器参数无影响,第7个及之后的参数现在则是从rsp+8开始第7个,rsp...
intadd(inta,intb,intc,intd,inte,intf,intg,inth) {//8个参数 intsum=a+b+c+d+e+f+g+h;//相加求和 returnsum; } intmain(void) { inti=10; intj=20; intk=i+j; intsum=add(11,22,33,44,55,66,77,88); intm=k;//为了观察%rax Caller Save 寄存器的恢复 ...
x86架构64位模式下的寄存器列表 在此列出x86架构处理器在64位模式下的可用寄存器列表,方便查阅~ 这里要注意的是,在64位模式下,所有通用寄存器都能访问第8位部分,低16位部分以及低32位部分。 以下是64位模式下AMD64 ABI函数调用协议参数传递机制: rdi, rsi, rdx, rcx, r8, r9...
进入x64时代,寄存器资源富裕了,参数传递绝大多数都是用寄存器来传了。寄存器传参的好处是速度快,减少了对内存的读写次数。 当然,具体使用栈还是用寄存器传参数,这个不是编程语言决定的,而是编译器在编译生成CPU指令时决定的,如果编译器非要在x64架构CPU上使用线程栈来传参那也不是不行,这个对高级语言是无感知的...
intadd(inta,intb,intc,intd,inte,intf,intg,inth){// 8 个参数intsum = a + b + c + d + e + f + g + h;//相加求和returnsum;}intmain(void){inti =10;intj =20;intk = i + j;intsum =add(11,22,33,44,55,66,77,88);intm = k;// 为了观察 %rax Caller Save 寄存器的恢...
而test2函数由于是叶子函数直接使用ebp/esp(此时它们两个相等),其参数和局部变量直接使用red zone空间存储,test2函数的栈帧空间布局如下: yezi2 x86-64.png 关于ebp基地址指针的使用(原标题:节约通用寄存器) 其实很多时候,我们发现ebp指针并没有使用,而仅仅使用esp指针就可以定位,并且DWARF(Debugging With Attributed ...