про сборку CF (Carry) и OF (Overflow) флаг

Известно, что CF указывает на беззнаковое выполнение, а OF указывает на подписанное переполнение. Так как же программа сборки различает беззнаковые и подписанные данные, ведь это всего лишь последовательность битов? (Через дополнительную память для информации о типе, или через позиционную информацию, или еще?) И можно ли использовать эти два флага взаимозаменяемо?


person Pwn    schedule 27.04.2009    source источник


Ответы (6)


Различие заключается в том, какие инструкции используются для управления данными, а не в самих данных. Современные компьютеры (примерно с 1970 г.) используют представление целочисленных данных, называемое дополнением до двух, в котором сложение и вычитание работают одинаково как для чисел со знаком, так и для чисел без знака.

  • Разница в представлении - это интерпретация самого старшего бита (также называемого битом знака). Для чисел без знака старший бит устанавливается, когда число находится в верхней половине полностью положительного диапазона. Для чисел со знаком старший бит устанавливается, когда число находится в нижней и отрицательной половине всего диапазона.

  • Различные инструкции могут использовать разные интерпретации одного и того же бита. Например, большинство больших машин имеют как знаковые, так и беззнаковые инструкции умножения. Машины с инструкцией «установить меньше» могут иметь как подписанные, так и неподписанные варианты.

  • OF (флаг переполнения) сообщает, изменил ли перенос знак самого значимого бита в результате, чтобы он отличался от наиболее значимых бит аргументов. Если числа интерпретируются как беззнаковые, флаг переполнения не имеет значения, но если они интерпретируются как подписанные, OF означает, например, что два больших положительных числа были добавлены и результат был отрицательным.

  • CF (флаг переноса) сообщает, был ли бит полностью удален из слова (например, в бит 33 или бит 65). Если числа интерпретируются как беззнаковые, флаг переноса означает, что сложение переполнено, и результат слишком велик, чтобы поместиться в машинное слово. Флаг переполнения не имеет значения.

Ответ на ваш вопрос заключается в том, что в ассемблерном коде есть несколько способов отличить подписанные данные от неподписанных:

  • Он может выбрать CF или OF для знаковых или беззнаковых сравнений.
  • Он может выбрать либо знаковые, либо беззнаковые инструкции умножения и деления.
  • Он может выбрать знаковый или беззнаковый сдвиг вправо (знаковый копирует старший бит; беззнаковый сдвиг в нули).
person Norman Ramsey    schedule 27.04.2009
comment
так что «любой путь возможен», но ассемблерный код выбирает наиболее «значимый» (тот, который имеет смысл)? - person Pwn; 27.04.2009
comment
Для чисел со знаком старший бит НЕ означает большое отрицательное значение, а только отрицательное значение. - person MarcH; 29.03.2011
comment
Следует заметить, что CF также можно использовать как [Bit Bit] (en.wikipedia.org/wiki/Carry_flag) - person Tony; 28.03.2015
comment
Для аналогичного, но более подробного объяснения этого с несколькими 4-битными примерами см. Условия / флаги переноса и переполнения. См. Также другие ссылки в вики-странице по тегам x86. - person Peter Cordes; 09.10.2016
comment
@MarcH - Я так понимаю, вашему комментарию 7 лет, но я думаю, что это неправильно. Числа со знаком могут храниться в различных представлениях, но в данном контексте мы обсуждаем целые числа с дополнением до двух. В дополнительном двоичном коде установленный самый старший бит означает, что у вас очень большое отрицательное значение. (short)(0b1000_0000_0000_0000) равно -32768. Отсюда каждый второй установленный бит отсчитывается от -32768 до -1, где -1 означает 0b1111_1111_1111_1111. В двоичном дополнении нет знакового бита. - person antiduh; 15.06.2018
comment
Число -1 не имеет очень большого абсолютного значения (и есть бит знака). Я отредактировал ответ. - person MarcH; 15.06.2018
comment
@MarcH: Я думаю, что исходный ответ был (попыткой) описать разрядное значение только самого msb: 128 для 8-битного беззнакового значения против -128 для 2-х дополнение 8 бит. Чтобы получить отрицательное целое число небольшой величины, требуется много установленных битов в других местах (с положительным значением позиции), чтобы сбалансировать его. - person Peter Cordes; 15.08.2018
comment
Спасибо @PeterCordes, я понимаю, что вы имеете в виду, но я не уверен, что Норман Рэмси имел в виду именно это, я бы хотел, чтобы он все еще был рядом. В любом случае вы предложили мне еще раз перефразировать, на этот раз в терминах диапазонов. Надеюсь, это еще яснее, дайте нам знать, что вы думаете. - person MarcH; 16.08.2018
comment
@MarcH: Мне нравится твое обновление. Вместо того, чтобы говорить о разряде msb в дополнении до 2, говорить о половинах представимого диапазона, вероятно, не менее полезно. (Это все равно будет справедливо для дополнения и величины знака, поэтому он более общий. Но этот ответ на самом деле не нуждается в объяснении замещающего значения 2, так что это нормально.) - person Peter Cordes; 16.08.2018

