Сборка: увеличение на 2 (или большее число) без разрушения CF в контуре АЦП? - PullRequest
0 голосов
/ 15 октября 2018

Я пытаюсь протестировать функцию добавления в 64-битной сборке TDM-GCC в Windows.Некоторое время назад я искал ресурсы и наткнулся на код, похожий на этот (я внес некоторые изменения, чтобы скомпилировать его в TDM-GCC).

typedef struct
{
    int size;
    __uint64_t uints[130];
} BigInteger;

void add(BigInteger *X, BigInteger *Y);   // X += Y
    // %rcx holds address of X, and %rdx holds address of Y apparently.

    // calc.s - assembly file
    .globl add
add:
    movq    8(%rdx), %rax
    addq    %rax, 8(%rcx)
    movq    16(%rdx), %rax
    adcq    %rax, 16(%rcx)
    movq    24(%rdx), %rax
    adcq    %rax, 24(%rcx)
    ...     ...

Этот первый код сборки работает.Недостатком является то, что даже для небольших чисел потребуется столько же времени, сколько и для расчета наибольшего размера.Поэтому вместо этого я проверил размер X и Y и поместил цикл с условием размера, чтобы не всегда приходилось добавлять весь массив, если X и Y не большие.

    ...
// %r13 holds X addr, %r14 holds Y addr.
    addq    $8, %r13   // I have tried  incq %r13
    addq    $8, %r14   // I have tried  incq %r14
    movq    (%r14), %rax
    addq    %rax, (%r13)
    decl    %ecx
    cmpl    $0, %ecx
    je      .add4
.add3:
    addq    $8, %r13   // I have tried  incq %r13
    addq    $8, %r14   // I have tried  incq %r14
    movq    (%r14), %rax
    adcq    %rax, (%r13)
    loop    .add3
.add4:
    ...

НоЯ был слишком прост, чтобы думать, что добавление 8 байтов к X и адресу Y (% r13,% r14) с помощью оператора ADDQ позволило бы выполнить итерацию по массиву.Проблема здесь в том, что если я использую оператор ADDQ, подобный этому, он сбрасывает флаг переноса в 0, поэтому весь цикл, который вычисляет сложение с переносом (. Add3) , прерывается.Я попытался использовать

    incq %r13

, думая, что incq будет работать аналогично увеличению указателя в C ++, который знает, на сколько байтов он должен переместиться.Но это только увеличение значений регистра на 1, а не на 8, на что, как я думал, оно будет перемещаться.


Поэтому мой вопрос: есть ли способ в сборке увеличить регистр на число больше 1, илисделать дополнение, не касаясь Carry Flag вообще?(Не добавить, adc, потому что оба они устанавливают флаг переноса в конце)

1 Ответ

0 голосов
/ 15 октября 2018

Использовать эффективный адрес загрузки с регистром + смещение

        lea     rax,[rax+8]    ;add 8 to rax
...