【发布时间】:2013-07-11 13:24:42
【问题描述】:
在 c 项目中使用(链接)时,汇编代码是否会忽略在 C 数据类型和函数之前声明的 const 关键字?并且可以修改数据类型的内容吗??
【问题讨论】:
标签: c assembly compiler-construction constants
在 c 项目中使用(链接)时,汇编代码是否会忽略在 C 数据类型和函数之前声明的 const 关键字?并且可以修改数据类型的内容吗??
【问题讨论】:
标签: c assembly compiler-construction constants
在 c 项目中使用(链接)汇编代码时是否忽略 const 在 C 数据类型和函数之前声明的关键字??
是的,const 关键字完全被汇编代码忽略了。
它可以修改数据类型的内容吗??
如果编译器能够将const 位置放在只读段中,则试图修改它的汇编代码将导致段错误。否则,将导致不可预知的行为,因为编译器可能已经优化了部分代码,但没有优化其他部分,假设 const 位置未被修改。
【讨论】:
它可以修改数据类型的内容吗??
也许,也许不是。如果原始对象声明为const,那么编译器可能会将其发送到只读数据段中,该数据段将在运行时加载到只读内存页面中。写入该页面,即使是从程序集写入,也会触发运行时异常(访问冲突或分段错误)。
您不会收到编译时错误,但在运行时您的程序可能会崩溃或行为异常。
【讨论】:
Assembly 使用您在 C 中声明的数据类型来更好地优化它在内存中存储信息的方式。一切都在一天结束时以二进制形式编写(int、long、char 等),因此一旦进入低级代码就没有数据类型。
【讨论】:
这个问题不是很精确。 “忽略”是什么意思?
汇编语言没有与 C 语言相同的 const 概念。所以,汇编不能忽略它。它根本不知道。
然而,C 编译器为 C 程序生成的汇编代码可能很容易受到 C 程序中 const 关键字位置的影响。
换句话说,汇编代码可能会受到const 关键字的影响。但是一旦构建了汇编代码,const 关键字就不再需要了。
说汇编程序可以修改声明为const 的东西也不完全正确。如果您将变量声明为const,则在某些情况下,编译器可能足够聪明,可以完全消除该变量,并将其替换为该变量的立即值。这意味着const 变量可能会从最终代码中完全消失,而没有任何东西可供汇编代码“修改”。
【讨论】:
GCC 将标记为 const 的全局变量放在名为 .rodata 的单独部分中。 .rodata 也用于存储字符串常量。
由于 .rodata 部分的内容不会被修改, 它们可以放在 Flash 中。必须修改链接描述文件以适应这种情况。
#include <stdio.h>
const int a = 10 ;
int main ( void ) {
return a ;
}
.section .rodata
.align 4
a:
.long 10
gcc 与 00 :
movl a(%rip), %eax // variabile constant
addq $32, %rsp
popq %rbp
gcc 与 O3 :
movl $10, %eax // numeric constant
addq $40, %rsp
ret
【讨论】: