我正在尝试编写 C 代码,其效果等同于以下汇编代码:
addq %rsi, %rdi
imulq %rdx, %rdi
movq %rdi, %rax
sarq $15, %rax
salq $31, %rax
andq %rdi, %rax
ret
有一个函数原型(prototype)
长解码(长x,长y,长z)
参数 x、y 和 z 在寄存器 %rdi、%rsi 和 %rdx 中传递。代码将返回值存储在寄存器 %rax 中。
到目前为止,我有以下 C 代码:
long decode(long x, long y, long z)
{
long w;
x = x+y;
x = x*z;
w = x;
w = ((x>>15)<<31);
return x&w;
}
其中,当使用 gcc -O2 -S -c filename.c 编译时产生以下内容:
addq %rdi, %rsi
imulq %rdx, %rsi
movq %rsi, %rax
sarq $15, %rax
salq $31, %rax
andq %rsi, %rax
ret
显然,寄存器 %rdi 和 %rsi 被交换了。
所以,如果我通过交换 x 和 y 来更改函数,它看起来像这样:
long decode4(long x, long y, long z)
{
long w;
y = x + y;
y = y * z;
w = y;
w = ((y>>15)<<31);
return y&w;
}
而且,程序集又是这样的:
addq %rdi, %rsi
imulq %rdx, %rsi
movq %rsi, %rax
sarq $15, %rax
salq $31, %rax
andq %rsi, %rax
ret
y 和 x 的交换,并没有改变生成的汇编代码中的任何东西。 关于如何解决该问题的任何想法? 谢谢!
最佳答案
您对代码的解释确实没有任何问题:
long decode(long x, long y, long z)
{
long w;
x = x+y;
x = x*z;
w = x;
w = ((x>>15)<<31);
return x&w;
}
它可以稍微简化,但它没有任何问题,因为输出仅在所用寄存器的反转方面有所不同。可观察到的结果将是相同的。您声明此要求:
I am trying to write C code that will have an effect equivalent to the following assembly
两者等价,所以我相信您的解决方案已经满足了作业要求。
有时这种类型的事情可以归结为所使用的编译器。我注意到我可以通过 GCC 4.6.4 和 -O2
优化级别获得您正在寻找的准确输出。您可以在 godbolt 上使用此代码输出是:
decode:
addq %rsi, %rdi
imulq %rdx, %rdi
movq %rdi, %rax
sarq $15, %rax
salq $31, %rax
andq %rdi, %rax
ret
这似乎与您类(class)的输出完全匹配。使用相同版本的 GCC (4.6.4),您可以获得相同的输出:
long decode(long x, long y, long z)
{
x = (x + y) * z;
return x & ((x >> 15) << 31);
}
关于c - 汇编语言到 C 问题与寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49343708/