【发布时间】:2013-01-11 02:50:00
【问题描述】:
虽然代码有效,但编译器决定混合相同类型的 32 位和 64 位参数,这让我感到困惑。具体来说,我有一个接收三个字符指针的函数。查看汇编代码,三个中的两个作为 64 位指针传递(如预期的那样),而第三个是局部常量,但仍然是字符串,作为 32 位指针传递。我看不出我的函数如何知道第三个参数何时不是完全加载的 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 会加载 LC4 的 32 位地址,高位设置为零,所以调用 edc_function() 时,可以使用完整的 64 位,只要地址在低 4GB 以内,它会正常工作。但这对我来说确实很奇怪。
-
好的,我不知道 CPU 对负载进行了零扩展。哇!这让我睡得很好......
-
仅供参考,如果无法进行此优化,下一个最佳选择是
lea .LC4(%rip), %rdx。不是具有 64 位绝对地址的 10 字节mov。 How to load address of function or label into register in GNU Assembler
标签: c gcc x86-64 gnu-assembler