Avvio alla Programmazione

Ed eccoci entrare nella fase iniziale della programazzione, con questo capitolo si entra nella fase diretta della stesura del codice macchina con spiegazioni ed esempi di codice in assembler, stà a voi cercare di non copiare puramente il codice ma di crearvi un livello di comprensione per capire l'effetivo funzionamento del medesimo. Il codice quì riportato può essere testato su qualsiasi processore "intel" a partire da un "386" in sù.
La codifica delle istruzioni in assembler richiede unicamente la numerazione in esadecimale quindi da qui in poi dobbiamo scordarci la numerazione decimale "fonte dei paperoni" e ogni riferimento ai numeri sarà in puro esadecimale.

Si parte con una configurazione del disco-fisso come spiegata in precedenza del tipo:
00,00,00,00 = primo segmento del disco
00,01,00,00 = segmento di inizio del nostro programma
02,00,00,00 = segmento di inizio eventuale sistema operativo se usiamo un solo calcolatore


Come avrete notato abbiamo ritagliato una piccola partizione per scriverci il nostro programma mentre tutto il resto si può utilizzare per il vostro sitema operativo o altro eventuale codice che avete installato. Non è poi così difficile spostare un poco avanti il vostro sistema operativo, con un po' di buona volontà si può fare senza rischiare perdite di dati o codice. Chi invece preferise utilizzare due calcolatori uno completmente per il proprio programma non avrà problemi di movimento codice avendo tutto il disco a propria disposizione, quindi dalla locazione del disco sopra indicata potrà inserire il codice del nuovo programma in costruzione.
Quindi ricapitolando il codice del nostro programma verrà copiato su disco a partire dalla locazione sopra indicata, facendo uso di un editor esadecimale si può ad esempio scriverlo direttamente in quelle locazioni, oppure lo si può scrivere con un semplice programma di debug e poi copiare il solo codice macchina nelle relative locazioni del disco. Mentre invece se si usano due calcolatori, il codice scritto con il calcolatore avente il sistema operativo va poi spostato sull'altro calcolatore alle locazioni del nostro programma, quindi si dovrà trovare un metodo per spostarlo, il più semplice è copiarlo su di un floppy per spostarlo da un calcolatore all'altro e scrivere una funzione che copi il codice dal floppy è una cosa banale, più complicato è se non si dispone di eventuali floppy sulle due macchine ma lunica soluzione rimane spostarlo tramite cd che complica parecchio le cose in quanto scrivere delle funzioni per leggere un cd non siano alla portata di tutti, penso... il problema lo affronteremo più avanti troveremo pure una soluzione magari quando saremo un pochino più capaci nello scrivere le nostre funzioni.

Il codice del nostro programma sarà suddiviso per programmi, ogni programma al quale daremo inizio verrà assegnato un nome e una locazione del disco dove sarà depositato, di li potrà essere richiamato con il relativo none, copiato in memoria ed eseguito, ogni programma sarà formato da una serie di funzioni definite come "call" e da un corpo di codice progressivo che darà espressione e movimento alla nostra idea.
Ogni programma avrà una dimensione massima di un segmento di codice macchina, mi sembra già tanto, quindi i programmi verranno divisi per segmento, questa piccola condizione ci permette di avere codice eseguibile molto veloce, in confronto del codice di un sistema operativo "che sono delle vere e proprie lumache" e ci permette di usare una codifica della condizione di salto all'interno di un segmento quindi tutte le nostre "jmp" avranno una dimensione di 16 bit, mentre il resto del codice potrà spaziare fino a 32 bit.
L'mbr del disco fisso, come tutti sanno, risiede sul primo segmento del disco e quindi li lo lascieremo senza andarlo a toccare, infatti a noi non ci serve, per l'avvio del nostro programma useremo un semplice disco floppy o in mancanza un cd che andremo a scrivere, poi impostato l'avvio del calcolatore da floppy o da cd ci basterà inserire il disco e il nostro programma partirà come una saetta.

Il primo codice che andiamo a scrivere è un mbr per l'avvio del nostro programma da disco floppy, lo posiamo scrivere direttamente sul dico floppy tramite un editor esadecimale. L'mbr del disco floppy stà sul segmento 00,00 ed ha una dimensione di 200 bytes, quando il disco viene inserito il bios provvede a caricare quel segmento alla specifica locazione della memoria 0000:7c00 settore di boot da dove prendono l'avvio tutti i programmi belli, brutti, grandi e piccoli il calcolatore non fa distinzione e da quella locazione da l'avvio sequenziale a tutte le funzioni del nostro programma.
Se prendiamo un disco floppy e lo andiamo a leggere con un editor esadecimale possiamo notare che i primi due bytes sevono per codificare una "jmp" poi si intravvedono altre numerazioni, in particolare le prine 3o4 righe sevono al sistema operativo e non sevono a noi; però non le possiamo cancellare altrimenti il sitema operativo non potrà più leggere quel disco, quindi faremo patire il nostro mbr un pochino più avanti, andiamo a calcolare dove rimanda quella jmp iniziale del disco e da quella locazione daremo inizio al nostro codice.

