sltu проверяет, является ли сумма двух наименее значимых слов меньше или равна одному из операндов.
Не совсем: устанавливается $10
в 1, если сумма двух наименее значимых слов строго меньше, чем один из операндов (рассматривается как 32-разрядные значения без знака); и 0, если сумма равна или больше этого операнда.
Если это так, то когда произошел перенос, верно?
Да.
Рассмотрим, что может произойти при добавлении различных возможных значений b к некоторому конкретному значению a (где все является 32-разрядным значением без знака):
- Если переполнение не произошло, мы должны иметь a <= sum <= 0xFFFFFFFF, поэтому 0 <= <em>b <= (0xFFFFFFFF - <em>a ) .
- Остальные случаи для b вызывают переполнение; фактическая сумма в этих случаях должна быть 0x100000000 <= sum <= <em>a + 0xFFFFFFFF, что при усечении до 32 битов дает 0 <= sum <= <em>a - 1.
Чтобы проверить, произошел ли перенос, при добавлении двух наиболее значимых слов и сохранить результат в $ 9
Я должен сделать:
sltu $9, $10, $12 # set carry-in bit
Не совсем.
Проблема в том, что вы добавляете два 32-битных значения и , возможно, перенос из суммы наименее значимых слов. Например, рассмотрим случай, когда есть перенос, и оба наиболее значимых слова - 0xFFFFFFFF: сумма будет 1+ 0xFFFFFFFF + 0xFFFFFFFF = 0xFFFFFFFF, и поэтому перенос не будет установлен (но так и должно быть).
Один из способов справиться с этим - проверить наличие переноса после добавления $12
к $10
и повторить проверку после добавления $11
к этой сумме. Только одна из этих сумм может вызвать перенос ($12 + $10
переполняется только тогда, когда $12
равно 0xFFFFFFFF, поскольку $10
равно 0 или 1; в этом случае сумма равна 0, поэтому вторая сумма не может быть переполнена как хорошо).
Так что это может (отказ от ответственности: уже поздно, и это не проверено), добиваться цели:
addu $11, $13, $15
sltu $10, $11, $15 # carry from low word
addu $10, $10, $12
sltu $9, $10, $12 # possible carry from high word (1)
addu $10, $10, $14
sltu $8, $10, $14 # possible carry from high word (2)
or $9, $8, $9 # carry in result if either (1) or (2) were true (can't both be true at once)