Чтобы вычесть число, то есть v = a - b
такое же, как и добавление с отрицательным числом, то есть v = a + (-b)
. Но в целочисленной арифметике отрицательное число кодируется как 2-комплимент, то же самое, что и 1-комплимент + 1 и 1-комплимент - побитовое отрицание.
Таким образом, мы можем написать, что:
v1v0 = a1a0 - b1b0
v1v0 = a1a0 + ~b1~b0 + 1
так, мы можем записать это в сборке, как (предполагается, что b1 = а3 и b0 = а2):
add64: addu $v0, $a0, $a2 # add least significant word
nor $t0, $a2, $zero # ~a2
sltu $t0, $a0, $t0 # set carry-in bit (capturing overflow)
addu $v1, $t0, $a1 # add in first most significant word
addu $v1, $v1, $a3 # add in second most significant word
jr $ra
#PS: To capture the carry bit in a unsigned sum is equivalent to test if the sum
# can not be contained in a 32 bit register. I.e. if a0 + a2 > 2^32 - 1
sub64: nor $a3, $a3, $zero # ~b1
nor $a2, $a2, $zero # ~b0
jal add64 # v1v0 = a1a0 + ~b1~b0
# adding 1 to v1v0
ori $a0, $v0, 0
ori $a1, $v1, 0
ori $a2, $zero, 1
ori $a3, $zero, 0
jal add64
jr $ra
используя ваши идеи, которые, я думаю, вы ответили бы на ваш вопрос:
subu $v0, $a0, $a2 # $v0 = $a0 - $a2
sltu $v1, $a0, $a2 # $v1 = ($a0 < $a2)? 1:0(subtract 1 if there's a borrow for Lo words)
subu $a1, $a1, $v1 # $a1 = $a1 - $v1
subu $v1, $a1, $a3 # $v1 = $a1 - $a3
Я понял, что добавление, но не уверен, как работает вычитание ... – Meteorite
Мне было бы хорошо, если бы вы сделали явным, что вы хотите вычитать – Amadeus
, почему тэг [tag: mips64] здесь? В MIPS64 добавления и вычитания по сути являются 64 бит, и вам не нужно ничего особенного для этого. –