Где хранится информация о знаке числа?

Рейтинг: 0Ответов: 1Опубликовано: 06.10.2014

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

Ответы

▲ 1

Если речь о целых числах, то в самом числе. Старший разряд является знаковым (1 - число отрицательное). См. Дополнительный код. -- @avp

Для целых чисел, на ассемблерном уровне обычно нет информации о том, это число со знаком или без. С битами, составляющими число, можно работать как будто это число со знаком, и как будто это беззнаковое число. Компилятор выбирает подходящие операции основываясь на своей информации. -- @VladD

Компилятор, когда компилирует код, знает, число знаковое или нет. И если он видит "нужно сложить два знаковых числа", то он просто вставит команду "взять данные по одному адресу, загрузить в регистр, взять по другому и записать в регистр и сложить то, что получилось по правилам складывания знаковых чисел". Поэтому ответ на Ваш вопрос - если такая информация нужна, компилятор ее для себя сохраняет (например, в виде отладочной информации или специфического набора команд). В общем случае, смотря в скомпилированный код, нельзя уверенно сказать, какая там была переменная. -- @KoVadim

На ассемблерном уровнем определить, являются ли числа знаковыми, можно по выполняемым над ними операциям. Например, если целые числа умножаются/делятся как знаковые (imul, idiv), то по идее они должны быть знаковыми. Точно так же, если используются условные операторы, учитывающие знак (js, jg, jge, jl, jle), значит результат последней операции - знаковое число, операнды по идее тоже. Сложение/вычитание для знаковых (считаем, что отрицательные числа хранятся в дополнительном коде) и беззнаковых чисел не различается. -- @insolor

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

Фрагмент файла c.c:

int a = 10, b = -10;
unsigned ua = a, ub = b;
if (a > b) printf ("%d > %d\n", a, b);
if (ua > ub) printf ("%u > %u\n", ua, ub);

Компиляция в ассемблерный код:

avp@avp-xub11:hashcode$ gcc -S c.c

Результат:

movl $10, 16(%esp) // a = 10
movl $-10, 20(%esp) // b = -10
movl 16(%esp), %eax
movl %eax, 24(%esp) // ua = a
movl 20(%esp), %eax
movl %eax, 28(%esp) // ub = b
movl 16(%esp), %eax
cmpl 20(%esp), %eax // if cmp(a, b)
jle .L2 // a <= b

movl 20(%esp), %eax
movl %eax, 8(%esp)
movl 16(%esp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
.L2: movl 24(%esp), %eax
cmpl 28(%esp), %eax // if cmp(ua, ub)
jbe .L3 // ua <= ub
....

Cм. Wikibooks: X86 Assembly/Control Flow -- @avp

Ответ сформирован из комментариев @avp, @VladD, @KoVadim, @insolor под вопросом.