Partiamo con il codice per l'mbr da disco floppy
      :003e  cli              ;prima operazione impostare lo stack
      :003f  mov ax,0000
      :0042  mov ss,ax
      :0044  mov sp,ffff
      :0047  mov dx,03f2      ;controller del floppy
      :004a  mov al,00
      :004c  out dx,al        ;andiamo a spegere il motore del floppy
      :004d  sti
      :004e  mov ax,07c0      ;settore di boot
      :0051  mov ds,ax
      :0053  jmp 0070
      :0060  *10 00           ;piccolo buffer dati per il bios "int 13"
             *01 00           ;numero settori
             *00 00 00 10     ;locazione del nostro programma in memoria
             *80 01 08 00     ;settore del disco (deposito del nostro programma)
      :0070  lea si,[0060]    ;punta al buffer del bios
      :0074  mov bx,0000
      :0077  mov cx,0080      ;numero di settori da caricare
      :007a  mov ah,42        ;legge un settore del disco
      :007c  mov dl,80        ;disco fisso
      :007e  int 13
      :0080  add bx,0200
      :0084  mov [0064],bx    ;prossima locazione in memoria
      :0088  inc w[0068]      ;prossimo settore da caricare
      :008c  loop 007a        ;abbiamo caricato il segmento "codice"

      :008e  mov eax,20000000
      :0094  mov [0064],eax
      :0098  mov eax,00080280
      :009e  mov [0068],eax
      :00a2  mov bx,0000
      :00a5  mov cx,0080
      :00a8  mov ah,42
      :00aa  mov dl,80
      :00ac  int 13
      :00ae  add bx,0200
      :00b2  mov [0064],bx
      :00b6  inc w[0068]
      :00ba  loop 00a8        ;abbiamo caricato il segmento "dati"

      :00bc  mov eax,30000000
      :00c2  mov [0064],eax
      :00c6  mov eax,00080380
      :00cc  mov [0068],eax
      :00d0  mov bx,0000
      :00d3  mov cx,0080
      :00d6  mov ah,42
      :00d8  mov dl,80
      :00da  int 13
      :00dc  add bx,0200
      :00e0  mov [0064],bx
      :00e4  inc w[0068]
      :00e8  loop 00d6        ;abbiamo caricato il segmento "call"
      :00ea  jmp 1000:0000    ;salto far sul nostro programma
      
Il dischetto del floppy è pronto per l'avvio del nostro programma, sintetizzo i principali passaggi: abbiamo caricato l'intero programma in memoria disponendolo in tre segmenti consecutivi e con la "jmp" finale siamo saltati all'inizio del primo segmento caricato.
Il segmento "codice" lo abbiamo prelevato dal disco-fisso alla locazione 00,08,01,80 e lo abbiamo depositato in memoria alla locazione 1000:0000 (modo reale)
Il segmento "dati" lo abbiamo prelevato dal disco-fisso alla locazione 00,08,02,80 e lo abbiamo depositato in memoria alla locazione 2000:0000 (modo-reale)
Il segmento "call" lo abbiamo prelevato dal disco-fisso alla locazione 00,08,03,80 e lo abbiamo depositato in memoria alla locazione 3000:0000 (modo-reale)

