trucchi-com

tutti i trucchi che nessuno sà

 

AREA PERSONALE

 

TAG

 

ARCHIVIO MESSAGGI

 
 << Luglio 2024 >> 
 
LuMaMeGiVeSaDo
 
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
 
 

FACEBOOK

 
 

CONTATTA L'AUTORE

Nickname: romoletto640
Se copi, violi le regole della Community Sesso: M
Età: 59
Prov: EE
 

 

« assembler per principiantiassembler per principianti »

assembler per principianti

Post n°15 pubblicato il 02 Giugno 2007 da romoletto640
 

Cap. 6 LISTA DELLE ISTRUZIONI

ADD XX,YY

A proposito di numeri, se sono compresi tra 0 e 255, ossia la capacità di una cella di memoria si chiamano BYTE, se sono invece, tra 0 e 65535, ossia 16 bit si chiamano WORD.

ADC XX,YY

AND XX,YY

CALL (NEAR/FAR) XX

CLC

CLD

CLI

Lo so, lo so, vi state chiedendo che diavolo sono questi interrupt. Detto fatto.

Gli interrupt sono delle interruzioni che il sistema invia alla CPU, pensateci un po' su, il vostro programma sta facendo le sue cose, ma l'orologio del computer continua a funzionare, oppure il vostro programma non sta leggendo la tastiera, ma voi premete CTR-ALT-CANC ed il computer si resetta lo stesso, come mai?. Semplice, alcuni dispositivi come l'orologio, la tastiera, ecc. sono in grado di mandare dei segnali alla CPU del tipo 'Hey, smettila di fare quello che stai facendo, e fai un attimo quest'altra cosa, poi puoi riprendere da dov'eri rimasta.

Pensate ad un computer che gestisce una centrale nucleare, voi lo state usando per giocare a tetris ed intanto il nocciolo è in fusione e sta mandando a fuoco il resto del mondo, bene gli allarmi possono mandare un interrupt alla CPU e questa metterà da parte il vostro tetris mentre spegnerà il nocciolo e salverà il mondo.

Con l'istruzione CLI dite alla CPU di lasciar perdere gli interrupt e badare solo al vostro tetris, che vada pure a fuoco tutta la terra.

CMC

Corso di assembler per principianti

INT

IRET

JA

JB

JBE

JC YY

JCXZ YY

JE YY

JG YY

JGE

JMP SHORT

JMP NEAR

JMP FAR SS:AA

LODSB

LODSW

LOOP

LOOPE

LOOPNE

MOV XX,YY

MUL b

OR XX,YY ;Ricordate l'operazione OR vero?.

POP XX ;E

Immaginiamo di aver scritto un videogioco e di avere memorizzato in AX la posizione della nostra navetta spaziale, in CX il numero di vite che ancora abbiamo, in DX la navetta nemica, insomma abbiamo occupato tutti i registri.

Ad un certo punto del programma abbiamo bisogno di scrivere sullo schermo che si sta avvicinando un grosso asteroide e ci serve, per farlo, il registro AX, come si fa?.

Se lo usiamo subito così, perderemo la posizione della nostra navetta e ci perderemo negli abissi siderali, dunque bisognerebbe appoggiarlo da qualche parte, usare AX e dopo recuperare il vecchio valore.

Secondo voi, dove potremmo appoggiarlo? una cella di memoria? giusto, ma se volessi qualcosa di più pratico ed immediato? ma certo, una catasta, lo STACK, come ho fatto a non pensarci prima? è il posto ideale.

Dunque, eravamo rimasti allo stack, e come si fa' a mettere AX sullo stack?, ma con PUSH AX, naturalmente, e dopo quando vorremo recuperarlo basterà fare POP AX, tenete presente che se nel frattempo effettuate una CALL od una PUSH di un altro registro non potete eseguire la POP perché la CALL spinge sullo stack l'indirizzo corrente prima di saltare al nuovo e, quindi, il vostro valore di AX passerebbe in seconda posizione, mentre la POP recupera sempre l'ultimo valore aggiunto allo stack, ovviamente se eseguo PUSH AX e dopo POP BX otterro' l'effetto di spostare il valore di AX in BX, ma in questo caso era preferibile MOV BX,AX, con lo stesso risultato.

Comunque l'esempio fatto è un po' forzato perché in genere i valori che vengono usati dal programma vengono memorizzati in celle di memoria prefissate chiamate variabili (perché il loro valore può cambiare nel corso di esecuzione del programma).

A ciascuna cella possiamo assegnare un nome qualsiasi e riferirci ad essa con questo nome, per esempio la cella che contiene le vite del nostro gioco potremo chiamarla vite ed ogni volta che ci ammazzano possiamo fare 'DEC vite' che decrementa le vite e controllare il valore se è arrivato a zero (game over).

Ricordate che tutte le operazioni di lettura e scrittura diretta in memoria avvengono nel segmento DS a meno che non specifichiate un segmento diverso di volta in volta.

Notate il nome dei registri di segmento:

CS

DS

ES

SS

Dal 386 in poi esistono anche i segmenti FS e GS simili ad ES.

Volete un esempio sull'uso delle variabili?. Eccolo:

Pippo DB 10 ;Inizializza una variabile ad un byte (DB),chiamala pippo e dagli il valore 10.

Beppe DW 10000 ;Inizializza una variabile a due byte (DW) chiamala beppe e mettici 10000.

Ugo DB 'Ciao mondo' ;Inizializza una serie di byte (10) chiamali ugo e ponici i valori ASCII della frase''.

Successivamente, se il programma ha necessità di aumentare pippo di 1 per portarlo a 11, farà:

MOV AL,

INC AL

MOV pippo,AL

Proseguiamo con la lista? Ok, stavo solo chiedendo.

