Почему сборка x86 позволяет помещать отрицательное целое число в переменную без знака? - PullRequest
0 голосов
/ 21 февраля 2019

Когда я запускаю это в Visual Studios, это позволяет мне успешно построить проект.

.data
   val1 DWORD -1

Поскольку DWORD не подписан, не должен ли ввод отрицательного значения привести к ошибке?

1 Ответ

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

Все это просто набор битов.Например (синтаксис NASM - dd просто означает «слово данных»), эти значения имеют одинаковую комбинацию битов:

    dd '4321'               ;Interpreted as ASCII characters
    dd 0x31323334           ;Interpreted as an unsigned hexadecimal number
    dd 825373492            ;Interpreted as a signed decimal number

.. и этот код также является точно такой же комбинацией битов,просто интерпретируется как (32-битные) инструкции:

    xor al,0x33
    xor dh,[ecx]

.. и этот код по-прежнему является точно такой же комбинацией битов, интерпретируемых как 16-битные инструкции:

    xor al,0x33
    xor dh,[bx+di]

..и если хотите, вы можете интерпретировать тот же шаблон битов, что и 32-разрядное число с плавающей запятой (2.59315147e-9), или как число с фиксированной запятой (например, 12594.20001220703125), или как двоично-десятичное десятичное число (4321),или как цвет («темно-серый с альфа» для RGBA), или как часть звука, или ...

То, как создается структура битов, не имеет большого значения.Важно то, как используется структура битов.Например, если вы делаете add dword eax,[foo], а затем jb .somewhere, тогда инструкция ветвления, вероятно, указывает, что это было добавление без знака, но если вы делаете add dword eax,[foo], тогда jl .somewhere, тогда инструкция ветвления, вероятно, указывает, что это добавление со знаком (даже еслиинструкция сложения одинакова как для подписанного, так и для неподписанного);но если вы сделаете fld dword [foo], тогда оно будет использоваться как 32-битное значение с плавающей запятой или ...

Сейчас;если вы посмотрите, как работает комплимент 2, вы заметите, что (для 8-битных целых чисел, потому что мне лень набирать 32-битные), есть два диапазона:

00000000b to 01111111b = 0 to +127, regardless of signed or unsigned
10000000b to 11111111b = +128 to +255 if unsigned, or -128 to -1 if signed

Другими словами, для32-разрядные целые числа, 0xFFFFFFFF (без знака) - это тот же шаблон битов, что и -1 (со знаком);и поскольку структура битов одинакова, не имеет значения, какую версию вы используете (кроме читабельности кода).

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