Можно ли сказать, что процессор x86 имеет типы данных? - PullRequest
0 голосов
/ 07 февраля 2019

В процессоре x86 есть некоторые инструкции, которые имеют дело с целыми числами и числами с плавающей запятой.

Например: инструкция INC увеличивает целое число (которое может быть сохранено в памяти или в регистре) на 1, поэтому инструкция INC «знает», что должна интерпретировать биты, которыми она манипулирует, как целое число.Итак, можем ли мы сказать, что у процессора x86 есть типы данных (так же, как мы можем сказать, что у C ++ есть типы данных)?или для того, чтобы мы могли сказать, что процессор x86 должен обеспечивать другие функции, такие как безопасность типов (которых он не обеспечивает)?

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

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

Некоторые инструкции, такие как умножение и деление, если работают с битами разного размера, два 8-битныхоперанды, получающиеся в результате в результате 16-битного вывода, имеют понятие знака для машин, дополняющих двойки, умножение без знака и умножение со знаком различны, и это только потому, что им нужно подписать расширение одного из операндов для завершения этой операции.если вы делаете n битов и n битов, то вам даже не важно, что это за биты.деление аналогично.

Можно сказать, что операции с плавающей запятой подразумевают, что биты представляют этот формат, и это справедливо.

Но понятие без знака int против char * против float и т. д. лежит в основномв мозгу программистов и на языке высокого уровня процессоры очень и очень глупы, они берут биты, на которые они подают инструкции и данные, и оперируют ими, в конечном итоге задача программиста - убедиться, что эти биты являются инструкциями, а данныеданные и выполняет желаемую задачу.Процессор - всего лишь машина для манипулирования битами, записано определение того, что делает каждая инструкция, чтобы вы знали, какие биты вы получите, основываясь на битах, которые вы передаете.

Попытка создать язык ассемблера или машинный код«Типы» - это, в основном, пустая трата времени, в некоторых синтаксисах есть такие вещи, как mov word ptr и т. д., но это природа набора команд и, что более важно, языка ассемблера, другой синтаксис можно было использовать, а затем использовать для получения правильной машиныкод, сгенерированный без использования указателя слова или ptr, чтобы просто заявить, что это косвенный режим адресации.

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

Самый простой для понимания - это inc или add, если вы берете два целых числа в вашем языке высокого уровня или целое число и немедленное и выполняете операцию, которая имеет смысл hello = hello +1;Но вы можете отличить эту инструкцию от char * x;... х ++;Вы все еще получаете некоторый регистр или ссылку на память и немедленное добавление.процессор не знает и не заботится о том, что один является переменной / целым числом, а другой - адресом, который он просто операнд и выводит.

0 голосов
/ 07 февраля 2019

Да, в asm есть операции, которые работают с данными в разных форматах, и вы можете вызывать эти типы.Но есть ноль типа безопасность .Это хороший способ выразить это.

, поэтому инструкция INC «знает», что должна интерпретировать биты, которыми она манипулирует, как целое число.

Но этонеуклюжий способ выразить это. INC ничего не «знает» ;он просто передает операнд в двоичный сумматор в ALU. Это полностью зависит от программиста (или компилятора), чтобы использовать правильные инструкции в правильном порядке в правильных байтах, чтобы получить желаемый результат. Например, реализовать переменные высокого уровня с типами.

Каждая инструкция asm делает то, что говорит на банке, не больше, не меньше.Раздел «Операция» в записи справочного руководства по набору инструкций описывает полное влияние, которое он оказывает на архитектурное состояние машины, включая флаги и возможные исключения.например, inc.Или более сложная инструкция с более интересным псевдокодом, который показывает, куда вносится каждый бит, BMI2 pdep r32a, r32b, r/m32 (и диаграммы).PDF-файл Intel, из которого они извлечены, содержит вступительный раздел, в котором объясняются любые обозначения, такие как CF ← Bit(BitBase, BitOffset); для bts (бит-тест и установка)


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

Ничто не может волшебным образом масштабировать индексы по ширине шрифта для вас.(Хотя AVX512 использует масштабированный disp8 в режимах адресации, поэтому 8-битное смещение может кодировать до -128 .. + 127 раз векторной ширины, а не столько байтов. В сборке на уровне источника вы все равно пишетесмещения байтов, и ассемблер может использовать, когда это возможно, более компактную кодировку машинного кода.)

