LOVE85
26-06-2006, 14:52
Ciao ragazzi ho consegnato online il materiale e il professore una volta controllato il codice ASM del mio elaborato dice:
Se imposta i dati di input secondo il caso di prova riportato dal
correttore, ossia
unsigned int Point = ( (-1000)<<16 | ((1000)&0xFFFF) );
unsigned int PointSet[]={
(0<<16) | (0)&0xFFFF,
(1000<<16) | (1000)&0xFFFF,
(-1000<<16) | (-1000)&0xFFFF,
((-999)<<16) | (999)&0xFFFF,
((-1000)<<16) | (200)&0xFFFF
};
noterà che il suo programma restituisce l'indice 1 (il punto 1000,1000),
mentre il punto più vicino è quello di indice 3 (999,-999).
Suggerisco di eseguire passo a passo con il debugger il programma in modo da
trovare l'errore.
ECCO IL MIO ELABORATO 2:
#include <stdio.h>
void main()
{
unsigned int Point = (5<<16) | (3)&0xFFFF; //il punto
unsigned int PointSet[] = { (10<<16) | (3)&0xFFFF, (4<<16) | (2)&0xFFFF, (5<<16) | (20)&0xFFFF}; //insieme
int n = sizeof(PointSet)/sizeof(PointSet[0]); // numero punti dell'insieme
int index; //risultato: indice del punto più vicino a Point
__asm
{
MOV ECX,n //Inizializza il registro ECX con il valore del numero dei punti n
MOV EDX,1 //Carica il valore 1 nel registro EDX per il confronto con il valore n
CMP EDX,ECX //Confronta 1 con il valore n
JE Fine //Salta a Fine se n=1 (si confronto un solo punto)
Ciclo1: MOV EAX,PointSet[ECX*4-4] // Inizia il ciclo che carica ogni elemento del vettore per confrontarlo con il punto dato in termini di distanza
PUSH EAX // Salvaguarda il contenuto di EAX (coordinate del punto corrente) nello stack per poter operare su EAX senza perdere il valore precedente
MOV EBX,Point[0] //Carica in EBX il punto dato verso il quale determinare la distanza
PUSH EBX //Salvaguarda il contenuto di EBX nello stack come sopra
AND EAX,0000FFFFh //Isola il valore di x del punto corrente dal suo valore y nel registro EAX
TEST AH,10000000b //Verifica se x del punto corrente è negativo
JNZ NegativoxVettore //Se x è negativo salta a NegativoxVettore dove provvede ad estendere il valore 1 in tutti i 16 bit più significativi
Coordinatay: AND EBX,0000FFFFh //Isola il valore di x del punto dato dal suo valore y nel registro EBX
TEST BH,10000000b //Verifica se x del punto dato è negativo
JNZ NegativoxPunto //Se x è negativo salta a NegativoxPunto dove provvede ad estendere a 1 tutti i 16 bit più significativi
Prosegui1: SUB EAX,EBX //Effettua la sottrazione tra le coordinate x del punto dato e del punto corrente
MUL EAX //Eleva al quadrato il riultato della sottrazione precedente facendo la moltiplicazione per se stesso
POP EBX //Estrae dallo stack e inserisce nel registro EBX nuovamente le coordinate del punto corrente
SHR EBX,16 //Sposta i primi 16 bit più significativi contenenti y del punto corrente nei 16 bit meno significativi
TEST BH,10000000b //Verifica se y del punto corrente è negativo
JNZ NegativoyVettore //Se y è negativo salta a NegativoyVettore dove provvede ad estendere a 1 tutti i 16 bit più significativi
Prosegui2: POP EDX //Estrae dallo stack e inserisce nel registro EDX nuovamente le coordinate del punto dato
SHR EDX,16 //Sposta i primi 16 bit più significativi contenenti y del punto dato nei 16 bit meno significativi
TEST DH,10000000b //Verifica se y del punto dato è negativo
JNZ NegativoyPunto //Se y è negativo salta a NegativoyPunto dove provvede ad estendere a 1 tutti i 16 bit più significativi
Prosegui3: SUB EDX,EBX //Effettua la sottrazione tra le coordinate y del punto dato e del punto corrente
MOV EBX,EAX //Salvaguarda il contenuto di EAX nel registro EBX
MOV EAX,EDX //Carica in EAX la differenza per predisporla alla moltiplicazione per se stessa
MUL EAX //Eleva al quadrato la differenza fra le y del punto corrente e del punto dato facendo la moltiplicazione per se stessa
ADD EAX,EBX //Somma i quadrati delle differenze tra le x e le y del punto dato e del punto corrente che rappresenta la distanza al quadrato
PUSH EAX //Salvaguarda nello stack la distanza al quadrato corrente da utilizzare per individuare quella minore
LOOP Ciclo1 //Gestione del Ciclo che ripete tutte le operazioni precedenti per ogni punto
JMP VersoFine //Salta a fine una volta terminato il ciclo e calcolati tutti i quadrati delle distanze salvaguardati nello stack
NegativoxVettore: OR EAX,11111111111111110000000000000000b //Imposta a 1 i 16 bit più significativi della componente x del punto corrente
JMP Coordinatay //Ritorna all'interno del Ciclo1
NegativoxPunto: OR EBX,11111111111111110000000000000000b //Imposta a 1 i 16 bit più significativi della componente x del punto dato
JMP Prosegui1 //Ritorna all'interno del Ciclo1
NegativoyVettore: OR EBX,11111111111111110000000000000000b //Imposta a 1 i 16 bit più significativi della componente y del punto corrente
JMP Prosegui2 //Ritorna all'interno del Ciclo1
NegativoyPunto: OR EDX,11111111111111110000000000000000b //Imposta a 1 i 16 bit più significativi della componente y del punto dato
JMP Prosegui3 //Ritorna all'interno del Ciclo1
VersoFine: MOV ECX,n //Carica nel registro ECX la dimensione n del vettore
DEC ECX //Decrementa di 1 il valore del registro ECX
MOV EDX,1 //Carica il valore 1 nel registro EDX (qui utilizzato per identificare l'indice della distanza al quadrato più piccolo)
POP EAX //Inizia l'estrazione delle distanza del quadrato per il loro conronto
Ciclo2: POP EBX //Inizio del ciclo di confronto
CMP EAX,EBX //Confronto tra le distanze corenti
JB Ritorno //Salta se la differenza delle distanze al quadrato è negativa
MOV EAX,EBX //Altrimenti scambia le due distanze in modo da mettere quella più piccola sempre in EAX
INC EDX //Calcola l'indice della distanza più piccola finora individuata e salvata in EAX
Ritorno: LOOP Ciclo2 //Ritorna al Ciclo2 per terminare i confronti delle distanze al quadrato
Fine: DEC EDX //Decrementa di 1 il valore del registro EDX per adeguarsi all'indice del vettore
MOV index,EDX //Carica l'indice trovato nella variabile index per stamparla a video
}
// Stampa su video
printf("Il punto piu' vicino a (%d,%d) e' (%d,%d) [indice=%d]\n",(short int)(Point&0xFFFF),(short int)(Point>>16),(short int)(PointSet[index]&0xFFFF),(short int)(PointSet[index]>>16),index);
}
Provate con altri punti anche quelli negativi e il programma funziona come deve. Mettendo il caso che dice il prof mi dà l'indice sbagliato. Perchè? :cry: :cry:
Se imposta i dati di input secondo il caso di prova riportato dal
correttore, ossia
unsigned int Point = ( (-1000)<<16 | ((1000)&0xFFFF) );
unsigned int PointSet[]={
(0<<16) | (0)&0xFFFF,
(1000<<16) | (1000)&0xFFFF,
(-1000<<16) | (-1000)&0xFFFF,
((-999)<<16) | (999)&0xFFFF,
((-1000)<<16) | (200)&0xFFFF
};
noterà che il suo programma restituisce l'indice 1 (il punto 1000,1000),
mentre il punto più vicino è quello di indice 3 (999,-999).
Suggerisco di eseguire passo a passo con il debugger il programma in modo da
trovare l'errore.
ECCO IL MIO ELABORATO 2:
#include <stdio.h>
void main()
{
unsigned int Point = (5<<16) | (3)&0xFFFF; //il punto
unsigned int PointSet[] = { (10<<16) | (3)&0xFFFF, (4<<16) | (2)&0xFFFF, (5<<16) | (20)&0xFFFF}; //insieme
int n = sizeof(PointSet)/sizeof(PointSet[0]); // numero punti dell'insieme
int index; //risultato: indice del punto più vicino a Point
__asm
{
MOV ECX,n //Inizializza il registro ECX con il valore del numero dei punti n
MOV EDX,1 //Carica il valore 1 nel registro EDX per il confronto con il valore n
CMP EDX,ECX //Confronta 1 con il valore n
JE Fine //Salta a Fine se n=1 (si confronto un solo punto)
Ciclo1: MOV EAX,PointSet[ECX*4-4] // Inizia il ciclo che carica ogni elemento del vettore per confrontarlo con il punto dato in termini di distanza
PUSH EAX // Salvaguarda il contenuto di EAX (coordinate del punto corrente) nello stack per poter operare su EAX senza perdere il valore precedente
MOV EBX,Point[0] //Carica in EBX il punto dato verso il quale determinare la distanza
PUSH EBX //Salvaguarda il contenuto di EBX nello stack come sopra
AND EAX,0000FFFFh //Isola il valore di x del punto corrente dal suo valore y nel registro EAX
TEST AH,10000000b //Verifica se x del punto corrente è negativo
JNZ NegativoxVettore //Se x è negativo salta a NegativoxVettore dove provvede ad estendere il valore 1 in tutti i 16 bit più significativi
Coordinatay: AND EBX,0000FFFFh //Isola il valore di x del punto dato dal suo valore y nel registro EBX
TEST BH,10000000b //Verifica se x del punto dato è negativo
JNZ NegativoxPunto //Se x è negativo salta a NegativoxPunto dove provvede ad estendere a 1 tutti i 16 bit più significativi
Prosegui1: SUB EAX,EBX //Effettua la sottrazione tra le coordinate x del punto dato e del punto corrente
MUL EAX //Eleva al quadrato il riultato della sottrazione precedente facendo la moltiplicazione per se stesso
POP EBX //Estrae dallo stack e inserisce nel registro EBX nuovamente le coordinate del punto corrente
SHR EBX,16 //Sposta i primi 16 bit più significativi contenenti y del punto corrente nei 16 bit meno significativi
TEST BH,10000000b //Verifica se y del punto corrente è negativo
JNZ NegativoyVettore //Se y è negativo salta a NegativoyVettore dove provvede ad estendere a 1 tutti i 16 bit più significativi
Prosegui2: POP EDX //Estrae dallo stack e inserisce nel registro EDX nuovamente le coordinate del punto dato
SHR EDX,16 //Sposta i primi 16 bit più significativi contenenti y del punto dato nei 16 bit meno significativi
TEST DH,10000000b //Verifica se y del punto dato è negativo
JNZ NegativoyPunto //Se y è negativo salta a NegativoyPunto dove provvede ad estendere a 1 tutti i 16 bit più significativi
Prosegui3: SUB EDX,EBX //Effettua la sottrazione tra le coordinate y del punto dato e del punto corrente
MOV EBX,EAX //Salvaguarda il contenuto di EAX nel registro EBX
MOV EAX,EDX //Carica in EAX la differenza per predisporla alla moltiplicazione per se stessa
MUL EAX //Eleva al quadrato la differenza fra le y del punto corrente e del punto dato facendo la moltiplicazione per se stessa
ADD EAX,EBX //Somma i quadrati delle differenze tra le x e le y del punto dato e del punto corrente che rappresenta la distanza al quadrato
PUSH EAX //Salvaguarda nello stack la distanza al quadrato corrente da utilizzare per individuare quella minore
LOOP Ciclo1 //Gestione del Ciclo che ripete tutte le operazioni precedenti per ogni punto
JMP VersoFine //Salta a fine una volta terminato il ciclo e calcolati tutti i quadrati delle distanze salvaguardati nello stack
NegativoxVettore: OR EAX,11111111111111110000000000000000b //Imposta a 1 i 16 bit più significativi della componente x del punto corrente
JMP Coordinatay //Ritorna all'interno del Ciclo1
NegativoxPunto: OR EBX,11111111111111110000000000000000b //Imposta a 1 i 16 bit più significativi della componente x del punto dato
JMP Prosegui1 //Ritorna all'interno del Ciclo1
NegativoyVettore: OR EBX,11111111111111110000000000000000b //Imposta a 1 i 16 bit più significativi della componente y del punto corrente
JMP Prosegui2 //Ritorna all'interno del Ciclo1
NegativoyPunto: OR EDX,11111111111111110000000000000000b //Imposta a 1 i 16 bit più significativi della componente y del punto dato
JMP Prosegui3 //Ritorna all'interno del Ciclo1
VersoFine: MOV ECX,n //Carica nel registro ECX la dimensione n del vettore
DEC ECX //Decrementa di 1 il valore del registro ECX
MOV EDX,1 //Carica il valore 1 nel registro EDX (qui utilizzato per identificare l'indice della distanza al quadrato più piccolo)
POP EAX //Inizia l'estrazione delle distanza del quadrato per il loro conronto
Ciclo2: POP EBX //Inizio del ciclo di confronto
CMP EAX,EBX //Confronto tra le distanze corenti
JB Ritorno //Salta se la differenza delle distanze al quadrato è negativa
MOV EAX,EBX //Altrimenti scambia le due distanze in modo da mettere quella più piccola sempre in EAX
INC EDX //Calcola l'indice della distanza più piccola finora individuata e salvata in EAX
Ritorno: LOOP Ciclo2 //Ritorna al Ciclo2 per terminare i confronti delle distanze al quadrato
Fine: DEC EDX //Decrementa di 1 il valore del registro EDX per adeguarsi all'indice del vettore
MOV index,EDX //Carica l'indice trovato nella variabile index per stamparla a video
}
// Stampa su video
printf("Il punto piu' vicino a (%d,%d) e' (%d,%d) [indice=%d]\n",(short int)(Point&0xFFFF),(short int)(Point>>16),(short int)(PointSet[index]&0xFFFF),(short int)(PointSet[index]>>16),index);
}
Provate con altri punti anche quelli negativi e il programma funziona come deve. Mettendo il caso che dice il prof mi dà l'indice sbagliato. Perchè? :cry: :cry: