Известно, что CF указывает на беззнаковое выполнение, а OF указывает на подписанное переполнение. Так как же программа сборки различает беззнаковые и подписанные данные, ведь это всего лишь последовательность битов? (Через дополнительную память для информации о типе, или через позиционную информацию, или еще?) И можно ли использовать эти два флага взаимозаменяемо?
про сборку CF (Carry) и OF (Overflow) флаг
Ответы (6)
Различие заключается в том, какие инструкции используются для управления данными, а не в самих данных. Современные компьютеры (примерно с 1970 г.) используют представление целочисленных данных, называемое дополнением до двух, в котором сложение и вычитание работают одинаково как для чисел со знаком, так и для чисел без знака.
Разница в представлении - это интерпретация самого старшего бита (также называемого битом знака). Для чисел без знака старший бит устанавливается, когда число находится в верхней половине полностью положительного диапазона. Для чисел со знаком старший бит устанавливается, когда число находится в нижней и отрицательной половине всего диапазона.
Различные инструкции могут использовать разные интерпретации одного и того же бита. Например, большинство больших машин имеют как знаковые, так и беззнаковые инструкции умножения. Машины с инструкцией «установить меньше» могут иметь как подписанные, так и неподписанные варианты.
OF (флаг переполнения) сообщает, изменил ли перенос знак самого значимого бита в результате, чтобы он отличался от наиболее значимых бит аргументов. Если числа интерпретируются как беззнаковые, флаг переполнения не имеет значения, но если они интерпретируются как подписанные, OF означает, например, что два больших положительных числа были добавлены и результат был отрицательным.
CF (флаг переноса) сообщает, был ли бит полностью удален из слова (например, в бит 33 или бит 65). Если числа интерпретируются как беззнаковые, флаг переноса означает, что сложение переполнено, и результат слишком велик, чтобы поместиться в машинное слово. Флаг переполнения не имеет значения.
Ответ на ваш вопрос заключается в том, что в ассемблерном коде есть несколько способов отличить подписанные данные от неподписанных:
- Он может выбрать CF или OF для знаковых или беззнаковых сравнений.
- Он может выбрать либо знаковые, либо беззнаковые инструкции умножения и деления.
- Он может выбрать знаковый или беззнаковый сдвиг вправо (знаковый копирует старший бит; беззнаковый сдвиг в нули).
(short)(0b1000_0000_0000_0000) равно -32768. Отсюда каждый второй установленный бит отсчитывается от -32768 до -1, где -1 означает 0b1111_1111_1111_1111. В двоичном дополнении нет знакового бита.
- person antiduh; 15.06.2018
128 для 8-битного беззнакового значения против -128 для 2-х дополнение 8 бит. Чтобы получить отрицательное целое число небольшой величины, требуется много установленных битов в других местах (с положительным значением позиции), чтобы сбалансировать его.
- person Peter Cordes; 15.08.2018
Не пытайтесь кодировать знак. Это невозможно. Вместо этого просто попытайтесь осознать истину: знака нет. Тогда вы увидите, что отличает не тип знака, а только вы.
Существуют разные коды операций для работы с подписанными и неподписанными данными. Если программа хочет сравнить два целых числа со знаком, она использует коды операций 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 для точных проверенных условий.
Это не так. Флаги просто устанавливаются всякий раз, когда возникает условие. Предполагается, что программист знает, с какими типами int он работает, и на основании этого знает, какой флаг проверять, если ему это небезразлично.
Невозможно попросить ЦП проверить и вернуть тип байта / слова / длины.
0xFF может содержать «255» или «-1», все зависит от того, какой тип байта говорит ваша программа.
Такие конструкции, как «тип», «знак» и т. Д., Существуют только в языках более высокого уровня, таких как Java, а не на уровне ЦП. В конце концов, для ЦП все является байтом, и наши программы должны организовывать и знать, как интерпретировать и манипулировать этими значениями ...
Флаги ЦП, обнаруженные в статусе, не навязывают никакой парадигмы, ваш код должен протестировать и соответствующим образом отреагировать.
В процессорах Intel регистры MMX и FPU фактически занимают одни и те же регистры. Таким образом, невозможно одновременно смешивать инструкции типа FPU и MMX, потому что значения одной операции будут уничтожать другую. Программы, которым необходимо либо завершить свои действия в одном режиме, например, выпустить инструкции FPU, а затем запустить MMX, но никогда оба одновременно.
Обычно программы на ассемблере не несут никакой специальной информации с переменными, чтобы указать, подписаны они или нет. Задача программиста - знать, когда проверять, какие флаги и когда использовать какие условные выражения (т.е. использовать JA вместо JG).
Итак, вам нужно знать, с каким типом переменной вы собираетесь работать, чтобы знать, какие команды использовать. Вот почему большинство языков программирования выдают предупреждения, когда программисты используют подписанные / беззнаковые типы взаимозаменяемо (то есть без явного приведения), поскольку это может быть сделано на оборудовании, но может привести к неожиданным результатам.