В документации ARM здесь сказано, что:
C
Установите в 1, когда операция привела к переносу, в противном случае сбросьте в 0.
и
Выполняется перенос:
... если результат вычитания положительный или равен нулю ...
(Очевидно, что результат должен рассматриваться как число со знаком; в противном случае перенос будет всегда выполняться с вычитаниями).
Я знаю, что флаг переноса "инвертирован" в ARM. Таким образом, если вычитание требует заимствования, тогда флаг переноса не устанавливается, даже если логически было выполнено «перенос» (т. Е. Без знака без знака).
Это имеет смысл для этого сценария:
CMP 3,5
Это сделает 3-5
. Начиная с 3 < 5
, происходит потеря значения без знака, и флаг переноса не будет установлен в ARM. Используя логику в документации ARM, 3-5
приводит к -2
, что отрицательно, поэтому перенос не происходит и, следовательно, флаг переноса не устанавливается.
Теперь, согласно документации ARM, связанной выше, код условия LO
(он же CC
) в ARM, который представляет сравнение «без знака, нижнее», равен true
, когда флаг переноса не установлен в ARM (то есть C == 0
). Таким образом, для приведенного выше примера код условия LO
будет истинным. Это также имеет смысл, поскольку 3 меньше 5, если рассматривать их как числа без знака.
========
Теперь рассмотрим этот сценарий:
CMP -1,0
Это будет делать -1-0
, то есть 0xffffffff - 0x00000000
. Логически, начиная с 0xffffffff > 0x00000000
, не происходит потери значения без знака и устанавливается флаг переноса.
Но посмотрите, что написано в документации ARM:
Выполняется перенос:
... если результат вычитания положительный или равен нулю ...
В соответствии с документацией выше , поскольку -1-0
приводит к -1
, что отрицательно, перенос не происходит и, следовательно, флаг переноса не устанавливается. Но это означает, что код условия LO
имеет значение true, что означает, что -1
меньше, чем 0
, когда обрабатывает их обоих как числа без знака (точно так же, как 3
было ниже, чем 5
, когда мы обрабатывали их обоих как числа без знака в предыдущем сценарии). Очевидно, что это не так с 0xffffffff > 0x00000000
.
Как объяснить это противоречие, когда я пытаюсь вычислить логику флага переноса, основываясь на том, что говорится в документации?