如果(var =='x'),文字存储在语句中的哪个位置?

时间:2010-09-15 06:01:04

标签: c++ c syntax

在这样的声明中说出

char var;

if( var == 'x');

我们是否在第一时间为'x'分配了任何内存?

如果是,那是什么(堆栈/数据)?

谢谢!

4 个答案:

答案 0 :(得分:24)

值'x'可以作为比较指令的一部分直接存储在代码段中,或者可以存储在代码段中以立即加载到寄存器中,或者存储在数据段中用于间接加载或相比。这取决于编译器。

答案 1 :(得分:7)

几乎所有针对功能强大的架构(16位及以上)的编译器都会将“x”的常量放在CPU指令中进行比较:

cmp  r0, #'x'

功能较少的体系结构倾向于将这些常量放在const内存中的表中,并将其加载以进行比较,或者直接从内存中进行比较。

答案 2 :(得分:4)

这是针对已安装的GCC副本所针对的任何体系结构回答此类问题的技术。使用-S标志获取合适代码片段的汇编源文件。或者,使用-Wa,-al获取一个程序集列表,显示汇编程序生成的实际字节数。例如,

int foo(char var) {
    if (var == 'x')
        return 42;
    return 17;
}

在我的Windows PC上编译gcc -c -Wa,-al以生成

GAS LISTING C:\DOCUME~1\Ross\LOCALS~1\Temp/ccyDNLLe.s                   page 1


   1                            .file   "q3715034.c"
   2                            .text
   3                            .p2align 4,,15
   4                    .globl _foo
   5                            .def    _foo;   .scl    2;      .type   32;
.endef
   6                    _foo:
   7 0000 55                    pushl   %ebp
   8 0001 31C0                  xorl    %eax, %eax
   9 0003 89E5                  movl    %esp, %ebp
  10 0005 807D0878              cmpb    $120, 8(%ebp)
  11 0009 5D                    popl    %ebp
  12 000a 0F94C0                sete    %al
  13 000d 48                    decl    %eax
  14 000e 83E0E7                andl    $-25, %eax
  15 0011 83C02A                addl    $42, %eax
  16 0014 C3909090              ret
  16      90909090
  16      90909090

线路7和9都是功能进入锅炉板的剩余部分,线路11和16是功能出口锅炉板。第8行将整个返回值寄存器清除为0.第10行是实际比较var == 'x',您可以在$120指令中看到幻数cmpb $120, 8(%ebp); 'x'的ASCII码为十六进制120或十六进制为0x78。您可以在偏移量为8的.text段中看到0x78,它将作为CMPB指令的一部分存储。身体的其余部分实现从我的样本片段中选择返回值,如果比较为真,则利用SETE指令使AL为1,否则为0。其余指令DECLANDLADDL会生成17或42,具体取决于整个AL寄存器中EAX寄存器的初始值。是整数函数的返回值存储在此体系结构中的地方。

答案 3 :(得分:1)

安东尼回答了事情的实际方面。让我从更语言理论的角度评论这个问题。 C ++标准将文字定义为 rvalue表达式,但字符串文字除外,它们是引用数组的 lvalue表达式。 C ++标准对对象的含义有一个清晰的概念。基本上,对象是具有地址对象类型(int,double,MyClass,...)。但标量类型的纯 rvalues (例如chardouble不被视为对象。它们只是值而不是指内存位置。这包括'x'3.14等文字。

编译器存储这些值的方式和位置超出了标准的范围。它甚至不必直接存储它们。例如,像x * 8这样的表达式可以转换为汇编代码,它将x的值向左移动三位。