当前位置: 首页 > 面试题库 >

gcc / clang如何假设字符串常量的地址是32位?

耿弘阔
2023-03-14
问题内容

如果我编译此程序:

#include <stdio.h>

int main(int argc, char** argv) {
    printf("hello world!\n");
    return 0;
}

对于x86-64,asm输出使用movl $.LC0, %edi/ call puts。(请参阅Godbolt上的完整asm输出/编译选项。)

我的问题是:GCC如何知道字符串的地址可以放入32位立即数中?为什么不需要使用它movabs $.LC0, %rdi(即mov r64, imm64,而不是零或符号扩展的imm32)。

AFAIK,没有什么说加载程序必须决定将数据段加载到任何特定地址的。如果该字符串存储在上方的某个地址,1ULL << 32那么movl将忽略较高的位。我在clang中得到类似的行为,所以我认为这并不是GCC独有的。

我关心的原因是我想创建自己的数据段,该段存储在内存中的任意位置(可能大于2 ^ 32)。


问题答案:

在GCC手册中:

https://gcc.gnu.org/onlinedocs/gcc-4.5.3/gcc/i386-and-x86_002d64-Options.html

3.17.15 Intel 386和AMD x86-64选项

-mcmodel =小

为小型代码模型生成代码:程序及其符号必须在地址空间的低2 GB中链接。指针是64位。程序可以静态或动态链接。 这是 默认的代码模型。

-mcmodel = kernel为内核代码模型生成代码。内核在负2 GB的地址空间中运行。该模型必须用于Linux内核代码。

-mcmodel =中

生成用于中型模型的代码:程序链接在地址空间的低2 GB中。小符号也放置在此处。大小大于-mlarge-data-
threshold的符号将放入大数据或bss节中,并且可以位于2GB以上。程序可以静态或动态链接。

-mcmodel =大

生成大型模型的代码:该模型不对节的地址和大小做任何假设。

https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html

3.18.1 AArch64选项

-mcmodel =小

为小代码模型生成代码。该程序及其静态定义的符号之间的距离必须在1GB之内。指针是64位。程序可以静态或动态链接。该模型尚未完全实施,通常被视为“小型”模型。

-mcmodel =小

为小代码模型生成代码。该程序及其静态定义的符号之间的距离必须在4GB之内。指针是64位。程序可以静态或动态链接。 这是 默认的代码模型

-mcmodel =大

为大型代码模型生成代码。这不假定节的地址和大小。指针是64位。程序只能静态链接。



 类似资料:
  • 首先,考虑这个例子: 我期望什么:因为“123”是一个< code>const char*,我期望这些字符串的地址(就像其中一个答案所说的)被比较。 …因为和将只比较这些字符串的基址。不是字符串本身的内容。 但输出仍然是。好吧,我们实际上不知道如何比较两个prvalue对象的地址(或者至少我不明白会怎么做)。所以让我们将这些字符串声明为变量,看看会发生什么: 输出仍然是 。所以字符串不会衰减吗?或

  • 本文向大家介绍字符型常量和字符串常量的区别相关面试题,主要包含被问及字符型常量和字符串常量的区别时的应答技巧和注意事项,需要的朋友参考一下 形式上: 字符常量是单引号引起的一个字符; 字符串常量是双引号引起的若干个字符 含义上: 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置) 占内存大小:字符常量只占2个字节; 字符串常量占

  • 3.8 32位地址的寻址方式 在32位微机系统中,除了支持前面的七种寻址方式外,又提供了一种更灵活、方便,但也更复杂的内存寻址方式,从而使内存地址的寻址范围得到了进一步扩大。 在用16位寄存器来访问存储单元时,只能使用基地址寄存器(BX和BP)和变址寄存器(SI和DI)来作为地址偏移量的一部分,但在用32位寄存器寻址时,不存在上述限制,所有32位寄存器(EAX、EBX、ECX、EDX、ESI、ED

  • 如这些问题中所述:问题1 在以下情况下,JVM将创建一个新的字符串对象,而不是使用字符串池中的现有对象: 然而,在阅读了下面两个类似的陈述之后,我有一个疑问。 从SCJP准备书: 当编译器遇到字符串文字时,它会检查池中是否已经存在相同的字符串。如果找到匹配项,对新文本的引用将指向现有的String,并且不会创建新的String文本对象。 来自JavaRanch: 在本例中,由于关键字“new”,我