Should there be pointer mappings or unsigned in 64-bit x86?

When writing an x86 user-space assembly and comparing two pointer values, you should use signed conditions, such as jland jgeor unsigned conditions, such as jband jae?

Intuitively, I believe that pointers as unsigned work from 0 to 2 ^ 64-1 in the case of a 64-bit process, and I think this model is accurate for 32-bit code. I think most people think of them.

In 64-bit code, however, I don’t think you can really cross the signed gap in 0x7FFFFFFFFFFFFFFF, and many interesting areas of memory tend to group near the signed 0 (often for code and static data, and sometimes for heaps depending on the implementation) and next to the maximum address in the lower half of the canonical address space (something like 0x00007fffffffffffmost systems today) for stack and heap locations on some implementations 1 .

So, I'm not sure which way they should be taken: the signed has the advantage that it is safe around 0, since there is no gap, and unsigned has the same advantage of about 2 ^ 63, since there is no gap. However, in practice, you do not see the address somewhere close to 2 ^ 63, since the virtual address space of the current commercial equipment is limited to less than 50 bits. Does this indicate a signature?


1 ... and sometimes the heap and other displayed areas are neither close to the bottom nor to the top of the address space.

+2
source share
1 answer

It depends on what you want to know about the two pointers!

ptrA < ptrB - C , . ptrA < ptrB - sizeA , , SIMD current < endp - loop_stride. .

, ptrB - C , ( ). ( , , C ++ UB , unsigned wrapping ​​ .) , " " C . , .

, "" , , / 64- . unsigned, , , , x86-64.


, unsigned ptrA < ptrB - C "", ptrB - C wraps (unsigned wraparound). , 0, C.

64kiB (, Linux, sysctl vm.mmap_min_addr = 65536 4096. =0 WINE). , , , , NULL deref ( ).

, loop_stride . sizeA ptrA + sizeA < ptrB, LEA copy + subtract. ptrA+sizeA , , 2 ^ 64-1 ( wraparound, "" , unsigned.)


, ? ptrB - C . - (, vDSO Linux), : , " " , " ". , ptrB - C .

( asm , C, UB, C sub lea/cmp/jl.)

0x7FFF... 0x8000.... . x86-64 ( , - 48 ) . . 64- 4 (48 ) ( 52 )?.

, x86-64 . , , 48- 64 , [63:48] 47 ( 0).

+----------+
| 2^64-1   |   0xffffffffffffffff
| ...      |                       high half of canonical address range
| 2^64-2^47|   0xffff800000000000
+----------+
|          |
| unusable |   Not to scale: this is 2^15 times larger than the top/bottom ranges.
|          |
+----------+
| 2^47-1   |   0x00007fffffffffff
| ...      |                       low half of canonical range
| 0        |   0x0000000000000000
+----------+

Intel 5- 57- (.. 9- ), . .. - 2 ^ 63 - 2 ^ 57 .

. x86-64 Linux, ( "" ) , ( ) . , Linux vDSO/vsyscall . ( , , ffffffffff600000-ffffffffff601000 [vsyscall] 64- , vDSO , 0x00007fff.... 32- , 4GiB , vDSO - , mmap(MAP_FIXED) . , , C ? )

- vsyscall, . ( , - , .)

, , /, , , /if x86-64 64- , . , , , , , .

, 32- , 64- 4GiB . ( 32- / 3: 1). . 32- . ( ILP32 x32 ABI: 32- .)


:

32- , , jge , jae 64- . ( setcc/cmovcc ). , perf diff , - adc sbb cmov setcc.

Sandybridge-family /cmp ( sub, add , ) ( JCC, ). CMP/ JCC.

Core2 -fuse cmp , , Core2 64- . ( - test - 32- , BTW.)

Nehalem - test cmp ( 64- ).

: microarch pdf Agner Fog.

+4

All Articles