主题:求助, 加法进位的问题
我写了个128位的加法函数,但不知道错在哪里:
0xfffffffd 00000000 00000000 fffffffe
+ 0x00000000 00000001 00000002 00000003
= 0xfffffffd 00000001 00000003 00000001
这个加法应该是没有溢出的。 我写的add128这个函数可以算出正确的结果,但是返回的状态是溢出了(返回0是没溢出,1是溢出),不知道哪里错了。哪位大牛帮我分析下,谢谢。
[code=c]
/*
Dev-C++ 4.9.9.2
*/
#include <stdio.h>
#define PRINT(x) printf("\n%-7s",#x)
#define check(x) PRINT(x),_check(&x)
typedef struct int128{
unsigned int _0, _1, _2, _3;
}int128;
/*
这个函数计算 128位数的加法: *p = n1 + n2
*/
inline int
add128 (int128 *p, int128 n1, int128 n2)
{
__asm__ ( "movl %0, %%edx\n\n\t" : :"p"(p) );//把p的值存如edx
__asm__ ( "movl %0, %%eax \n\t"
"addl %1, %%eax\n\t"
"movl %%eax,(%%edx)\n"
:
:"m"(n1._0), "m"(n2._0)
);//p->_0 = n2._0+n1._0;最低位相加,加法指令用add
__asm__ ( "movl %0, %%eax \n\t"
"adcl %1, %%eax \n\t"
"movl %%eax,4(%%edx)\n"
:
:"m"(n1._1), "m"(n2._1)
);//p->_1 = n2._1+n1._1;不过加法指令用adc
__asm__ ( "movl %0, %%eax \n\t"
"adcl %1, %%eax \n\t"
"movl %%eax,8(%%edx)\n"
:
:"m"(n1._2), "m"(n2._2)
);//p->_2 = n2._2+n1._2;不过加法指令用adc
__asm__ ( "movl %0, %%eax \n\t"
"adcl %1, %%eax \n\t"
"movl %%eax,12(%%edx)\n"
:
:"m"(n1._3), "m"(n2._3)
);//p->_3 = n2._3+n1._3;不过加法指令用adc
__asm__ ( "lahf \n\t"
"andl $0x1, %eax \n\t"
);//把FLAG的状态传入ah,然后让eax和0x1 做&运算,提取CF的状态
//如果CF为1,这此次加法 溢出
}
/*
把指针p指向的对象(128位整数) 按照高位到低位的顺序输出
*/
void _check( const int128 *p)
{
printf(" 0X %08x %08x %08x %08x ",(*p)._3,(*p)._2,(*p)._1,(*p)._0);
}
/**************** 主函数 *****************/
int main(void)
{
int128 n1 = {0xfffffffeUL,0,0,0xfffffffdUL};
int128 n2 = {3,2,1,0}, n3={0};
int status = add128(&n3,n1,n2);// n1 + n2的值保存到 n3,status记录是否溢出
printf("\n%*s",35,"高位 <-- 低位");
check(n1);check(n2);check(n3);
printf("\nstatus= %d\n",status);
puts("\nexit\n");
return 0;
}[/code]
0xfffffffd 00000000 00000000 fffffffe
+ 0x00000000 00000001 00000002 00000003
= 0xfffffffd 00000001 00000003 00000001
这个加法应该是没有溢出的。 我写的add128这个函数可以算出正确的结果,但是返回的状态是溢出了(返回0是没溢出,1是溢出),不知道哪里错了。哪位大牛帮我分析下,谢谢。
[code=c]
/*
Dev-C++ 4.9.9.2
*/
#include <stdio.h>
#define PRINT(x) printf("\n%-7s",#x)
#define check(x) PRINT(x),_check(&x)
typedef struct int128{
unsigned int _0, _1, _2, _3;
}int128;
/*
这个函数计算 128位数的加法: *p = n1 + n2
*/
inline int
add128 (int128 *p, int128 n1, int128 n2)
{
__asm__ ( "movl %0, %%edx\n\n\t" : :"p"(p) );//把p的值存如edx
__asm__ ( "movl %0, %%eax \n\t"
"addl %1, %%eax\n\t"
"movl %%eax,(%%edx)\n"
:
:"m"(n1._0), "m"(n2._0)
);//p->_0 = n2._0+n1._0;最低位相加,加法指令用add
__asm__ ( "movl %0, %%eax \n\t"
"adcl %1, %%eax \n\t"
"movl %%eax,4(%%edx)\n"
:
:"m"(n1._1), "m"(n2._1)
);//p->_1 = n2._1+n1._1;不过加法指令用adc
__asm__ ( "movl %0, %%eax \n\t"
"adcl %1, %%eax \n\t"
"movl %%eax,8(%%edx)\n"
:
:"m"(n1._2), "m"(n2._2)
);//p->_2 = n2._2+n1._2;不过加法指令用adc
__asm__ ( "movl %0, %%eax \n\t"
"adcl %1, %%eax \n\t"
"movl %%eax,12(%%edx)\n"
:
:"m"(n1._3), "m"(n2._3)
);//p->_3 = n2._3+n1._3;不过加法指令用adc
__asm__ ( "lahf \n\t"
"andl $0x1, %eax \n\t"
);//把FLAG的状态传入ah,然后让eax和0x1 做&运算,提取CF的状态
//如果CF为1,这此次加法 溢出
}
/*
把指针p指向的对象(128位整数) 按照高位到低位的顺序输出
*/
void _check( const int128 *p)
{
printf(" 0X %08x %08x %08x %08x ",(*p)._3,(*p)._2,(*p)._1,(*p)._0);
}
/**************** 主函数 *****************/
int main(void)
{
int128 n1 = {0xfffffffeUL,0,0,0xfffffffdUL};
int128 n2 = {3,2,1,0}, n3={0};
int status = add128(&n3,n1,n2);// n1 + n2的值保存到 n3,status记录是否溢出
printf("\n%*s",35,"高位 <-- 低位");
check(n1);check(n2);check(n3);
printf("\nstatus= %d\n",status);
puts("\nexit\n");
return 0;
}[/code]