Умножение возвращает неверное значение для больших чисел x86 Assembly - PullRequest
0 голосов
/ 13 апреля 2019

Я пытаюсь написать простую программу на C (с использованием функции сборки extern), которая преобразует килограммы в фунты.Вот функция на C и способ ее вызова:

extern int convert(int value, int factor);

printf("Value in Pounds: %lf\n", convert(value, 2205)/1000.0); // doing division in C since I could not figure out how to work with floating point in assembler

Однако, когда параметр «value» слишком велик (я хочу, чтобы он работал с 9-значным целым числом), вычисленное значение неверно,Как я могу решить проблему?Вот код ассемблера:

.globl _convert

_convert:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax # get value
movl 12(%ebp), %ecx # get factor
mull %ecx
movl %ebp, %esp
popl %ebp
ret

Я также попытался написать цикл, который повторяет количество раз "фактор" и добавляет к нему "значение", но я получаю те же результаты.

1 Ответ

1 голос
/ 14 апреля 2019

9 цифр слишком велико, так как 999999999 · 2.20642> 2 ^ 31, поэтому это будет отрицательное число.Вместо этого используйте 32-разрядное целое число без знака или ограничьте входное значение максимумом 974083355.

Вы также можете попробовать использовать 3 параметра, чтобы коэффициент преобразования составлял целую дробь для большей точности:

extern unsigned int convert(int value, int numerator, int denominator);

    convert(num, 220462, 100000);


        .globl  _convert
_convert:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax  # get value
        movl    12(%ebp), %ecx # get numerator
        mull    %ecx           # edx:eax = product
        movl    16(%ebp), %ecx # get denominator
        divl    %ecx           # eax = quotient
        add     %edx,%edx      # round
        cmp     %ecx,%edx
        cmc
        adc     0,%eax
        movl    %ebp, %esp
        popl    %ebp
        ret
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...