64位GCC混合32位和64位指针

时间:2013-01-27 18:24:43

标签: c gcc x86-64 gas

尽管代码有效,但我对编译器似乎混合相同类型的32位和64位参数的决定感到困惑。具体来说,我有一个接收三个char指针的函数。查看汇编代码,三个中的两个作为64位指针(如预期的那样)传递,而第三个,一个局部常量,但仍然是字符串,作为32位指针传递。我没有看到我的函数如何知道第3个参数何时不是满载的64位指针。显然,只要较高的一方为0,这并不重要,但我不认为它会努力确保这一点。在这个例子中,任何东西都可能在RDX的高端。我错过了什么?顺便说一句,接收函数假定它是一个完整的64位指针,并在条目中包含此代码:

     movq    %rdx, -24(%rbp)

这是有问题的代码:

.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?
    }

2 个答案:

答案 0 :(得分:4)

在寄存器中加载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的上/负2GB 地址空间大而没有限制。)

答案 1 :(得分:3)

将此作为答案添加,因为它包含原始问题的“部分难题”:

只要编译器可以确定[通过指定满足此条件的内存模型] .LC4在前4GB内,它就可以执行此操作。 %edx将加载32位的LC4地址,高位设置为零,因此当调用edc_function()时,它可以使用%rdx的完整64位,并且只要地址在较低的4GB,它会很好。