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

尽管代码有效,但我对编译器决定混合使用相同类型的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? } 

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

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

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