Я читаю «Компьютерные системы - перспектива программиста» Брайанта и О'Халларона.
В разделе, касающемся сравнений, говорится, что команда SETB Dest
устанавливает пункт назначения равным 1, если предыдущий результат команды cmpq A, B
между значениями без знака меньше 0.
В нем также говорится, что, другими словами, он устанавливает целевое значение в значение бита CF (флаг переноса).
Но у меня есть сомнение, контрпример и вопрос.
Рассмотрим следующую функцию C:
char cmp_u(unsigned char a, unsigned char b) {
return (a < b);
}
Он генерируется с gcc
ассемблерный код выглядит так:
cmpb %sil, %dil
setb %al
ret
Таким образом, он сначала оценивает a - b
с помощью команды cmpb
и устанавливает флаги в соответствии с результатом. А затем (согласно книге) устанавливает возвращаемое значение равным 1, если установлено CF
, и 0 в противном случае.
Теперь рассмотрим, что a = 1
и b = 2
(a a = 0000 0001 и b = 0000 0010
и -b = 1111 1110
. Поэтому a - b = 0000 0001 + 1111 1110 = 1111 1111
. Как видите, эта операция не выдает бит выполнения, поэтому CF должен быть установлен в ноль. И это противоречие.
Рассмотрим противоположный случай: a = 2
и b = 1
. a - b = 0000 0010 + 1111 1111 = 1 0000 0001
. Бит выполнения есть, и поэтому CF должен быть установлен в 1. Опять противоречие.
Приведенные выше примеры показывают, что setb
должен установить 1 в качестве пункта назначения, когда CF = 0 и 0 в противном случае.
И вопрос:
Что происходит, когда старший значащий бит b
установлен в 1? Например, когда b = 128 = 1000 0000 (bit representation)
?