|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
[Assembler 8086]Stampa caratteri a schermo
Ciao, ho iniziato da poco con questo linguaggio e stavo facendo un programma ( che funziona ) in assembler per sistemi 8086.
Ho scritto questo: Codice:
; You are asked to develop an 8086 assembly program that write to console a 10 elements character vector defined ; as a global variable. ; Write operation must be performed through DOS int 21h facility. DIM EQU 10 .MODEL small .STACK .DATA VETT DB 75,119,98,32,82,111,99,107,115,33 ;Questi sono caratteri ASCCi. Stampa 'Kwb Rocks!' .CODE .STARTUP MOV CX,DIM ;Imposto 10 dentro CX MOV AH,2 ;Imposto AH a 2, così da poter stampare a schermo i numeri nel vettore MOV DI,0 ;Imposto 0 dentro DI. DI è un pointer per l'indicizzazione lab2: MOV DL,VETT[DI] ;Sposto dentro DL l'elemento DIesmo di VETT. DL è usato per restituire l'output a schermo INC DI ;Aggiornamento del puntatore INT 21H ;Visualizzo il carattere DEC CX ;Decremento il contatore CMP CX,0 ;Confronto CX con 0 JNZ lab2 ;Se CX != da 0 vado a lab2 .EXIT END
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
![]() |
![]() |
![]() |
#2 | |
Senior Member
Iscritto dal: Sep 2009
Messaggi: 638
|
Ciao.
Quote:
Perchè vorresti mettere word? |
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Volevo provare a mettere DW perchè a scuola abbiamo sempre messo DW... Tutto qua... Effettivamente devo ancora capire in base a cosa mettere DW, DB, DD o l'altro che ora mi sfugge... Comunque, questo è l'errore:
![]() E mi sono dato una spiegazione: sul mio libro c'è scritto, a proposito dei registri di dato: Ciascuno dei quattro registri da 16 bit ouò essere tratto come 2 registri di 8 bit ( il nome dei registri di 8 bit si ottiene sostituendo X con L o H a seconda che si tratti del byte basso o del byte alto, rispettivamente ). Quindi, siccome io utilizzo il registro AL, di 8 bit ( 1 byte ), abbiam detto, se cerco di farci stare una word dentro ( 16 bit, 2 byte ), è chiaro che non ci sta... C'ho preso? Una cosa che non ho capito nell'incrementazione dell'indice per un vettore: mentre in C bastava mettere una costante che definisse il numero di celle del vettore, e una variabile contatore che ad ogni giro veniva incrementata; qua ora devo sia definire una costante che una variabile e ( se ho ben capito ), la prima la decremento e l'altra la aumento, ad ogni giro... E per capire se ho riempito tutto devo fare CMP <registro_della_costante>, 0 Invece di operare su due dati, non posso aumentarne solo uno e compararlo alla costante? Ovvero: Codice:
DIM EQU 15 MOV CX, DIM MOV DI, 0 ; DI è l'indice ... CMP CX, DI ; if ( DI != CX ) torna all'etichetta altrimenti riga sotto ... Codice:
; You are asked to develop an 8086 assembly program that reads from console a 10 elements character vector and ; save it in a global variable. Read operation must be performed through DOS int 21h facility. DIM EQU 10 .MODEL SMALL .STACK .DATA VETT DB DIM DUP (?) .CODE .STARTUP MOV CX,DIM ;Carica in CX la dimensione del vettore. CX è usato per i contatori o operazioni su stringhe MOV DI,0 ;Azzero DI. DI è un pointer usato per l'indicizzazione MOV AH,1 ;Imposto AH a 1, questo permette l'acquisizione di un carattere da tastiera. lab1: INT 21H ;Leggo un carattere da tastiera che viene messo nel registro AL MOV VETT[DI],AL ;Sposto il carattere dentro VETT[DI] INC DI ;Incremento DI di uno ;DEC CX ;Decremento CX di uno CMP CX,DI ;Confronto il valore in CX con quello di DI JNZ lab1 ;Se diversi vado a lab1 .EXIT END
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
Ultima modifica di kwb : 06-11-2010 alle 15:40. |
![]() |
![]() |
![]() |
#4 | |||
Senior Member
Iscritto dal: Sep 2009
Messaggi: 638
|
Quote:
allora, tu in questo caso usi DB perchè vuoi memorizzare dei caratteri, che quindi sono di singolo byte. Se tu avessi voluto memorizzare dei numeri a 16 bit, avresti usato DW, che quindi riservava 2 byte per ogni elemento. Però, allocare 10 elementi DW è come allocare 20 elementi DB. Visto che per la cpu non c'è nessuna differenza (non sa se sono 20 byte o 10 word), l'assemblatore pensa che tu stia facendo un errore, e ti dice che stai cercando di prendere dei dati che avevi dichiarato come word. Se tu vuoi ad ogni costo dichiarare il vettore come DW, e accedere a singoli byte, puoi modificare così l'istruzione Codice:
MOV DL, BYTE PTR VETT[DI] A questo punto però, devi fare un'altra modifica al listato... vediamo se riesci a trovarla ![]() Quote:
![]() Quote:
L'8086 ha una istruzione chiamata LOOP che è uguale a: Codice:
LOOP etichetta -> CMP CX,0 JNZ etichetta |
|||
![]() |
![]() |
![]() |
#5 | ||
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
È bastato cambiare l'istruzione Codice:
INC DI Codice:
ADD DI,2 Incremento volevo dire ![]() Quote:
EDIT: Bellissimo il thread su WinUX, mi hai fatto fare due risate ![]()
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
||
![]() |
![]() |
![]() |
#6 | ||
Senior Member
Iscritto dal: Sep 2009
Messaggi: 638
|
Quote:
Quote:
Anche qualsiasi compilatore C usa il tuo metodo, se compili questo codice inutile: Codice:
int main() { int a, c; for(c=0; c<10; ++c) a = c; return 0; } Codice:
gcc prova.c -S -O0 -masm=intel -m32 viene tradotto in questo assembly: Codice:
main: push ebp ; prepara lo stack e alloca le 2 variabili mov ebp, esp sub esp, 16 mov DWORD PTR [ebp-8], 0 jmp .L2 ciclo: mov eax, DWORD PTR [ebp-8] ; prende C mov DWORD PTR [ebp-4], eax ; lo salva in a add DWORD PTR [ebp-8], 1 ; ++c .L2: cmp DWORD PTR [ebp-8], 9 ; confronta C con 9 jle ciclo ; salta se è minore o uguale mov eax, 0 ; return 0 leave ret |
||
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
![]() ![]() I commenti li hai aggiunti tu immagino ![]()
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
![]() |
![]() |
![]() |
#8 | ||
Senior Member
Iscritto dal: Sep 2009
Messaggi: 638
|
Quote:
![]() Il ciclo di compilazione è: sorgenteC ---compilatore--> sorgenteASM ---assembler--> codiceOggetto ---linker--> programmaEseguibile In effetti quando chiami Gcc lui da solo poi richiama l'assemblatore e il linker automaticamente. Ci sono poi anche compilatori che traducono direttamente in codice macchina, ma non so dirti quali siano. Quote:
![]() |
||
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
![]()
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Sep 2009
Messaggi: 638
|
Quote:
![]() http://it.wikipedia.org/wiki/GNU_Compiler_Collection Quando chiami solo "gcc" dalla linea di comando, non chiami neanche più il compilatore vero e proprio, ma un front-end che richiama poi il compilatore, assembler e linker... per il linguaggio giusto in base al sorgente che gli passi come parametro (almeno per i sorgenti con un'estensione identificabile). Infatti se vuoi puoi passare a gcc il nome di un file Assembly, e lui provvede da solo a chiamare solo l'assemblatore e il linker, o puoi passargli dei file oggetto e lui chiama solo il linker, oppure gli puoi passare tutti e tre i tipi contemporaneamente e lui si preoccupa di attivare le fasi giuste in base al file. Ultima modifica di Z80Fan : 06-11-2010 alle 18:13. |
|
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
![]()
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:37.