我调用Gnu中用C编写的简单函数作为程序:
C文件:

long foo(int a, int b){
    return a*b;
}

作为文件:
.data
TEXT: .ascii "Result: %ld\n\0"
.text
.globl main
main:
    pushl $100000
    pushl $100000
    call foo
    addl $8, %esp

    pushl %eax
    pushl $TEXT
    call printf
    addl $8, %esp

    pushl $0
    call exit


在%eax寄存器中,我得到:1410065408,这显然是错误的。
当乘法时,结果被放入EDX:EAX中。但在这种情况下它是如何工作的呢?
当使用-S中的gcc选项编译时,我得到的是:
    .globl  foo
    .type   foo, @function
foo:
    pushl   %ebp
    movl    %esp, %ebp
    movl    8(%ebp), %eax
    imull   12(%ebp), %eax
    popl    %ebp
    ret

是否意味着来自%edx寄存器的结果的上半部分丢失?

最佳答案

这看起来像是在32位x86上工作,所以long是32位的。即使在执行*s上的int运算符时它是64位的,因此结果是int,并且可以被截断,因为如果溢出,行为是未定义的。
如果要查看64位结果,请使用(long long)a*b,返回long long,然后使用%lld打印。

10-07 20:34