Где находится результат умножения C при вызове из GNU AS? - PullRequest
0 голосов
/ 23 апреля 2019

Я вызываю простую функцию, написанную на C из программы AS Gnu:

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, что явно неверно.

При умножении в AS результат помещается в 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 потеряна?

Ответы [ 2 ]

3 голосов
/ 23 апреля 2019

Похоже, вы работаете на 32-битной x86, поэтому long 32-битная.Даже если он был 64-битным, хотя вы выполняете оператор * на int s, результат будет int, и его можно усечь, поскольку поведение не определено, если оно переполняется.

Если вы хотите увидеть 64-битный результат, используйте (long long)a*b, верните long long и используйте %lld для его печати. ​​

0 голосов
/ 24 апреля 2019

тело foo() умножает два целых числа, они передают результат обратно в long int Это приводит к проблеме переполнения во время операции умножения.

Предлагайте:

#include <stdio.h>

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


int main( void )
{
    long result = foo( 100000, 100000 );
    printf( "%ld\n", result );
}

, что приводит к ожидаемому:

10000000000
...