Perché questo codice non è stato scritto in un modo molto più semplice?


8

Mi sono imbattuto in una domanda mentre lavoravo sul linguaggio assembly. Ecco la domanda:

Supponiamo che il bit P2.2 sia usato per controllare una luce esterna e il bit P2.5 una luce all'interno di un edificio. Mostra come accendere la luce esterna e spegnere quella interna.

Soluzione fornita:

SETB C            ; CY = 1
ORL C, P2.2       ; CY = P2.2 ORed w/ CY
MOV P2.2, C       ; turn it on if not on
CLR C             ; CY = 0
ANL C, P2.5       ; CY = P2.5 ANDed w/P2.5
MOV P2.5,C        ; turn it off if not off

Ho pensato che avrebbe fatto lo stesso lavoro per codificare:

SETB P2.2
CLR P2.5

Cosa c'è che non va?


2
Forse solo didattica, che mostra come usare il bit di trasporto come accumulatore. Non c'è alcun vantaggio che posso vedere in questo caso particolare. Questo sembra 8051 codice assembly.
Spehro Pefhany,

@SpehroPefhany Ma per quanto ne so, il registro Acc è usato in alcuni casi poiché è l'unico registro che supporta alcune istruzioni come DA, RR, RL ecc. Non penso che questo sia il caso qui. Ho sbagliato?
İlker Demirel,

Il carry è un po 'largo. È possibile utilizzarlo come accumulatore in alcuni casi come la valutazione della logica ladder.
Spehro Pefhany,

Risposte:


11

Hai ragione in quanto sembra che il codice che mostri sia sciocco. Forse qualunque macchina su cui gira non può eseguire operazioni immediate per impostare bit su porte I / O, ed è per questo che qualcosa come SETB P2.2 non è possibile.

Impostando ancora il bit CY su 1, quindi OR inserire qualsiasi cosa in esso è semplicemente stupido. Lo stesso vale per impostare il bit CY su 0, quindi ANDing qualcosa al suo interno. Chiaramente il bit CY può essere copiato direttamente in un bit pin I / O, poiché il codice lo fa. Al massimo dovrebbero essere 4 istruzioni, certamente non 6.


Quindi posso dire che se un bit è indirizzabile a bit, mi è permesso usare istruzioni bit su qualunque bit, giusto?
İlker Demirel,

1
@ İlk: non necessariamente. Potrebbero esserci delle restrizioni come le istruzioni dei bit funzionano solo su alcuni registri, determinate memorie "vicine" e simili. Senza conoscere il processore, non possiamo dire con certezza se SETB P2.2 sarebbe stato possibile. Tuttavia, SETB C seguito da MOV P2.2, C, è chiaramente possibile.
Olin Lathrop,

1
@OlinLathrop: il processore è quasi certamente una variante 8051, e le istruzioni impostate per quelle consentirebbero di utilizzare le stesse posizioni SETB bite le CLR bitistruzioni per MOV bit,C. Inoltre, mentre si utilizzano istruzioni discrete per leggere una porta I / O, aggiornare il valore e riscriverlo si otterrà una semantica diversa dall'uso delle istruzioni di lettura-modifica-scrittura, le istruzioni bit a bit usano tutte la stessa semantica di lettura-modifica-scrittura su I / O porte.
supercat

9

Il codice è quasi certamente per un processore che utilizza il set di istruzioni 8051. Su quel processore, la variazione di codice fornita avrebbe lo stesso effetto dell'originale, tranne per il fatto che sarebbe più veloce. L'esecuzione di "ORL C, P2.2" quando è impostato carry non avrà alcun effetto osservabile se non per sprecare un certo numero di cicli (due cicli della CPU per un totale di 24 cicli di clock su un 8051 se ricordo bene; probabilmente un numero diverso su alcune altre varianti) . Allo stesso modo con l'esecuzione di "ANL C, P2.5" quando carry è chiaro. Sebbene possano esserci alcuni tipi di processori in cui una richiesta di lettura di alcune posizioni I / O avrebbe un effetto osservabile, non credo che nessun processore in stile 8051 abbia mai avuto un comportamento simile per qualsiasi posizione I / O bit-indirizzabile, molto meno per bit di P2.

Forse lo scopo del codice era dimostrare le istruzioni ORL C,bite ANL C,bit, ma questo sembra uno strano esempio per dimostrarle.


6

Il codice assembly fornito è probabilmente generato dal compilatore. È la versione non ottimizzata delle seguenti istruzioni C, dove P2_2e P2_5sono gli oggetti bit-indirizzabili:

P2_2 |= 1;
P2_5 &= 0;

Questo può sembrare equivalente a P2_2 = 1;e P2_5 = 0;, ma non lo è se i registri indirizzabili ai bit sono oggetti volatili. Un'operazione di lettura-modifica-scrittura su un oggetto volatile deve eseguire la lettura e la scrittura, in questo ordine. Ciò garantisce che si verifichino effetti collaterali derivanti dalla lettura o dalla scrittura del registro.

Anche se non conosco un registro indirizzabile a bit 8051 con effetti collaterali, un compilatore non può presumere che non ci sia o non lo sarà mai.


1
Un buon punto per essere eventualmente generato dal compilatore. Tuttavia, sposta quindi la domanda sul perché qualcuno dovrebbe scrivere P2_2 | = 1 anziché solo P2_2 = 1.
Olin Lathrop

3

La vera differenza tra questi potrebbe essere sottile.

Nella tua risposta semplificata la logica viene letta dalla porta, imposta o cancella il valore del bit e poi riscrivilo nella porta. Nota l'intera porta potrebbe essere riscritta qui.

La soluzione, d'altra parte, usa l'istruzione di bit MOV che può operare in un modo piuttosto diverso.

Senza entrare nei dettagli della parte particolare utilizzata qui è difficile determinare se c'è una differenza o se è importante.

O potrebbe essere solo l'istruttore che ha deciso di farti pensare .... che dopo tutto .. il suo vero lavoro.


0

L'unica risposta è che il processore non supporta direttamente le istruzioni a 1 bit. Tuttavia, quando si utilizza il bit di riporto, si sa che viene manipolato solo un bit.

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.