- 论坛徽章:
- 0
|
#include "stdio.h"
typedef unsigned long long u64;
typedef unsigned int u32;
inline u64 mod_mul(u64 a, u64 b, u64 p)
{
u64 ret;
__asm__(
"movq %0, %%rax;\n"
"mulq %1;\n"
"divq %2;\n"
"movq %%rdx, %3;"
:
:"g"(a), "g"(b), "g"(p), "g"(ret)
:"%rax", "rdx"
);
return ret;
}
u64 mod_test(u64 a, u64 n, u64 p)
{
u64 ret = 1;
u64 b = mod_mul(a, a, p);
ret = mod_mul(ret, b, p);
return ret;
}
int main()
{
u64 ret = mod_test(2, 3, 10);
printf("%llu\n", ret);
return 0;
}
gcc版本是4.1.1-1
x86-64版本的fc5
在不加优化的情况下运行正常,输出为4
在加了-O2或-O1优化后,输出为1
加-S查看汇编代码,发现问题在mod_test函数中
主要汇编代码如下:
mod_test:
.LFB13:
movq%rdx, %rcx
#APP
movq %rdi, %rax;
mulq %rdi;
divq %rcx;
movq %rdx, %rax;//内联mod_mul(a, a, p)结束(1)
movq $1, %rax;//此处出现问题 (2)
mulq %rax;//(3)
divq %rcx;
movq %rdx, %rax;
在(1)结束之后,应该对b进行赋值的,而不是将返回值暂存在rax中
暂存在rax中的好处是少一次movq指令,但怎么能保证在b = mod_mul(a, a, p)到(3)之间rax没有变化呢
并且在(2)中,第一个参数(ret)已经使用了rax,第二个参数怎么还能用rax来传进来 |
|