Considérons la fonction suivante:
unsigned sum_evens (unsigned number) {
number &= ~1; // ~1 = 0xfffffffe (32-bit CPU)
unsigned result = 0;
while (number) {
result += number;
number -= 2;
}
return result;
}
Maintenant, nous allons jouer le compilateur jeu et essayer de le compiler à la main. Je vais supposer que vous êtes en utilisant x86 parce que c'est ce que la plupart des ordinateurs de bureau utilisation. (x86 est le jeu d'instructions Intel Processeurs compatibles.)
Nous allons passer par un simple (unoptimized) version de comment cette routine pourrait ressembler lors de la compilation:
sum_evens:
and edi, 0xfffffffe ;edi is where the first argument goes
xor eax, eax ;set register eax to 0
cmp edi, 0 ;compare number to 0
jz .done ;if edi = 0, jump to .done
.loop
add eax, edi ;eax = eax + edi
sub edi, 2 ;edi = edi - 2
jnz .loop ;if edi != 0, go back to .loop
.done
ret ;return (value in eax is returned to caller)
Maintenant, comme vous pouvez le voir, l'une des constantes dans le code (0
, 2
, 1
) en fait dans le cadre des instructions du PROCESSEUR! En fait, 1
ne pas s'afficher du tout; le compilateur (dans ce cas, il suffit de m') déjà calcule ~1
et utilise le résultat dans le code.
Alors que vous pouvez prendre l'adresse d'un PROCESSEUR d'instruction, il fait souvent pas de sens de prendre l'adresse d'une partie de celui-ci (en x86 parfois, vous pouvez, mais dans de nombreux autres Processeurs que vous ne peut tout simplement pas faire cela à tous), et les adresses de code sont fondamentalement différents de données d'adresses (qui est pourquoi vous ne pouvez pas traiter un pointeur de fonction (une adresse de code) en tant que régulier pointeur (une adresse de données)). Dans certaines architectures des processeurs, du code des adresses et des données d'adresses sont totalement incompatibles (bien que ce n'est pas le cas de x86 de la manière la plus moderne des Systèmes d'exploitation de l'utiliser).
Notez qu' while (number)
est équivalent à while (number != 0)
. Qu' 0
n'apparaît pas dans le code compilé à tous! Il est implicite par l' jnz
instruction (saut si pas de zéro). C'est une autre raison pourquoi vous ne pouvez pas prendre l'adresse de celui - 0
- il n'en a pas, c'est littéralement de nulle part.
J'espère que cela le rend plus clair pour vous.