Я узнал о 2's Complement
и неподписанных и подписанных int. Поэтому я решил проверить свои знания, насколько я знаю, что отрицательное число хранится в 2's complement
так, чтобы сложение и вычитание не имели бы другого алгоритма и схемы были бы простыми.Как в сборке присваивается отрицательное число неподписанной работе int?
Теперь, если я пишу
int main()
{
int a = -1 ;
unsigned int b = - 1 ;
printf("%d %u \n %d %u" , a ,a , b, b);
}
Выходной Comes To Be -1 4294967295 -1 4294967295
. Теперь я посмотрел на схему битов и различные вещи, а затем понял, что -1
в дополнении 2: 11111111 11111111 11111111 11111111
, поэтому, когда я интерпретирую его с использованием% d, он дает -1
, но когда я интерпретирую с использованием %u
, он обрабатывает его как положительное число и поэтому он дает 4294967295
. Я проверил, скопище код
.LC0:
.string "%d %u \n %d %u"
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], -1
mov DWORD PTR [rbp-8], -1
mov esi, DWORD PTR [rbp-8]
mov ecx, DWORD PTR [rbp-8]
mov edx, DWORD PTR [rbp-4]
mov eax, DWORD PTR [rbp-4]
mov r8d, esi
mov esi, eax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0
leave
ret
Теперь здесь -1
перемещается в регистр оба раза в беззнаковое и знаковое. То, что я хочу знать, если реинтерпретация только имеет значение, то почему у нас есть два типа: unsigned
и signed
, это printf
формат строки %d
и %u
, что имеет значение?
Дальше, что действительно происходит, когда я назначаю отрицательное число целому числу без знака (я узнал, что инициализатор преобразует это значение из int
в unsigned int
.), Но в коде сборки я не видел такой вещи. Так что же происходит на самом деле?
И как машина знает, когда она должна делать 2's complement
, а когда нет, она видит отрицательный знак и выполняет 2's complement
?
Я прочитал почти каждый вопрос и ответ, вы можете подумать, что этот вопрос дублируется, но я не мог найти удовлетворительного решения.
* «Как машина знает, когда он должен сделать 2 в дополнение, а когда нет» * - Я не понимаю, это - все сводится к тому, двоичная в программировании. Машинные инструкции не заботятся о 'signed' или' unsigned', это конструкции более высокого уровня. – UnholySheep
@UnholySheep Что я имею в виду, когда я пишу подписанный int a = -1, он хранится как дополнение к 2, поэтому каждое отрицательное число не имеет значения, где оно хранится таким образом или нет? –
Для языка C отрицательное число может быть одним из трех представлений, поэтому необязательно дополнение 2. Также формат printf должен соответствовать вводу, или ваша программа плохо сформирована. Текущий стандарт C поддерживает дополнение 2 таким образом, что преобразование типов подписей в и из неподписанных типов не изменяет представление битов на компьютере с дополнительным дополнением 2. Машины действительно не знают о значении переменной, когда она находится в регистре. Компилятор знает, поэтому программа знает, и этого достаточно. – user3528438