Если вы хотите использовать inc al в младшем байте указателя для циклического перебора первых 256 байтов(выровненный) массив, это совершенно нормально.(И эффективно на процессорах, отличных от семейства P6, где вы получите остановку частичного регистра при чтении полного регистра.)


В некоторой степени верно, что x86 имеет встроенную поддержку многих типов.Большинство целочисленных инструкций содержат байты, слова, слова и qword размер операнда .И, конечно же, есть инструкции FP (float / double / long double), и даже в основном устаревшие данные BCD.

Если вы заботитесь о переполнении со знаком и без знака, вы смотрите на OFили CF соответственно.(Таким образом, целое число со знаком и без знака зависит от того, какие флаги вы смотрите после факта для большинства инструкций, потому что add / sub - это та же самая двоичная операция для unsigned и дополнения до 2).

Но умножение расширяется,делите, приходите в подписанной и неподписанной версиях.Один операнд imul против mul (и BMI2 mulx) выполняет умножение со знаком или без знака N x N => 2N-битное умножение.(Но часто вам не нужен результат с высокой половиной и вы можете просто использовать более эффективный imul r32, r/m32 (или другой размер операнда). Низкая половина умножения - это тот же двоичный операнд для интерпретации входных данных со знаком или без знака; только старшая половина отличается в зависимости от того, имеет ли MSB входов положительное или отрицательное значение-место.)


Не всегда хорошая идея использовать тот же размер операнда, что и тип данных C ++вы реализуете.например, 8-битный и 16-битный часто могут быть вычислены с 32-битным размером операнда, избегая проблем с частичным регистром.Для add / sub перенос переносится только из LSB в MSB, поэтому вы можете выполнять 32-битные операции и использовать только младшие 8 битов результата.(Если вам не нужно сдвиг вправо или что-то в этом роде.) И, конечно, размер 8-битного операнда для cmp может оказаться полезным, но это не запись каких-либо 8-битных регистров.


x86 типы / форматы данных включают в себя гораздо больше, чем просто целое число

  • двоичное целое число со знаком 2 и двоичное целое число без знака
  • IEEE float и double, с операндами памяти SSE и SSE2 и x87.
  • 16-разрядный float с половинной точностью (vcvtph2ps и наоборот):загружать / хранить только.Некоторые процессоры Intel имеют половинную точность multi / add в GPU , но ядра x86 IA могут конвертировать только для экономии пропускной способности памяти и использовать по крайней мере float для векторных математических инструкций FP.
  • 80-битная расширенная точность с x87
  • 80-битный BCD с x87 fbstp
  • упакованный и неупакованный BCD, поддерживаемый флагом AF (nibble-carry) и такие инструкции, как DAA (десятичное значение упакованного BCD, AL после добавления) и AAA (ASCII, корректирующее после добавления: для неупакованного BCD в AL, AH).не в 64-битном режиме
  • битовые карты с bt / bts / etc: bts [rdi], eax может выбрать бит вне dword на rdi.В отличие от назначения регистра, битовый индекс не маскируется с помощью &0x1f (https://www.felixcloutier.com/x86/bt). (вот почему bt/bts/etc mem,reg так много мопов, тогда как reg, reg и mem, немедленныенеплохо).

См. также Как читать нотацию Intel Opcode для получения списка всех нотаций, используемых в справочном руководстве по набору команд Intel. Например, r /m8 - это 8-битный регистр целых чисел или ячейка памяти. imm8 - это 8-битное значение (обычно расширяется до размера операнда, если он больше 8).

В руководстве используются m32fp для операндов памяти FP x87, против m32int для x87 fild / fistp (целочисленная загрузка / сохранение) и других инструкций x87 с целочисленным источникомкак fiadd.

Также такие вещи, как m16: 64 , дальний указатель в памяти (сегмент: смещение), например, в качестве операнда для косвенного дальнего jmp или дальний call. Конечно, было бы разумно сосчитать дальние указатели и "тип", который поддерживает x86. Есть инструкциикак lgs rdi, [rsi], который загружает gs:rdi из операнда 2 + 8 байтов, на который указывает rsi.(Конечно, чаще используется в 16-битном коде.)

m128 / xmm может быть не тем, что вы на самом деле называете «типом данных», хотя;никакие инструкции SIMD фактически не рассматривают операнд как 128-битное или 512-битное целое число.64-битные элементы являются самыми большими для всего, кроме случайных чисел.(Или чисто побитовые операции, но на самом деле это 128 отдельных операций И ​​параллельно, никакого взаимодействия между соседними битами вообще нет.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...