X86_64调用约定问题
我们知道,X86_64 使用寄存器 rdi、rsi、rdx、rcx、r8、r9 来存储普通函数的参数,并使用堆栈内存来存储大参数,并使用 xmm 来存储 float 和 double 参数。但在我的代码中,函数“myuprobe_sum_dww_ptr”已连接。它不使用 rdi 来存储第一个参数,而是存储局部变量。请看下面的代码,我在代码中注释了寄存器的使用信息。有人可以帮忙解释一下吗?
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
struct double_wraper
{
double data;
};
struct double_wraper_wraper
{
double_wraper_wraper()
{
dp = new double_wraper();
}
~double_wraper_wraper()
{
delete dp;
}
uint32_t a;
struct double_wraper d;
struct double_wraper* dp;
};
// a -> rdi, b -> rsi
uint32_t myuprobe_sum_int(uint32_t a, uint32_t b)
{
//printf("%u + %u = %u, addr = %p\n", a, b, &a);
return a + b;
}
// d1 -> rsi, d2 -> rdx, v -> rcx
double_wraper_wraper myuprobe_sum_dww_ptr(const double_wraper_wraper* d1, const double_wraper_wraper* d2, uint32_t v)
{
double_wraper_wraper d3; // d3 -> rdi, why??????????????
d3.a = d1->a + d2->a + v;
d3.d.data = d1->d.data + d2->d.data;
d3.dp->data = d1->dp->data + d2->dp->data;
//printf("%u + %u = %u, addr = %p\n", d1->a, d2->a, d3.a, d1);
//printf("%lf + %lf = %lf, addr = %p\n", d1->d.data, d2->d.data, d3.d.data, d1);
printf("%lf + %lf = %lf, addr = %p\n", d1->dp->data, d2->dp->data, d3.dp->data, d1);
return d3;
}
// d1 -> rdi, d2 -> rsi, d3 -> rdx, v -> rcx
double_wraper myuprobe_sum_dw_ptr(const double_wraper* d1, const double_wraper* d2, const double_wraper_wraper* d3, uint32_t v)
{
double_wraper d4;
d4.data = d1->data + d2->data + d3->d.data;
//printf("%lf + %lf + %lf = %lf, addr = %p\n", d1->data, d2->data, d3->d.data, d4.data, d1);
return d4;
}
int main()
{
while(1) {
double_wraper_wraper d4, d5;
d4.a = rand();
d4.d.data = rand() + (double)rand() / RAND_MAX;
d4.dp->data = rand() + (double)rand() / RAND_MAX;
d5.a = rand();
d5.d.data = rand() + (double)rand() / RAND_MAX;
d5.dp->data = rand() + (double)rand() / RAND_MAX;
auto d7 = myuprobe_sum_dww_ptr(&d4, &d5, 100);
uint32_t a,b;
a = rand();
b = rand();
auto c = myuprobe_sum_int(a, b);
double_wraper d8,d9;
d8.data = rand() + (double)rand() / RAND_MAX;
d9.data = rand() + (double)rand() / RAND_MAX;
auto d10 = myuprobe_sum_dw_ptr(&d8, &d9, &d4, 100);
usleep(5000000);
}
}
编译:g++ test.cpp -o test -g -O0
As we know, X86_64 use register rdi, rsi, rdx, rcx, r8, r9 to store normal function's arguments, and use stack memory to store large argument, and use xmm to store float and double argument. But in my code, the function 'myuprobe_sum_dww_ptr' is wired. It doesn't use rdi to store the first argument but to store a local variable. Please see the code below, and I have commented the register usage information in the code. Could anyone help to explain?
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
struct double_wraper
{
double data;
};
struct double_wraper_wraper
{
double_wraper_wraper()
{
dp = new double_wraper();
}
~double_wraper_wraper()
{
delete dp;
}
uint32_t a;
struct double_wraper d;
struct double_wraper* dp;
};
// a -> rdi, b -> rsi
uint32_t myuprobe_sum_int(uint32_t a, uint32_t b)
{
//printf("%u + %u = %u, addr = %p\n", a, b, &a);
return a + b;
}
// d1 -> rsi, d2 -> rdx, v -> rcx
double_wraper_wraper myuprobe_sum_dww_ptr(const double_wraper_wraper* d1, const double_wraper_wraper* d2, uint32_t v)
{
double_wraper_wraper d3; // d3 -> rdi, why??????????????
d3.a = d1->a + d2->a + v;
d3.d.data = d1->d.data + d2->d.data;
d3.dp->data = d1->dp->data + d2->dp->data;
//printf("%u + %u = %u, addr = %p\n", d1->a, d2->a, d3.a, d1);
//printf("%lf + %lf = %lf, addr = %p\n", d1->d.data, d2->d.data, d3.d.data, d1);
printf("%lf + %lf = %lf, addr = %p\n", d1->dp->data, d2->dp->data, d3.dp->data, d1);
return d3;
}
// d1 -> rdi, d2 -> rsi, d3 -> rdx, v -> rcx
double_wraper myuprobe_sum_dw_ptr(const double_wraper* d1, const double_wraper* d2, const double_wraper_wraper* d3, uint32_t v)
{
double_wraper d4;
d4.data = d1->data + d2->data + d3->d.data;
//printf("%lf + %lf + %lf = %lf, addr = %p\n", d1->data, d2->data, d3->d.data, d4.data, d1);
return d4;
}
int main()
{
while(1) {
double_wraper_wraper d4, d5;
d4.a = rand();
d4.d.data = rand() + (double)rand() / RAND_MAX;
d4.dp->data = rand() + (double)rand() / RAND_MAX;
d5.a = rand();
d5.d.data = rand() + (double)rand() / RAND_MAX;
d5.dp->data = rand() + (double)rand() / RAND_MAX;
auto d7 = myuprobe_sum_dww_ptr(&d4, &d5, 100);
uint32_t a,b;
a = rand();
b = rand();
auto c = myuprobe_sum_int(a, b);
double_wraper d8,d9;
d8.data = rand() + (double)rand() / RAND_MAX;
d9.data = rand() + (double)rand() / RAND_MAX;
auto d10 = myuprobe_sum_dw_ptr(&d8, &d9, &d4, 100);
usleep(5000000);
}
}
Compile: g++ test.cpp -o test -g -O0
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论