RCL XX

RCR XX

 

RET

RETF

ROL ; Come RCL, ma l'ottavo bit rientra direttamente al primo posto senza coinvolgere il carry.

ROR

STC

STD

STI

TEST XX,YY

Ovviamente ci sono tante altre istruzioni che ho tralasciato perché un po' più complicate o non utili per i nostri scopi.

Infatti, se ricordate, abbiamo detto che l'assembler è utile più che altro per quelle piccole utility di poco conto che non chiedono grandi risorse, ma almeno un po' di velocità, oppure questo corso può servire a capire qualcosa quando leggerete un listato assembler.

; testa i valori XX e YY ed aggiorna i flag. In pratica avviene un AND virtuale tra XX e YY.
; Poni ad 1 il flag degli interrupt. Interrupt abilitati.
; Poni ad 1 il flag di direzione, SI e DI verranno incrementati dopo istruzioni tipo LODSB o STOSB.
; Poni a 1 il flag di carry.
; Come sopra, ma verso destra.
;Come sopra, ma preleva dallo stack anche il valore del segmento di ritorno, si usa dopo una CALL FAR.
;Ritorna al programma chiamante dopo una CALL.
;Come sopra, ma verso destra. Stavolta il carry entra all'ottavo posto.
; (Rotate with carry left) ruota a sinistra con riporto. Mettiamo che XX sia il registro AL ad 8 bit. Dunque AL=10110001b, ruotare a sinistra significa, prendi il primo bit a destra (1) e spostalo al secondo posto, prendi il secondo e spostalo al 3° e così via, alla fine prendi l'ottavo e spostalo nel flag di carry, poi prendi il vecchio valore del flag di carry e mettilo al primo bit di Al. Ovviamente gli spostamenti avvengono sempre sui valori originali dei singoli bit.
;poni in pippo AL, ora pippo=11
;incrementa AL AL=AL+1 (11)
pippo ; Carica in AL il contenuto di pippo (ricordate che i valori byte ad 8 bit vanno caricati nei registri ad 8 bit, vero?
; (Stack Segment) segmento dello stack.
; (Extra Segment) a vostra disposizione per altri segmenti.
; (Data Segment) segmento dei dati.
; (Code Segment) segmento del codice.
questo?. Bé, per spiegarlo farò un piccolo esempio:
;Moltiplica AX per b. Risultato in AX
;Copia il valore di XX in YY, alla fine sia XX che YY conterranno il valore di XX, che può essere un registro, una cella di memoria od un valore numerico
; Come sopra, ma solo se flag di zero=0 e CX è maggiore di 0
; Decrementa CX, salta se cx è maggiore di 0 e flag di zero=1
; Decrementa CX, se non è zero salta di b bytes.
;Carica la word puntata da DS:(SI) in AX, incrementa SI.
; Carica il byte puntato da DS:(SI) in AL, incrementa SI.
; Salta in un altro segmento (SS) indirizzo AA.
;Salta e basta di w bytes (+-32737)
;Salta e basta di b bytes avanti o indietro (+-127)
; (Jump Greater Equal) come sopra, anche uquale. Ovviamente esistono anche le condizioni opposte ossia ,NZ (non zero), Less (minore), NE (not equal), ecc.
; (Jump Greater) salta se il primo operando è più grande del secondo. Considera il segno flag S
; (Jump Equal) salta se zero=1
;(Jump CX Zero) salta se CX=0, ve l'avevo detto che CX è il registro principe per contare all'indietro.
;(Jump Carry) salta se carry=1
;(Jump Below Equal) salta se carry=1 e zero=1
; (Jump Below) salta se carry=1, il risultato è minore. ;Salta all'indirizzo relativo YY, se il flag di carry è 0 ed il flag di zero è 0. Salto relativo significa che YY viene considerato positivo o negativo, come si diceva nella lezione precedente, e sommato o sottratto all'indirizzo corrente. Il programma riprenderà da qui. ; Fine dell'interrupt, ritorna pure dove eri. ;Richiama l'interrupt numero b, comodo per simulare la fusione del nocciolo senza rischiare il mondo. ;Complementa il flag di carry, ossia giralo a rovescio. ;Azzera il flag di interrupt, così la CPU non eseguirà gli interrupt. ; Azzera il flag di direzione. ; Clear carry flag, azzera il flag di carry ;Chiama un altro pezzo di programma che può trovarsi sullo stesso segmento (NEAR) oppure lontano (FAR), XX è l'indirizzo. ; Conoscete già la funzione AND, vero? ;Come per ADD, ma aggiunge 1 se il flag di carry è settato ad 1. ; Ovvero aggiungi ad XX che può essere un registro il dato YY che può essere un altro registro od un valore numerico.

La URL per il Trackback di questo messaggio è:
https://blog.libero.it/trucchicom/trackback.php?msg=2789022

I blog che hanno inviato un Trackback a questo messaggio:
Nessun trackback

 
Commenti al Post:
Nessun commento
 
 
 

INFO


Un blog di: romoletto640
Data di creazione: 29/05/2007
 

CERCA IN QUESTO BLOG

  Trova
 

ULTIME VISITE AL BLOG

precious445benny1984fredom010pantera_blanca2NevegGgiallAea.joobleRjegu73developer68OLIO5wallygator54istrice82hiram9mrk2005rospetta000erconte5
 

CHI PUò SCRIVERE SUL BLOG

Solo l'autore può pubblicare messaggi in questo Blog e tutti gli utenti registrati possono pubblicare commenti.
 
RSS (Really simple syndication) Feed Atom
 
 

I MIEI LINK PREFERITI

 

© Italiaonline S.p.A. 2024Direzione e coordinamento di Libero Acquisition S.á r.l.P. IVA 03970540963