gcc/clang 如何假设字符串常量的地址是 32 位的? [英] How can gcc/clang assume a string constant's address is 32-bit?

查看:18
本文介绍了gcc/clang 如何假设字符串常量的地址是 32 位的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我编译这个程序:

#include <stdio.h>

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

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

for x86-64, the asm output uses movl $.LC0, %edi / call puts. (See full asm output / compile options on godbolt.)

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

My question is: How can GCC know that the the string's address can fit in a 32bit immediate operand? Why doesn't it need to use movabs $.LC0, %rdi (i.e. a mov r64, imm64, not a zero or sign-extended imm32).

AFAIK,没有什么说加载器必须决定在任何特定地址加载数据部分.如果字符串存储在 1ULL << 之上的某个地址32 那么高位将被 movl 忽略.我在 clang 中遇到了类似的行为,所以我认为这不是 GCC 独有的.

AFAIK, there's nothing saying the loader has to decide to load the data section at any particular address. If the string is stored at some address above 1ULL << 32 then the higher bits will be ignored by the movl. I get similar behavior with clang, so I don't think this is unique to GCC.

我关心的原因是我想创建自己的数据段,该数据段位于内存中我选择的任意地址(可能超过 2^32).

The reason I care is I want to create my own data segment that lives in memory at any arbitrary address I choose (above 2^32 potentially).

推荐答案

在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=small

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

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=kernel 为内核代码模型生成代码.内核在负 2 GB 的地址空间中运行.这个模型必须用于 Linux 内核代码.

-mcmodel=kernel Generate code for the kernel code model. The kernel runs in the negative 2 GB of the address space. This model has to be used for Linux kernel code.

-mcmodel=中

为中型模型生成代码:程序链接在下层2 GB 的地址空间.小符号也放在那里.大小大于 -mlarge-data-threshold 的符号被放入大数据或 bss 部分,可以位于 2GB 以上.程序可以静态或动态链接.

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.

-mcmodel=大

为大型模型生成代码:此模型不做任何假设关于部分的地址和大小.

Generate code for the large model: This model makes no assumptions about addresses and sizes of sections.

<小时>

https://gcc.gnu.org/onlinedocs/gcc/AArch64-选项.html

3.18.1 AArch64 选项

-mcmodel=小

为微型代码模型生成代码.程序及其静态定义的符号之间必须在 1GB 以内.指针是 64 位.程序可以静态或动态链接.这模型没有完全实现,大多被视为小".

Generate code for the tiny code model. The program and its statically defined symbols must be within 1GB of each other. Pointers are 64 bits. Programs can be statically or dynamically linked. This model is not fully implemented and mostly treated as ‘small’.

-mcmodel=small

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

Generate code for the small code model. The program and its statically defined symbols must be within 4GB of each other. Pointers are 64 bits. Programs can be statically or dynamically linked. This is the default code model.

-mcmodel=大

为大型代码模型生成代码.这不对部分的地址和大小做出任何假设.指针是 64 位的.程式只能静态链接.

Generate code for the large code model. This makes no assumptions about addresses and sizes of sections. Pointers are 64 bits. Programs can be statically linked only.

这篇关于gcc/clang 如何假设字符串常量的地址是 32 位的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