Se non abbiamo la disponibilità dei floppy ci dobbiamo arrangiare impostando l'mbr da cd, a tale punto devo precisare che lavorare su cd è una cosa piuttosto ardua, penso che il sistema cd sia un gran pasticcio, mi spiego i cd sono stati creati e programmati per essere scritti una sola volta in un colpo unico dalle fabbriche e quindi distribuiti per la sola lettura su masterizzatori di vario tipo, poi si pensò bene che si sarebbe potuto anche scriverli direttamente su di un calcolatore allora si inventarono tutti i regolamenti e programmi a tale funzione.
Scrivere un cd su calcolatore oggi è possibile però i problemi non mancano, per prima cosa dobbiamo procurarci il programma specifico a seconda di cosa vogliamo fare, poi possiamo trasferire sul cd i dati. Se abbiamo una buona quantità di dati da trasferire su cd possiamo quasi riempirlo in un solo colpo, ma se abbiamo pochi dati da trasferire il cd ci rimane in prevalenza vuoto, se poi andiamo ad aggiungere altri dati sullo stesso cd va a finire che con qualche registrazione il disco improvvisamente rimane pieno, oppure possiamo cancellare il tutto e riscrivere da inizio cd i nostri dati, naturalmente perdendo quanto vi era stato registrato in precedenza.
Ora se andiamo ad esaminere il nostro cd che abbiamo registrato a più riprese dobbiamo constatare che la maggior parte del cd è rimasta vuota senza possibilità di aggiungere altri dati, peggio ancora se andiamo a registrare i dati in formato "iso" il cd si riempie alla prina registrazione e poi viene chiuso, bloccato non si può aggiungere altro. Penso che il cd su calcolatore sia un pò un mangia soldi quindi ne faremo il meno uso possibile.

Andiamo a scrivere "l'mbr" per l'avvio del nostro programma da cd; il codice da portare su cd è lo stesso che ho riportato in precedenza, tale e quale, quindi dobbiamo scrivere quel codice con un editor esadecimale poi salvarlo su disco fisso come archivio di tipo binario, poi con uno specifico programma per cd dobbiamo convertirlo in formato "iso" e masterizzarlo su di un nuovo cd, tutto fatto con un settore di dati binari occupiamo l'intero cd che ci servirà per l'avvio del nostro programma da masterizzatore.

Mbr di avvio

A questo punto abbiamo codificato l'mbr del nostro programma però per il momento non ci serve fintanto che non abbiamo una parte del nostro programma pronto per l'esecuzione, quindi passiamo alla scrittura dell'mbr denominato "avvio" che ci permette di caricare ed eseguire le funzioni di base per poter lavorare direttamente sulla nostra macchina. Le funzioni di base rappresentano il primo programma che andremo a codificare e comprendono le impostazioni essenziali della macchina e un piccolo compilatore provvisorio che quando verrà eseguito ci permetterà la stesura di tutto il codice che vogliamo realizzare. Qindi dobbiamo munirci di un secondo disco floppy o cd e riportarci sopra il codice che andiamo a vedere.

Secondo mbr denominato "avvio"
      :003e  cli              ;prima operazione impostare lo stack
      :003f  mov ax,0000
      :0042  mov ss,ax
      :0044  mov sp,ffff
      :0047  mov dx,03f2      ;controller del floppy
      :004a  mov al,00
      :004c  out dx,al        ;andiamo a spegere il motore del floppy
      :004d  sti
      :004e  mov ax,07c0      ;settore di boot
      :0051  mov ds,ax
      :0053  jmp 0070
      :0060  *10 00           ;piccolo buffer dati per il bios "int 13"
             *01 00           ;numero settori
             *00 00 00 10     ;locazione del nostro programma in memoria
             *80 00 08 00     ;settore del disco (deposito del nostro programma)
      :0070  lea si,[0060]    ;punta al buffer del bios
      :0074  mov bx,0000
      :0077  mov cx,0080      ;numero di settori da caricare
      :007a  mov ah,42        ;legge un settore del disco
      :007c  mov dl,80        ;disco fisso
      :007e  int 13
      :0080  add bx,0200
      :0084  mov [0064],bx    ;prossima locazione in memoria
      :0088  inc w[0068]      ;prossimo settore da caricare
      :008c  loop 007a        ;abbiamo caricato il segmento "codice"

      :008e  mov eax,20000000
      :0094  mov [0064],eax
      :0098  mov eax,00080000
      :009e  mov [0068],eax
      :00a2  mov bx,0000
      :00a5  mov cx,0080
      :00a8  mov ah,42
      :00aa  mov dl,80
      :00ac  int 13
      :00ae  add bx,0200
      :00b2  mov [0064],bx
      :00b6  inc w[0068]
      :00ba  loop 00a8        ;abbiamo caricato il segmento "dati"
      :00bc  jmp 1000:0000    ;salto far sul nostro programma
      
Il nostro secondo mbr è pronto:
Abbiamo prelevato il segmento "codice" dal disco-fisso alla locazione 00,08,00,80 e lo abbiamo depositato in memoria alla locazione 1000:0000 (modo-reale)
Abbiamo prelevato il segmento "dati" dal disco-fisso alla locazione 00,08,00,00 e lo abbiamo depositato in memoria alla locazione 2000:0000 (modo-reale)

Introduzione alla programmazione in "Assembler"
invia E-mail