Не пытайтесь кодировать знак. Это невозможно. Вместо этого просто попытайтесь осознать истину: знака нет. Тогда вы увидите, что отличает не тип знака, а только вы.

person Community    schedule 27.04.2009

Существуют разные коды операций для работы с подписанными и неподписанными данными. Если программа хочет сравнить два целых числа со знаком, она использует коды операций jl, jle, jg и jge, где l и g обозначают l ess и g reater соответственно. . Если программа хочет сравнить два целых числа без знака, она использует коды операций jb, jbe, ja и jae, где a и b обозначают a bove и b elow соответственно. . Во всех случаях буква e означает «или равно». Эти коды операций используются для ветвления на основе сравнения.

Точно так же есть инструкции setCC, которые устанавливают байт в 0 или 1 в зависимости от сравнения. Эти функции идентичны - есть setl, setle, setg, setge, setb, setbe, seta, setae и другие.

Подписанные коды операций проверяют флаги ZF, OF и SF. Коды операций без знака проверяют флаги ZF, CF и SF. См. Разделы Справочного руководства программиста 80386 с инструкциями по JCC и инструкции setCC для точных проверенных условий.

person Adam Rosenfield    schedule 27.04.2009

Это не так. Флаги просто устанавливаются всякий раз, когда возникает условие. Предполагается, что программист знает, с какими типами int он работает, и на основании этого знает, какой флаг проверять, если ему это небезразлично.

person jmucchiello    schedule 27.04.2009

Невозможно попросить ЦП проверить и вернуть тип байта / слова / длины.

0xFF может содержать «255» или «-1», все зависит от того, какой тип байта говорит ваша программа.

Такие конструкции, как «тип», «знак» и т. Д., Существуют только в языках более высокого уровня, таких как Java, а не на уровне ЦП. В конце концов, для ЦП все является байтом, и наши программы должны организовывать и знать, как интерпретировать и манипулировать этими значениями ...

Флаги ЦП, обнаруженные в статусе, не навязывают никакой парадигмы, ваш код должен протестировать и соответствующим образом отреагировать.

В процессорах Intel регистры MMX и FPU фактически занимают одни и те же регистры. Таким образом, невозможно одновременно смешивать инструкции типа FPU и MMX, потому что значения одной операции будут уничтожать другую. Программы, которым необходимо либо завершить свои действия в одном режиме, например, выпустить инструкции FPU, а затем запустить MMX, но никогда оба одновременно.

person mP.    schedule 27.04.2009

Обычно программы на ассемблере не несут никакой специальной информации с переменными, чтобы указать, подписаны они или нет. Задача программиста - знать, когда проверять, какие флаги и когда использовать какие условные выражения (т.е. использовать JA вместо JG).

Итак, вам нужно знать, с каким типом переменной вы собираетесь работать, чтобы знать, какие команды использовать. Вот почему большинство языков программирования выдают предупреждения, когда программисты используют подписанные / беззнаковые типы взаимозаменяемо (то есть без явного приведения), поскольку это может быть сделано на оборудовании, но может привести к неожиданным результатам.

person SoapBox    schedule 27.04.2009