int main() {
int64_t di = -10;
uint64_t ui = UINT64_MAX - 9;
return 0;
}
When I disassemble main
it gives me this output:
Dump of assembler code for function main:
0x0000000000001119 <+0>: push rbp
0x000000000000111a <+1>: mov rbp,rsp
0x000000000000111d <+4>: mov QWORD PTR [rbp-0x10],0xfffffffffffffff6
0x0000000000001125 <+12>: mov QWORD PTR [rbp-0x8],0xfffffffffffffff6
0x000000000000112d <+20>: mov eax,0x0
0x0000000000001132 <+25>: pop rbp
0x0000000000001133 <+26>: ret
Both of them are 0xfffffffffffffff6
I understand one bit in signed variable is to determine its sign but how it knows it is signed or unsigned variable. Maybe it sets some flag idk
In this processor architecture, and commonly in today’s processors, there is no indication of whether the bits in a register are a signed integer, an unsigned integer, an address, or something else. There is no type information associated with the register; it is simply a sequence of bits.
When you write additional C code to use the data, such as a test if (di < 3) …
, the compiler will generate instructions that depend on the type of data. For example, there is a compare instruction that produces several bits describing the relationship between two numbers, and there are branch instructions that use those bits to perform branches such as “branch if the first number is less than the second number using a signed interpretation.” Thus, the type information is built into the assembly instructions that use the data.