Gar*_*ary 5 c gcc x86-64 gnu-assembler
尽管代码有效,但我对编译器决定混合使用相同类型的32位和64位参数感到困惑.具体来说,我有一个接收三个char指针的函数.查看汇编代码,三个中的两个作为64位指针(如预期的那样)传递,而第三个,一个局部常量,但仍然是字符串,作为32位指针传递.我没有看到我的函数如何知道第3个参数何时不是满载的64位指针.显然,只要较高的一方为0,这并不重要,但我不认为它会努力确保这一点.在这个例子中,任何东西都可能在RDX的高端.我错过了什么?顺便说一句,接收函数假定它是一个完整的64位指针,并在输入时包含此代码:
movq %rdx, -24(%rbp)
Run Code Online (Sandbox Code Playgroud)
这是有问题的代码:
.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?
}
Run Code Online (Sandbox Code Playgroud)
在寄存器中加载 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.
Run Code Online (Sandbox Code Playgroud)
(其他的是内核,类似于small,但在地址空间的上/负2GB和大没有限制)。
添加此作为答案,因为它包含原始问题的“谜题的一部分”:
只要编译器可以确定[例如通过指定满足此要求的内存模型].LC4 在第一个 4GB 内,它就可以做到这一点。%edx 将加载 LC4 地址的 32 位,并且高位设置为零,因此当调用 edc_function() 时,它可以使用 %rdx 的完整 64 位,并且只要地址在较低的4GB,就可以了。
| 归档时间: |
|
| 查看次数: |
1412 次 |
| 最近记录: |