Quando si progetta un ISA, è buona norma decidere di consentire un'istruzione "pop" che non richiede un operando per ricevere il valore popping?

4

Molti ISA tra cui x86, x64, ARM, Itanium, hanno un'istruzione pop che richiede un operando che di solito è un registro (o, nel caso di ARM, un elenco di registri). In effetti, non riesco a pensare a un ISA in cima alla mia testa dove l'istruzione pop non richiede un operando (diverso dalle macchine stack per bytecode come JVM e CIL).

Ho notato che quando si esegue la programmazione degli assiemi, ci sono alcune volte che voglio eliminare il valore in cima allo stack senza doverlo conservare da nessuna parte. Normalmente questo può essere fatto modificando direttamente il puntatore stack o frame, ma, dal punto di vista della scrittura effettiva del codice assembly, sembra più economico avere semplicemente un opcode pop che non accetta alcun registro e semplicemente si sbarazza di quello che era al in cima allo stack.

Quando si progetta un ISA per una macchina di registro, è buona norma decidere di consentire un'istruzione pop che non richiede un operando per ricevere il valore di popping? Non riesco davvero a vedere alcuna rovina per questo.

    
posta Govind Parmar 16.05.2017 - 20:26
fonte

2 risposte

6

Questo dipenderà molto dal resto del tuo ISA, ma in generale l'aggiunta di cose non è gratuita.

L'aggiunta di un'istruzione senza% di pop riduce lo spazio opcode disponibile per altre istruzioni.

Certo, puoi creare uno schema barocco, ispirato a x86 per supportare istruzioni infinite, ma poi devi implementarlo e pagare i costi associati aggiuntivi.

Inoltre, si limita solo a% word-size pop s, può fare byte- pop s, half-word- pop s, e double-word- pop s come bene? Con un operando di registro, la dimensione del registro potrebbe indicare quanti bit a pop . Senza alcun operando, dovresti utilizzare più codici operativi per supportare% di diverse dimensioni in% co_de. Oppure supporta solo una dimensione predefinita e forza la manipolazione diretta del puntatore dello stack per qualsiasi altra cosa.

È un'altra istruzione che deve essere implementata.

Ciò significa più tempo e denaro spesi per progettare e testare l'implementazione. Nelle implementazioni hardware, probabilmente significa più circuiti, risultando in un prodotto più grande, più costoso, più caldo e più lento. Le implementazioni software richiedono più codice, con conseguente maggiore spazio per i bug e, eventualmente, richiedono una piattaforma di destinazione più potente (cioè più costosa).

Non c'è davvero molto vantaggio.

Come hai già sottolineato, è ridondante. pop o simili in pratica fa già la stessa cosa. Sì, forse è leggermente più conveniente della manipolazione manuale del puntatore dello stack nelle rare occasioni in cui è applicabile, ma sappiamo da decenni che il linguaggio assembly non è quello che si usa quando si desidera codificare con alta produttività. Se sei preoccupato per la produttività, porta un compilatore C al tuo ISA, o meglio ancora, qualcosa come D o Rust. Magari anche con alcuni linguaggi non di sistema di alto livello in esecuzione su di esso. Lascia l'assemblea nelle rare occasioni in cui è necessario, o per scopi didattici.

Se è gratuito, forse lascialo lì, invece di spendere altro lavoro per rimuoverlo.

MIPS ottiene qualcosa di simile gratuitamente. Oppure, se avesse un'istruzione sub $SP, 4 . Il registro pop di MIPS è hardcoded su 0 e cancella le scritture . Un'ipotetica istruzione $0 per MIPS richiederebbe comunque un operando, ma, se specifichi registro pop , otterrai la regolazione del puntatore dello stack senza salvare il valore eseguito. In questo modo non avresti bisogno di un extra $0 opcode per un caso edge particolare, e potrebbe semplicemente riutilizzare la stessa infrastruttura dataflow utilizzata da ogni altra istruzione che scrive su un registro.

Dedicare a zero un registro ha i suoi costi, in particolare riduce il numero di altri registri più versatili che possono essere resi disponibili e che è un registro di casi speciali. Il primo è significativo solo se il tuo ISA è già limitato sui registri disponibili. Quest'ultimo è compensato dal fatto che si tratta di un caso speciale estremamente semplice. A seconda dell'implementazione, potrebbe essere in effetti meno costoso di un registro generale (non c'è bisogno di logica di memoria, non c'è bisogno di alcuna connessione di input ...).

    
risposta data 16.05.2017 - 22:10
fonte
6

Personalmente non metterei queste istruzioni nel mio ISA.

Ecco perché: gli ISA dovrebbero essere economici; cioè devono fornire le loro funzionalità utilizzando il minor numero di istruzioni e il minor numero possibile di istruzioni. Ci sono già molti fattori che funzionano contro questa economia (retrocompatibilità, per esempio), quindi non dovresti buttare via questa economia in modo frivolo.

Se crei un'istruzione Pop che rende opzionale l'operando, hai ora creato una biforcazione: due istruzioni invece di una, sia per l'assemblatore che per il chip che eseguirà il Istruzioni. E questo lo hai fatto senza dubbio per un edge case, in modo che Pop non significhi più "pop".

Una volta che vai su questa strada, ti starai ponendo la domanda "Altre istruzioni dovrebbero avere anche operandi opzionali per coerenza? Cosa significa omettere l'operando per quelle istruzioni?" Perché dovresti farlo per l'istruzione Pop , ma non per altre istruzioni?

Salva i casi limite per le istruzioni ordinarie; richiedere all'utente di specificare un registro e semplicemente ignorare il valore restituito. Fai in modo che l'istruzione Pop funzioni allo stesso modo ogni volta che viene utilizzata.

    
risposta data 16.05.2017 - 21:00
fonte

Leggi altre domande sui tag