GCC 64-bit mixing 32-bit and 64-bit pointers

Although the code works, I'm confusing the compiler's solution, seemingly mixing 32 and 64 bit parameters of the same type. In particular, I have a function that gets three char pointers. Considering the assembly code, two of them are passed as 64-bit pointers (as expected), while the third is a local constant, but the character string, however, is passed as a 32-bit pointer. I do not see how my function could ever know when the third parameter is not a fully loaded 64-bit pointer. Obviously, this does not matter as long as the highest side is 0, but I do not see that she was making efforts to ensure this. In this example, everything can be on the high side of RDX. What am I missing? BTW, the receive function takes over the full 64-bit pointer and includes this code when writing:

     movq    %rdx, -24(%rbp)

This is the code in question:

.LC4
    .string "My Silly String"

    .text
    .globl funky_funk
    .type  funky_funk, @function
    funky_funk:
        pushq     %rbp
            movq      %rsp, %rbp
            pushq     %rbx
            subq      $16, %rsp
            movq      %rdi, -16(%rbp)          ;char *dst 64-bit
            movl      %esi, -20(%rbp)          ;int len, 32 bits OK

            movl      $.LC4, %edx              ;<<<<---- why is it not RDX?

            movl      -20(%rbp), %ecx          ;int len 32-bits OK
            movq      -16(%rbp), %rbx          ;char *dst 64-bit
            movq      -16(%rbp), %rax          ;char *dst 64-bit
            movq      %rbx, %rsi               ;char *dst 64-bit
            movq      %rax, %rdi               ;char *dst 64-bit
            call      edc_function


    void funky_funk(char *dst, int len)
    {                                             //how will function know when 
         edc_function(dst, dst, STRING_LC4, len); //a str passed in 3rd parm
    }                                             //is 32-bit ptr vs 64-bit ptr?

    void edc_function(char *dst, char *src, char *key, int len)
    {
         //so, is key a 32-bit ptr? or is key a 64-bit ptr?
    }
+5
source share
2 answers

Adding this as an answer as it contains the “puzzle piece” for the original question:

While the compiler can determine [by, for example, determining a memory model that satisfies this) that .LC4 is within the first 4 GB, it can do this. % edx will be loaded with 32 bits of the LC4 address, and the upper bits will be set to zero, so when edc_function () is called, it can use the full 64-bit% rdx and as long as the address is inside less than 4 GB, it will be work fine.

+3
source

32- . , , , 32- .

GCC x64, . GCC:

`-mcmodel=small'
     Generate code for the small code model: the program and its
     symbols must be linked in the lower 2 GB of the address space.
     Pointers are 64 bits.  Programs can be statically or dynamically
     linked.  This is the default code model.
`-mcmodel=medium'
     Generate code for the medium model: The program is linked in the
     lower 2 GB of the address space.  Small symbols are also placed
     there.  Symbols with sizes larger than `-mlarge-data-threshold'
     are put into large data or bss sections and can be located above
     2GB.  Programs can be statically or dynamically linked.

( - , , / 2GB ).

+4

All Articles