Беззнаковое сравнение. Команда SETB в ассемблерном коде - PullRequest
0 голосов
/ 08 ноября 2018

Я читаю «Компьютерные системы - перспектива программиста» Брайанта и О'Халларона.

В разделе, касающемся сравнений, говорится, что команда 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)?

...