Я читаю Computer Systems: A Programmer's Perspective, и домашняя работа должна была описать, как работает этот алгоритм.Как это 128-битное целочисленное умножение работает в сборке (x86-64)?
функция C:
void store_prod(__int128 *dest, int64_t x, int64_t y) {
*dest = x * (__int128)y;
}
Монтаж:
movq %rdx, %rax
cqto
movq %rsi, %rcx
sarq $63, %rcx
imulq %rax, %rcx
imulq %rsi, %rdx
addq %rdx, %rcx
mulq %rsi
addq %rcx, %rdx
movq %rax, (%rdi)
movq %rdx, 8(%rdi)
ret
Я не знаю, почему он выполняет: xh * yl + yh * xl = value which we add after unsigned multiplication
только предположение: сдвиг делает его 128 бит, так как вы получаете 64 бит в начале. 1 и -1 являются im, угадывая pos/neg числа –
Оба операнда для умножения должны быть одного типа. С этой целью 'x' повышается до типа' __int128', потому что 'y' относится к этому типу после броска, а целочисленный рейтинг продвижения' __int128' выше, чем у 'int64_t'. Одно из преобразований выполняется 'cqto', но это работает только на' rax', поэтому другое преобразуется 'sarq'. – EOF
@EOF, но почему мы умножаем младшие биты y с 1 или -1? imulq% rax,% rcx - эта инструкция после правого сдвига делает именно это. Поскольку бит младшего порядка не содержит никакой информации о знаках, почему мы это делаем? – denis631