о сборке флагов CF (Carry) и OF (Overflow) - PullRequest
26 голосов
/ 27 апреля 2009

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

Ответы [ 6 ]

35 голосов
/ 27 апреля 2009

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

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

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

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

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

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

  • Он может выбрать либо CF, либо OF для сравнения со знаком или без знака.
  • Он может выбрать либо умножение с делением со знаком, либо без знака.
  • Он может выбрать сдвиг вправо со знаком или без знака (подпись копирует старший бит; сдвиг без знака в нуле).
17 голосов
/ 27 апреля 2009

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

5 голосов
/ 27 апреля 2009

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

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

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

4 голосов
/ 27 апреля 2009

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

3 голосов
/ 27 апреля 2009

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

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

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

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

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

1 голос
/ 27 апреля 2009

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

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

...