Assembly x86添加以64位返回的A+B-C+D

Assembly x86添加以64位返回的A+B-C+D,assembly,x86,Assembly,X86,你好,我在大学里遇到了一个难题。 我们正在学习x86 asm,到目前为止,我花了很多时间来正确理解代码。 我尝试以签名方式添加a+b-c+d,并返回64位的值 问题是,代码实际上是有效的,我不明白为什么它会有效。 以下变量在main.c中声明为全局变量 char op8 = 0; short op16 = 0; int op32a=0,op32b=0; int main() { // (op1 + op2) - op3 + op4 op8 = 127; op16 = 30767; //

你好,我在大学里遇到了一个难题。 我们正在学习x86 asm,到目前为止,我花了很多时间来正确理解代码。 我尝试以签名方式添加a+b-c+d,并返回64位的值

问题是,代码实际上是有效的,我不明白为什么它会有效。 以下变量在main.c中声明为全局变量

 char op8 = 0;
 short op16 = 0;
 int op32a=0,op32b=0;

int main() {

// (op1 + op2) - op3 + op4
op8 = 127;
op16 = 30767;
//op8 + op16 = 30894
op32a = 1;
op32b = 2147483647;
//(op8 + op16 - op32a) =30893;
//30893 + 2147483647 = 2146514540
long long result = specialsum();

printf("%lld\n",result);
}

下面的代码实际生成正确的输出。 但我认为我在上一次操作中添加了adc$0,%edx,因此它将返回实际的64位数字

# (A+B-C) + D
movl op32b,%ebx
addl %ebx,%eax
adc $0,%edx
我不明白为什么它会产生正确的输出,即使我没有将进位添加到edx


有人能解释一下吗?

您唯一的测试用例生成的结果是2146514540,这是正的,但小于2^31-1,因此EDX=0是正确的。用mov而不是通常的方法将EDX归零,因此固定常数的上半部分恰好适用于测试的输入

如果测试结果为阴性,或者阳性结果大于2^31-1,则会在函数中发现一些错误

其他测试用例:op16=0xff,op8=1或更高,因此添加%bx,%ax将产生进位,adc$0,%eax将产生垃圾。在监视寄存器值时,使用调试器单步执行代码


提示,加载movswl op16,%eax;cltd签署扩展op16到edx:eax。

如果我想让程序更健壮,我应该在哪里添加溢出检查?你不明白哪部分?如果C是一个非常高的负数a+b--C,它应该溢出吗?如何将这个大数字添加到D并将其拆分为EDX:EAXC似乎只是op32a,其值为1。
# (A+B-C) + D
movl op32b,%ebx
addl %ebx,%eax
adc $0,%edx