Come funziona il confronto dei numeri interi internamente?


18

Ad esempio, quando si confrontano due numeri interi come segue in un linguaggio di tipo C:

if (3 > 2) {
    // do something
}

In che modo viene giudicato se 3 è maggiore di 2 (vero) o no (falso) internamente?


19
La risposta attuale va bene nel caso in cui il confronto riguardi l'espressione variabile, ma manca una dichiarazione di non responsabilità che molti compilatori moderni guarderanno il tuo pezzo di codice, rileveranno che l'espressione sarà sempre vera (a causa dei valori letterali) e ignorerai il iftutto , andando direttamente alla codifica do something.
SJuan76,

3
Possibile duplicato di Come funzionano i computer?

3
@Snowman Non sono d'accordo. Qualsiasi indagine di programmazione "come funziona" può essere ridotta a quella domanda, ma ciò non li rende duplicati.
user1643723

1
@ user1643723 Lo fa quando la funzione in questione è un codice operativo specifico.
Chrylis -on strike -

1
@ user1643723 La domanda è: in che modo un computer esegue un'operazione di base e la risposta principale discute porte logiche e tabelle logiche. Due argomenti che sono ampiamente trattati nella risposta principale dell'obiettivo dupe, che risponde anche alla tua domanda.

Risposte:


61

Fino in fondo alla tana del coniglio, eh? OK, ci proverò.

Passaggio 1. Da C al linguaggio macchina

Il compilatore C trasforma il tuo confronto in codici operativi memorizzati nel linguaggio macchina . Il linguaggio macchina è una serie di numeri che la CPU interpreta come istruzioni. In questo caso ci sarebbero due codici operativi: "sottrai con carry" e "salta se carry". In altre parole, 2 viene sottratto da 3 in un'istruzione e l'istruzione successiva controlla se è traboccata. Questi sarebbero preceduti da due istruzioni per caricare i numeri 2 e 3 in posizioni dove possono essere confrontati.

MOV AX, 3    ; Store 3 in register AX
MOV BX, 2    ; Store 2 in register BX
SUB AX, BX   ; Subtract BX from AX
JC  Label    ; If the previous operation overflowed, continue processing at memory location "Label"

Ognuno di questi ha una rappresentazione binaria; ad esempio, il codice per SUBè 2Dhex o 00101101in binario.

Passaggio 2. Codici operativi per ALU

Opcode aritmetiche piace ADD, SUB, MUL, e DIVeseguire matematica intero base usando un ALU o logico-aritmetica Unità incorporata nella CPU. I numeri sono memorizzati nei registri da alcuni codici operativi; altri codici operativi indicano al chip di chiamare l'ALU per fare matematica su tutto ciò che è memorizzato nei registri in quel momento.

Nota: a questo punto siamo ben al di là di tutto ciò di cui qualsiasi ingegnere software si preoccuperebbe se lavorasse con un 3GL come C.

Passaggio 3. L'ALU, il mezzo-sommatore e il sommatore completo

Sapevi che tutte le operazioni matematiche che conosci possono essere ridotte a una serie di operazioni NOR ? Ed è esattamente così che funziona l'ALU.

L'ALU sa solo come lavorare con i numeri binari e può eseguire solo operazioni logiche come OR, NOT, AND e XOR. L'implementazione dell'aggiunta e sottrazione binaria viene eseguita con una serie di operazioni logiche disposte in un certo modo, in un sottosistema noto come sommatore . Questi sottosistemi sono composti da una rete di "semi-adduttori" che operano su due bit e determinano la loro somma a singolo bit e un flag carry a singolo bit. Concatenandoli insieme, l'ALU può eseguire operazioni su numeri con 8, 16, 32 bit ecc.

Half-Adder

Che dire della sottrazione? La sottrazione è solo un'altra forma di aggiunta:

A - B = A + (-B)

L'ALU calcola -Bprendendo il complemento a due di B. Una volta convertito in negativo, l'invio del valore al sommatore comporterà un'operazione di sottrazione.

Passaggio 4: passaggio finale: transistor su chip

Le operazioni degli additivi vengono implementate usando una combinazione di componenti elettrici che interagiscono per creare "gate logici", come quelli che si trovano nella logica transitor-transistor o TTL o in CMOS . Fai clic qui per alcuni esempi per vedere come sono collegati.

Su un chip, ovviamente, questi "circuiti" sono implementati in milioni di piccoli pezzi di materiale conduttivo e non conduttivo, ma il principio è lo stesso di se fossero componenti a grandezza naturale su una breadboard. Guarda questo video che mostra tutti i transistor su un microchip attraverso l'obiettivo di un microscopio elettronico.

Alcune note aggiuntive:

  1. Il codice che hai scritto verrebbe effettivamente precompilato dal compilatore e non eseguito in fase di esecuzione, poiché è composto esclusivamente da costanti.

  2. Alcuni compilatori non vengono compilati in codice macchina ma introducono ancora un altro livello, come bytecode Java o linguaggio intermedio .NET. Ma alla fine tutto viene eseguito tramite linguaggio macchina.

  3. Alcune operazioni matematiche non sono effettivamente calcolate; sono osservati in enormi tabelle su un'unità di coprocessing aritmetica o contengono una combinazione di ricerca e calcolo o interpolazione. Un esempio potrebbe essere la funzione per calcolare una radice quadrata . Le moderne CPU per PC dispongono ciascuna di un'unità di coprocessing in virgola mobile integrata in ciascun core della CPU.


3
FWIW, fare riferimento al TTL può essere fonte di confusione poiché praticamente nessun processore moderno utilizza la segnalazione TTL, la maggior parte utilizza FET CMOS e tensioni inferiori invece di BJT 5v.
whatsisname

2
CMOS sarebbe sicuramente un riferimento migliore rispetto a TTL, come suggerisce @whatsisname, perché non solo è più preciso rispetto a ciò che accade nei processori moderni, è anche concettualmente molto più semplice.
Jules il

3
@JackAidley è questo che significa questa parte: "In altre parole, 2 viene sottratto da 3 in un'istruzione e l'istruzione successiva controlla se è traboccata."
KutuluMike,

1
Nitpicking: suppongo che CMPverrebbe usato, non SUB- ma poi di nuovo è più o meno un " SUBdove il risultato viene ignorato e vengono posizionate solo le bandiere"
Hagen von Eitzen,

5
Le tue definizioni di mezzo e full-adder sono errate. Un mezzo sommatore accetta due input da 1 bit e restituisce la somma e il carry. Un sommatore completo accetta un input di carry-in aggiuntivo ma è comunque solo un singolo bit. Esistono molti modi per creare un sommatore N-bit, il più semplice è un sommatore con ripple che è solo una catena di N additivi completi. In pratica per Ns più grandi questo ha un ritardo piuttosto brutto, quindi i design più complessi vengono utilizzati nei moderni progetti di CPU.
Voo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.