Question

en C, j'ai ce morceau de code:

int a;
a = 10 + 5 - 3

J'ai envie de demander:où est (10+5-3) stockés chez?(Autant que je sache, a est situé sur la pile, et (10+5-3)?Comment est-ce rvalue calculée?)

Était-ce utile?

La solution

Typiquement, la valeur r est "stocké" dans le programme lui-même.

En d'autres termes, le compilateur lui-même ( avant que le programme est exécuté jamais ) calcule 10 + 5 - valeur 3 (il peut le faire depuis puisqu'il est basé sur des valeurs immédiates constantes), et il émet le code assembleur pour stocker le résultat de ce calcul quel que soit l valeur pour l'assignement (dans ce cas, la variable nommé, que le compilateur sait probablement comme une adresse par rapport à une origine de segment de données de toutes sortes).

La valeur r, qui a une valeur de 12 est donc seulement trouvé à l'intérieur du binaire du programme, dans une instruction de montage que regarde comme

  mov <some dest, typically DS-relative>, $0C 

$ 0C est la "valeur r".

Si la valeur r est arrivé à être le résultat d'un calcul qui ne peut faire au moment de l'exécution, par exemple si le code c était sous-jacente: a = 17 * x; // x temps var run, la valeur r serait trop « stockée » (ou plutôt matérialisée) comme une série d'instructions dans le fichier binaire du programme. La différence avec le simple « mov dest, imm » ci-dessus est qu'il faudrait plusieurs instructions pour charger la variable x dans un accumulateur, il faut multiplier par 17 et stocker le résultat à l'adresse où une variable est. Il est possible que le compilateur peut « autoriser lui-même » ;-) à utiliser la pile pour une etc. résultat intermédiaire, mais ce serait
a) complètement dépendant compilateur
b) transiant
c) et généralement cela reviendrait uniquement partie de la valeur r
il est donc sûr de dire que la valeur r est un concept de compilation qui est encapsulé dans certaines parties du programme (et non les données), et ne sont pas stockées, mais nulle part dans le binaire du programme.

En réponse à paxdiablo: l'explication ci-dessus est en effet restrictif des possibilités parce que la norme c fait effectivement pas dicter quoi que ce soit de cette nature. Jamais le moins, la plupart une valeur r est finalement matérialisée, au moins en partie, par des instructions qui fixe les choses de telle sorte que la valeur appropriée, que ce soit calculée (au moment de l'exécution) ou s'adresse correctement immédiate.

Autres conseils

Constantes sont probablement simplifiées au moment de la compilation, de sorte que votre question littéralement posée ne peut pas aider. Mais quelque chose comme, disons, i - j + k qui n'a pas besoin d'être calculé lors de l'exécution de certaines variables, peuvent être « stockés » où le compilateur aime, en fonction de l'architecture du processeur: le compilateur essaiera généralement de faire de son mieux pour utiliser les registres, par exemple

 LOAD AX, i
 SUB AX, j
 ADD AX, k

pour calculer une telle expression « stocker » dans le registre accumulateur AX, avant de l'affecter à un certain emplacement de mémoire avec STORE AX, dest ou analogue. Je serais très surpris si un compilateur moderne sur une optimisation de l'architecture CPU même semi-décent (oui, x86 inclus -)! Nécessaire pour renverser les registres à la mémoire pour une expression assez simple

Cela dépend compilateur. En général, la valeur (12) sera calculé par le compilateur. Il est ensuite stocké dans le code, typiquement en tant que partie d'une charge / déplacement instruction de montage immédiat.

Où il stocke il est en fait totalement jusqu'à compilateur. La norme ne dicte pas ce comportement.

typique lieu peut être vu en compilant en fait le code et regardant la sortie de l'assembleur:

int main (int argc, char *argv[]) {
    int a;
    a = 10 + 5 - 3;
    return 0;
}

qui produit:

        .file   "qq.c"
        .def    ___main;
            .scl    2;
            .type   32;
        .endef
        .text
.globl _main
        .def    _main;
            .scl    2;
            .type   32;
        .endef
_main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        addl    $15, %eax
        addl    $15, %eax
        shrl    $4, %eax
        sall    $4, %eax
        movl    %eax, -8(%ebp)
        movl    -8(%ebp), %eax
        call    __alloca
        call    ___main
        movl    $12, -4(%ebp)         ;*****
        movl    $0, %eax
        leave
        ret

Le bit est marqué ;***** pertinent et vous pouvez voir que la valeur est créée par le compilateur et vient d'être inséré directement dans une instruction de type mov.

Notez que ce n'est que ce simple parce que l'expression est une valeur constante. Dès que vous introduisez les valeurs non constantes (comme les variables), le code devient un peu plus compliqué. C'est parce que vous devez regarder ces variables dans la mémoire (ou ils peuvent déjà être dans un registre), puis manipuler les valeurs à run-time , pas compilation .

En ce qui concerne la façon dont le compilateur calcule ce que la valeur devrait être, c'est de faire l'évaluation de l'expression et est une toute autre question: -)

  • Le résultat du calcul dans le RHS (-côté de droite) est calculée par le compilateur dans une étape que l'on appelle « propagation constant ».
  • Ensuite, il est stocké comme un opérande de l'instruction d'assemblage déplaçant la valeur dans a

Voici un démontage de MSVC:

  int a;
  a = 10 + 5 - 3;

0041338E  mov         dword ptr [a],0Ch 

Votre question est fondée sur une prémisse erronée.

La propriété de définir lvalue en C est ce qu 'il a une place dans le stockage, i.e. il est stockée . C'est ce qui différencie lvalue de rvalue . Rvalue est pas stockés partout. C'est ce qui en fait un rvalue. Si elle était stockée, il serait lvalue par définition.

Les termes "lvalue" et "rvalue" sont utilisés à traversent le monde des expressions.Qui est, (10+5-3) est une expression qui se trouve être une rvalue (parce que vous ne pouvez pas appliquer l'opérateur & pour elle -- en C++, les règles sont plus complexes).Au moment de l'exécution, il n'y a pas des expressions, des lvalues ou rvalues.En particulier, ils ne sont pas stockées n'importe où.

Vous vous demandez où la valeur 12 est stockée, mais la valeur 12 est ni une lvalue, ni une rvalue (par opposition à l'expression 12 ce qui serait une rvalue, mais 12 n'apparaît pas dans votre programme).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top