 
View Full Version : programma assembler elementare :(
pincopall
28-06-2004, 23:42
ciao a tutti,
sono alla disperazione...devo fare un programme in assembler per un processore intel 8051 che mi trovi il minimo tra 4 numeri e lo metta in un registro...questa è la traccia in sintesi:
A <- min(A,B,R0,R1)
il programma dovrebbe essere molto facile solo che nn riesco a fare l'if...ho provato a usare i jmp solo che cmq poi lui mi svolge l'ultima parte e quindi nn funziona :(
come diavolo si fa????
vi prego di aiutarmi...per chi ci capisce dovrebbe essere una cosa di poki minuti...ma a noi ci hanno dato da fare sto programma senza averci spiegato niente...riesco a fare gli altri ma questo con la scelta del maggiore o minore nn lo riesco a fare!
la linea che ho provato a seguire è stata quella di fare la sottrazione tra a e b...di vedere se aggiungendo 128 (lo scrivo in decimale solo per comodità) al risultato il numero andava in overflow o no...se nn andava allora a>b...altrimenti b>a...solo che cmq nn riesco a fargli prendere la decisione!
spero che qualcuno mi aiuti a fare questa cosa:(
grazie a tutti
ciao
8051 ????? Mai visto microprocessore con questa sigla... Forse è un micrcontrollore ?
Ah...trovato... Ma viene usato come microcontrollore...
http://www.cs.ucr.edu/~dalton/8051/
pincopall
29-06-2004, 00:05
Originariamente inviato da cionci 
8051 ????? Mai visto microprocessore con questa sigla... Forse è un micrcontrollore ? 
si è un microcontrollore della intel...non sai aiutarmi??
pincopall
29-06-2004, 00:15
Originariamente inviato da cionci 
No :( 
ma il linguaggio nn dovrebbe essere molto molto simile? perkè il programma x chi sa l'assembler dovrebbe essere una cosa da fare in 10 secondi :(
AnonimoVeneziano
29-06-2004, 00:22
L'assembly può essere molto diverso da chip a chip , probabilmente anche se è un chip Intel l'assembly per i8051 sarà molto diverso da quello di un qualsiasi altro chip x86 (che è l'assembly che la maggiorparte della gente qua conosce) .
Bisognerebbe avere info sulle istruzioni che questo chip riconosce , sui registri che possiede , su come usa la memoria ....
Ciao
pincopall
29-06-2004, 00:25
Originariamente inviato da AnonimoVeneziano 
L'assembly può essere molto diverso da chip a chip , probabilmente anche se è un chip Intel l'assembly per i8051 sarà molto diverso da quello di un qualsiasi altro chip x86 (che è l'assembly che la maggiorparte della gente qua conosce) .
Bisognerebbe avere info sulle istruzioni che questo chip riconosce , sui registri che possiede , su come usa la memoria ....
Ciao 
guarda io uso il copiltore della keil c51...magari lo conosci e sai cosa si può usare e cosa no...io il materiale ce l'ho, solo che nn posso scriverti il libro :(
vi prego aiutatemi che nn so che fare
Posta quello che hai scritto... Guardiamo se ti possiamo aiutare...
pincopall
29-06-2004, 01:30
Originariamente inviato da cionci 
Posta quello che hai scritto... Guardiamo se ti possiamo aiutare... 
allora...faccio un pezzo della routine molto semplificata...giusto per farvi vedere dome mi blocco :(
diciamo che devo trovare solo il minimo tra 2 numeri per comodià:
mov a,r0
mov b,r1
mov c,r2 (qui nel registro metto un numero che sarà in decimale 128, cioè un numero che sommato al risultato mi da un numero negaivo, iniziante per 1, se il risultato era positivo; mentre mi va in overflow se il risultato era negativo...in questo modo so se il risultato della differenza è maggiore o minore di 0 e quindi stabilisco se A è + grande di B o no)
subb a,r1
add  a,r2
jnc nocar1
mov a,r0
nocar1: mov a,r1
il minore lo scrivo cmq in a!
la cosa che mi frega...è che lui cmq fa sempre l'ultima operazione !mentre io vorrei invece che la facesse solo in un caso...cioè quando il carry nn c'è!
probabilmente ragiono in c++...e vorrei fare qualcosa come if/esle...solo che qua nn riesco a fargli fare una cosa o l'altra...lui le fa sempre cmq entrambe...a meno che nn fa il jump e va alla fine :(
come devo fare?
PS: se nn è chiara qualcosa (come sicuramente sarà)...ditelo che provo a spiegarvi meglio!
HELP!!!
repne scasb
29-06-2004, 09:03
pincopall
29-06-2004, 13:26
Originariamente inviato da repne scasb 
comment *
	Routine: Trovare il minimo tra 4 valori numerici
	  Input: r0,r1,r2,r3 (valori numerici da testare)
	 Output: r4 (il minimo)
     Linguaggio: Assembly Intel 8051
*
	mov	a,r0
	mov	r4,a	
	mov	a,r4
	subb	a,r1
	jc	label_01
	mov	r4,a
label_01:
	mov	a,r4
	subb	a,r2
	jc	label_02
	mov	r4,a
label_02:
	mov	a,r4
	subb	a,r3
	jc	label_03
	mov	r4,a
label_03:
	ret
 
allora sembra tutto ok...solo che alla fine c'è qualcosa che nn va...infatti nel label 2 lui l'ultima operazione che fa è quella di scrivere a in r4...dove a xò è diventata a-r3...quindi nn mi scrive il risultato del minimo ma quello della sottrazione :(
come va modificato?
repne scasb
29-06-2004, 13:33
pincopall
29-06-2004, 13:39
Originariamente inviato da repne scasb 
comment *
	Routine: Trovare il minimo tra 4 valori numerici
	  Input: r0,r1,r2,r3 (valori numerici da testare)
	 Output: r4 (il minimo)
     Linguaggio: Assembly Intel 8051
*
	mov	a,r0
	mov	r4,a	
	mov	a,r4
	subb	a,r1
	jc	label_01
	add	a,r1
	mov	r4,a
label_01:
	mov	a,r4
	subb	a,r2
	jc	label_02
	add	a,r2
	mov	r4,a
label_02:
	mov	a,r4
	subb	a,r3
	jc	label_03
	add	a,r3
	mov	r4,a
label_03:
	ret
Controllalo, non ho sottomano un emulatore 8051. 
ho già controllato :)
intanto grazie davvero...sei stato gentilissimo!
il prog funziona solo che in un caso c'è un errore...nel caso a sia il + piccolo lui alla fine del label 2 copia a in r4 dove a xò è la differenza di a-r3 e quindi sballa il risulato!
poi devo fare delle piccole modifiche ai nomi xchè il tuo programma verifica i numeri scritti da registro...mentre il mio deve prendere 2 numeri da registro e 2 da accumulatore( a e b)...e poi il risultato lo devo mettere in a e non in r4!
ma dimmi una cosa...come fa a vedere dal carry se la differenza è  positiva o negativa?
repne scasb
29-06-2004, 13:48
pincopall
29-06-2004, 13:50
Originariamente inviato da repne scasb 
gentilissima.
Il risultato (il numero piu' piccolo non sta in a, ma in r4. quindi alla fine in r4 trovi il risultato. 
label_02:
	mov	a,r4
	subb	a,r3
	jc	label_03
	mov	a,r4
è quello il problema...che alla fine io copio r4 in a...quindi ci metto il risultato sbagliato :(...metto il risultato della sottrazione precedente...ho fatto le prove al compilatore
pincopall
29-06-2004, 14:02
allora ho fatto le prove ed hai ragione...avevo sbagliato a leggere...pardon!
mi spiehi un pò come fa a capire dal carry se la differenza è un numero positivo o negativo???
altra cosa...io alla fine devo scrivere il risultato in a (così dice la traccia)...come faccio visto che a lo usi come accumulatore?
la traccia precisa è: dati A,B,r0, r1...trovare il minimo e metterlo in A.
come modifico il programma?
scusa ancora ma il prof nn è che ci ha spiegato molto e ieri ci siamo scervellati :(
pincopall
29-06-2004, 14:10
allora
scusa ma ho ricontrollato tutto e nn funziona...infatti l'ultima istruzione di ogni label copia a in r4...ma a è la differenza nno è + il numero di partenza...quindi in r4 nn mi ritrovo il numero minore la differenza!
repne scasb
29-06-2004, 14:14
repne scasb
29-06-2004, 14:17
pincopall
29-06-2004, 14:20
ok...grazie 1000 davvero di tutto...sei stata gentilissima davvero!
ora faccio tutte le prove anke se credo che con la somma torni tutto :)
grazie ancora!
ciao ciao
PS: ora vedo se riesco a cambiare il codice con i dati giusti e a far tornare il minimo in a....in caso ti richiederò aiuto :)
pincopall
29-06-2004, 14:49
niente da fare...il prog funziona se do i valori 1,2,3,4...ma se li do 4,3,2,1 lui mi da in r4 4 invece di uno...in pratica funziona solamente se i valori assegnati sono crescenti...altrimenti no...scusami ma sto veramente impazzendo dietro questo programma schifoso...non è che potresti farlo direttamente con le variabili come le mie? quindi A,B,r0,r1 e non r1,r2,r3,r4...il risultato va in A e non in r4...sto davvero impazzendo!!!
pincopall
29-06-2004, 15:37
allora ho modificato il codice in base alla traccia ...vedi un pò se secondo te è giusto!
	mov	r2,a
	mov 	r3,b
	mov	a,r2
	mov	r4,a	
	mov	a,r4
	subb	a,r3
	jc	label_01
	mov	r4,b
label_01:
	mov	a,r4
	subb	a,r0
	jc	label_02
   	add 	a,r0
	mov	r4,a
label_02:
	mov	a,r4
	subb	a,r1
	jc	label_03
	add	a,r1
	mov	r4,a    
label_03:
	mov	a,r4
	ret
ho fatto diverse prove e pare andare tutto bene...c'è solo una cosa che nn capisco...come faccio ad assegnare ad un registro un numero negativo?
xchè volevo vedere se mettendo un numero negativo mi portava quello come minore...ma ho come l'impressione che lui lo veda come numero grande e mi riporta il + piccolo tra i positivi!
posso usare solo 2 cifre in esadecimale ai registri...io ho messo il numero ff ad uno dei registri pensando che fosse negato...ma pare che lui lo tratti come positivo!
come funziona questa storia??
Non conosco questo assembly, ma ci posso provare:
mov r4, a
mov r3, b
subb a, r3
jc label01
mov r4, b
label01:
mov a, r4
subb a, r0
jc label02
mov a, r0
mov r4, a
label02:
mov a, r4
subb a, r1
jc label03
mov a, r1
mov r4, a
label03:
ret ***in r4 c'è il sirultato***
Avevo fatto un errore, ho corretto ;)
magari ............dai un occhiata qui (http://www.8052.com/tutintro.phtml)
Ho visto che ci deve essere l'accomulatore... Un attimo... Correggo...
pincopall
29-06-2004, 15:57
Originariamente inviato da cionci 
Non conosco questo assembly, ma ci posso provare:
mov r4, a
mov r5, r4
mov r3, b
subb r5, r3
jc label01
mov r4, b
label01:
mov r5, r4
mov r3, r0
subb r5, r3
jc label02
mov r4, r0
label02:
mov r5, r4
mov r3, r1
subb r5, r3
jc label03
mov r4, r1
label03:
ret ***in r4 c'è il sirultato*** 
nn puoi fare operazioni da registro a registro...da errore nella sintassi....devi fare da registro ad accumulatore o viceversa!
idem per la sottrazione
Corretto... Un attimo che riguardo...
pincopall
29-06-2004, 15:59
cmq con il codice che ho postato io prima se nei regestri metto valori positivi allora funziona bene...ma se metto anke solo un numero negativo sballa...xchè????????????????
PS...a e b li definisco all'inizio insieme ai registri ovviamente!
Corretto:
mov r4, a
mov r3, b
subb a, r3
jc label01
mov r4, b
label01:
mov a, r4
subb a, r0
jc label02
mov a, r0
mov r4, a
label02:
mov a, r4
subb a, r1
jc label03
mov a, r1
mov r4, a
label03:
ret ***in r4 c'è il sirultato***
pincopall
29-06-2004, 16:08
Originariamente inviato da cionci 
Corretto:
mov r4, a
mov r3, b
subb a, r3
jc label01
mov r4, b
label01:
mov a, r4
subb a, r0
jc label02
mov a, r0
mov r4, a
label02:
mov a, r4
subb a, r1
jc label03
mov a, r1
mov r4, a
label03:
ret ***in r4 c'è il sirultato***  
ok...questo sembra funzionare bene...solo che il risultato mi serve meterlo in a e non in r4...come fare? :(
PS: qualcuno mi sa dire xchè il mio sballava mettendo risultati negativi?
In fondo fai un mov a, r4 ;)
pincopall
29-06-2004, 16:16
Originariamente inviato da cionci 
Corretto:
mov r4, a
mov r3, b
subb a, r3
jc label01
mov r4, b
label01:
mov a, r4
subb a, r0
jc label02
mov a, r0
mov r4, a
label02:
mov a, r4
subb a, r1
jc label03
mov a, r1
mov r4, a
label03:
ret ***in r4 c'è il sirultato***  
uff...ho provato anke qui ad inserire un numero negativo in un registro...ossia ff...che dovrebbe risultare il minore...ma il minore risulta sempre il + piccolo tra i positivi...xchè?????????
pincopall
29-06-2004, 18:00
ragà ho il fumo che esce da tutte le parti ormai...dopo 2 giorni sono andato in tilt completo!
entrambi i programmi funzionano...solo che hanno lo stesso identico difetto...che se nei registri metto tutti numeri positivi o tutti numeri negativi funzionano benissimo...ma se metto un numero negativo (o più) fa in tilt...nel senso ke come minore mi da il numero + piccolo tra i positivi...come se il numero negativo fosse + grande!
quello che nn capisco e xchè quando lui fa 3-(-5) scrive nel registro 07 ( intanto dovrebbe fare 08...mah) e poi fa il salto (quindi lo prende come se fosse un numeo negativo) e scrive nel registro 3 invece che -5!
xchè cavolo fa il salto se gli esce un numero positivo (che poi è 8 e nn sette nn ho capito manco questo....viene sempre un numero scalato di 1) mentre lo dovrebbe fare solo con una differenza negativa?????????????????????????????????
qualcuno mi illumini...ormai sono completamente fuso a furia di farmi operazioni in esadecimale :(
repne scasb
29-06-2004, 18:26
pincopall
29-06-2004, 20:19
Originariamente inviato da repne scasb 
Nell'8051 i numeri negativi sono dati da |0-n|. Ossia -1 equivale a 255, -17 equivale a 239. Quindi se vuoi che il software possa funzionare anche con i numeri negativi devi prima di ogni confronto devi sommare 128 al registro da controntare. Chiaramente il risultato deve essere decrementato di 128 (funzionera solo con numeri compresi tra -128 e +127). 
come venivano rappresentati i numeri lo sapevo, infatti se metto nei registri iniziali solo numeri negativi il programma funziona bene, nn capisco xchè invece non succeda tra un numero positivo e uno negativo!
quello che dici tu funziona se hai da confrontare un numero positivo e uno negativo...ma se confronto 2 numeri positivi poi sballerebbe!
questo è quello che penso...anke se onestamente non capisco xchè quando lui fa 2-(-3)...scrive come risultato 5...ma poi lo conta come se fosse un numero negativo e sballa le operazioni!
se ho sbagliato a raglionare...mi potresti fare l'esempio e dire dove sbaglio???
cmq sei davvero gentilissima...grazie di tutto!
PS: al mio amico che doveva fare il programma x prendere il max l'ho fatto sulla base del mio con il jnc al posto del jc e modificando poke altre cose...solo che anke lì abbiamo lo stesso identico problema :(
mmx[ngg]
30-06-2004, 03:25
acall Get?Min
mov   a,  r1
acall Get?Min
mov   a,  b
acall Get?Min
mov   a,  r0
ret
GetUMin:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetUMin
	mov a, r7
	mov r0, a
EndGetUMin:
	ret
GetSMin:
	jb acc.7, Signed
	xch a, r0
	jnb acc.7, Compare
	mov r0, a
	ret
Signed:
	xch a, r0
	jnb acc.7, EndGetSMin
Compare:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetSMin
	mov a, r7
	mov r0, a
EndGetSMin:
	ret
Sostituisci il ? con U x i numeri senza segno e S per quelli segnati....dovrebbe funzionare (provalo bene però xke non ho mai usato questo asm e non l'ho nemmeno compilato)...se cmq non bastasse vai qui (http://www.8052.it)
pincopall
30-06-2004, 12:57
Originariamente inviato da mmx[ngg] 
acall Get?Min
mov   a,  r1
acall Get?Min
mov   a,  b
acall Get?Min
mov   a,  r0
ret
GetUMin:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetUMin
	mov a, r7
	mov r0, a
EndGetUMin:
	ret
GetSMin:
	jb acc.7, Signed
	xch a, r0
	jnb acc.7, Compare
	mov r0, a
	ret
Signed:
	xch a, r0
	jnb acc.7, EndGetSMin
Compare:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetSMin
	mov a, r7
	mov r0, a
EndGetSMin:
	ret
Sostituisci il ? con U x i numeri senza segno e S per quelli segnati....dovrebbe funzionare (provalo bene però xke non ho mai usato questo asm e non l'ho nemmeno compilato)...se cmq non bastasse vai qui (http://www.8052.it) 
troppe chiamate...io al max posso usa il jump...nn posso fare dei sottoprogrammi proprio!
:(
mmx[ngg]
30-06-2004, 13:07
Xke no ?
Le call sono supportate dall'MCS51 o è un obbligo ke ti viene imposto ?
pincopall
30-06-2004, 15:08
Originariamente inviato da mmx[ngg] 
Xke no ?
Le call sono supportate dall'MCS51 o è un obbligo ke ti viene imposto ? 
si questo lo so che le supporta...solo che nn posso farlo io x come mi è stato posto l'esercizio :(
cmq dopo ore ed ore di rincoglionimenti sono giunto ad uno conclusione che nn avevo capito!
quando io inserisco nei registri un numero...lui nn vede se è positivo o negativo...vede solo numeri da 0a 256 (ma scritti in esadecimale quindi da 0 a ff) e quando io penso di scrivere in complemento a 2 un numero negativo...e quindi cerco di scrivere -1 come 255 lui vede cmq 255...quindi quando gli dico di scegliere (tramite sottrazione) se prendere 20 oppure -1 lui effettivamente vede 20 e 255....quindi ovviamente prende 20!
ora come faccio a fargli capire che io voglio lavorare con numeri da -128 a 127????!!!!?!?!?
c'è un modo?
spiegati meglio.......... vuoi poter lavorare con i numeri relativi, giusto?
Nonho leto bene ........... ma non ti avevano detto che bastava aggiungere 128 al numero???
Ho letto male?? Sono fumato?? ^_^
pincopall
30-06-2004, 16:13
Originariamente inviato da Luc@s 
spiegati meglio.......... vuoi poter lavorare con i numeri relativi, giusto?
Nonho leto bene ........... ma non ti avevano detto che bastava aggiungere 128 al numero???
Ho letto male?? Sono fumato?? ^_^ 
si ma il problema è che lui non associa al numero 255 il numero -1!!! quindi per lui 255 vale 255...sono io che devo trovare l'algoritmo per faf funzionare le cose...che poi se a 7 aggiungi 128 diventa un numero negato è un'altra cosa...a parte che per avere -7 devi fare il complemento a 2!
cmq il problema ripeto sta nel fatto che lui non lavora in complemento a2 ma vede i numero così come sono, da o a 255 e non da -128 a 127!
mmx[ngg]
30-06-2004, 16:32
Come hai già detto te, sull'MCS51 non c'è il supporto diretto ai numeri segnati ma devi gestirteli a manina via codice.
Il codice te l'ho postato sopra...se non puoi utilizzare le call devi semplicemente espanderle...un pò di fantasia :)
Cmq....
Originariamente inviato da pincopall 
ora come faccio a fargli capire che io voglio lavorare con numeri da -128 a 127????!!!!?!?!?
c'è un modo? 
*** Valido x numeri non segnati (0..255) ***
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetUMin_A
	mov a, r7
	mov r0, a
EndGetUMin_A:
	mov a,  r1
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetUMin_B
	mov a, r7
	mov r0, a
EndGetUMin_B:
	mov a, b
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetUMin_C
	mov a, r7
	mov r0, a
EndGetUMin_C:
	mov a, r0
	ret
*** Valido x numeri segnati (-128..127) ***
	jb acc.7, Signed_A
	xch a, r0
	jnb acc.7, Compare_A
	sjmp AsnGetSMin_A
Signed_A:
	xch a, r0
	jnb acc.7, EndGetSMin_A
Compare_A:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetSMin_A
	mov a, r7
AsnGetSMin_A:
	mov r0, a
EndGetSMin_A:
	mov a, r1
	jb acc.7, Signed_B
	xch a, r0
	jnb acc.7, Compare_B
	sjmp AsnGetSMin_B
Signed_B:
	xch a, r0
	jnb acc.7, EndGetSMin_B
Compare_B:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetSMin_B
	mov a, r7
AsnGetSMin_B:
	mov r0, a
EndGetSMin_B:
	mov a, b
	jb acc.7, Signed_C
	xch a, r0
	jnb acc.7, Compare_C
	sjmp AsnGetSMin_C
Signed_C:
	xch a, r0
	jnb acc.7, EndGetSMin_C
Compare_C:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetSMin_C
	mov a, r7
AsnGetSMin_C:
	mov r0, a
EndGetSMin_C:
	mov a, r0
	ret
Visto ke non ho la certezza ke funzioni (non posso neanke compilarlo) provalo e poi dimmi (cmq mi sembra strano ke non puoi, da esercizio, utilizzare le call.....)
pincopall
30-06-2004, 18:38
Originariamente inviato da mmx[ngg] 
Come hai già detto te, sull'MCS51 non c'è il supporto diretto ai numeri segnati ma devi gestirteli a manina via codice.
Il codice te l'ho postato sopra...se non puoi utilizzare le call devi semplicemente espanderle...un pò di fantasia :)
Cmq....
*** Valido x numeri non segnati (0..255) ***
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetUMin_A
	mov a, r7
	mov r0, a
EndGetUMin_A:
	mov a,  r1
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetUMin_B
	mov a, r7
	mov r0, a
EndGetUMin_B:
	mov a, b
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetUMin_C
	mov a, r7
	mov r0, a
EndGetUMin_C:
	mov a, r0
	ret
*** Valido x numeri segnati (-128..127) ***
	jb acc.7, Signed_A
	xch a, r0
	jnb acc.7, Compare_A
	sjmp AsnGetSMin_A
Signed_A:
	xch a, r0
	jnb acc.7, EndGetSMin_A
Compare_A:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetSMin_A
	mov a, r7
AsnGetSMin_A:
	mov r0, a
EndGetSMin_A:
	mov a, r1
	jb acc.7, Signed_B
	xch a, r0
	jnb acc.7, Compare_B
	sjmp AsnGetSMin_B
Signed_B:
	xch a, r0
	jnb acc.7, EndGetSMin_B
Compare_B:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetSMin_B
	mov a, r7
AsnGetSMin_B:
	mov r0, a
EndGetSMin_B:
	mov a, b
	jb acc.7, Signed_C
	xch a, r0
	jnb acc.7, Compare_C
	sjmp AsnGetSMin_C
Signed_C:
	xch a, r0
	jnb acc.7, EndGetSMin_C
Compare_C:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetSMin_C
	mov a, r7
AsnGetSMin_C:
	mov r0, a
EndGetSMin_C:
	mov a, r0
	ret
Visto ke non ho la certezza ke funzioni (non posso neanke compilarlo) provalo e poi dimmi (cmq mi sembra strano ke non puoi, da esercizio, utilizzare le call.....) 
sei un grande....funziona...ho provato...ora me lo stampo e me lo guardo per bene che con una prima okkiata velocissima nn ci ho capito molto...ora me lo studio per bene e se ho domande da farti poi posto ok?
cmq grazie davvero a te e a tutti...siete grandi :)
pincopall
30-06-2004, 19:00
ehm...una cosa al volo...ma il primo passaggio a cosa serve? lui controlla se nell'accumulatore c'è un numero positivo o negativo...ma nell'accumulatore ci sarà sempre 0 all'inizio no???
cmq...scusa se ne approfitto un pò...ma per sicurezza mi potresti scrivere cosa fa affianco ad ogni passaggio?!? molto sinteticamente, giusto per non avere dubbi :)
cmq di funzionare funziona...questo è sicuro...ora vado a studiarmelo un pò :)
mmx[ngg]
30-06-2004, 19:12
Originariamente inviato da pincopall 
ehm...una cosa al volo...ma il primo passaggio a cosa serve? lui controlla se nell'accumulatore c'è un numero positivo o negativo...ma nell'accumulatore ci sarà sempre 0 all'inizio no???
No....almeno...tu hai scritto : 
A = Min(A, B, R0, R1)
Quindi A all'inizio deve essere valorizzato
cmq...scusa se ne approfitto un pò...ma per sicurezza mi potresti scrivere cosa fa affianco ad ogni passaggio?!? molto sinteticamente, giusto per non avere dubbi :)
cmq di funzionare funziona...questo è sicuro...ora vado a studiarmelo un pò :) 
Io ti propongo un'altra soluzione....commenta il codice e se sbagli ti correggo...è il metodo migliore x imparare a ragionare ;)
mmx[ngg]
30-06-2004, 23:56
Giusto x completezza e visto ke il codice ke ho postato (senza l'uso delle call) mi fà un pò cagare, ti passo questo ke 'dovrebbe' fare la stessa cosa ma è un attimino + compatto (usa lo stack)
	push acc
	push b
	mov a, r1
	push acc
	mov r6, #3
GetSMin:
	pop acc
	jb acc.7, Signed
	xch a, r0
	jnb acc.7, Compare
	sjmp AsnGetSMin
Signed:
	xch a, r0
	jnb acc.7, EndGetSMin
Compare:
	mov r7, a
	clr c
	subb a, r0
	jnc EndGetSMin
	mov a, r7
AsnGetSMin:
	mov r0, a
EndGetSMin:
	djnz r6, GetSMin
	mov a, r0
	ret
P.S.
Si può fare push r1 ? se si modifica il codice :)
pincopall
01-07-2004, 15:20
allora....ho da chiederti due cose...una sul codice vekkio e una sul nuovo!
nel vekkio io assegno un valore ad a quando inizializzo i registri scrivendo
mov a,#xxxh dove xxx sta per il numero ma ho fatto compilare il programma passo passo e quando lui fa la prima azione quindi il jz acc7 vede in acc il valore 000...onestamente nn ho capito il xchè :( anke xchè poi il programma funziona!
x il secondo codice invece...che mi sembra molto compatto, elegante e funzionale( ti sembrerà strano ma stavo provando anke io a farlo con il push e pop solo che essendo alle prmie armi non è che riuscivo a farlo proprio bene !) non capisco xchè ad un certo punto scrivi mov r6, #3....xchè metti il valore 3 in r6??? a cosa serve???
pincopall
01-07-2004, 16:15
ok scusa...mi rispondo da solo :)
il 3 xchè lui fa 3 cicli...ogni volta decrementa quel valore in modo da fermare tutto quando arriva a zero...e a quel punto scrive il valore + piccolo che ha al momento!
se nn ho capito male quindi lui inizia i confronti dalla fine, cioè da r1 e r0...po il minore lo confronta con b e poi il minore con a!
i confronti li fa a seconda che ci siano numeri positivi o negativi!
mi pare di aver capito bene il programma...cmq per sicurezza ora scrivo affianco ad ogni azione quello che credo faccia e poi ti posto tutto...così vediamo se c'è qualcosa che ho capito male!
grazie di tutto...sei stato gentilissimo...ringrazio anche tutti gli altri che mi hanno aiutato :)
pincopall
01-07-2004, 16:58
ecco qui la mia idea sul programma :)
	push acc		; salva nello stack il contenuto di a
	push b			; salva nello stack il contenuto di b
	mov a, r1		; mette r1 in a
	push acc		; salva nello stack il contenuto di a (r1)
	mov r6, #3		; 3 xchè è il numero di cicli che vengono effettuati
GetSMin:
	pop acc			; recupera dallo stack l'ultimo valore caricato,quindi r1
	jb acc.7, Signed;	; se r1 è un numero negativo salta a signed (verifica il bit + significativo)
	xch a, r0		; scambia i valori tra  a(r1) ed r0
	jnb acc.7, Compare	; salta a signed se a (r0) è un numero positivo
	sjmp AsnGetSMin		; salta a asngetmin (xchè salto corto????)
Signed:
	xch a, r0		; scambia i valori tra  a ed r0
 	jnb acc.7, EndGetSMin	; salta a endgetmin se r0 è un numero positivo
Compare:
	mov r7, a		
	clr c			; cancella in carry
	subb a, r0		; fa la differenza tra a (r0) e r0(r1) e mette il risultato in a
	jnc EndGetSMin		; salta a endgetmin se la differenza è un numero positivo 
	mov a, r7		; mette r7 in a
AsnGetSMin:
	mov r0, a		; mette a in r0
EndGetSMin:
	djnz r6, GetSMin	; decrementa r6 (3) e salta a getsmin 
	mov a, r0		; pone il risultato in a
	ret
tra parentesi c'è la vera corrispondeza ai registri iniziali ovviamente solo nel primo ciclo!
mi pare che il programma sia ottimo, compatto...e mi pare di aver capito esattamente la logica...cosa che invece ancora nn ho bel chiara del primo codice che mi avevi dato, senza push e pop!
dammi la conferma delle mie idee...e saremo tutti contenti, soprattutto io :)
ho modificato...l'unica cosa che nn mi è chiara è la differenza tra jmp e sjmp! che differenza c'è tra salto e salto corto???
con jmp funzionerebbe lo stesso?
mmx[ngg]
01-07-2004, 22:11
Se fai un confronto istruzione x istruzione tra il codice senza le call e quello con l'uso dello stack ti accorgerai ke sono praticamente la stessa cosa :)
Semplicemente nel primo sono ripetute x 3 volte le stesse istruzioni (cambia ovviamente il nome delle label)
X renderti meglio l'idea ragiona in questo modo....l'algoritmo in tutte le 3 versioni semplicemente confronta il valore dell'accumulatore solo e sempre con il registro r0 nel momento in cui questo risulta maggiore di a ne eredita il valore. Successivamente nell'accumulatore viene mosso il prossimo valore e il tutto riparte dall'inizio :)
Poi...
JMP occupa 1 byte e salta all'indirizzo calcolato dalla somma di A + DPTR
LJMP occupa 3 bytes e permette di saltare in qualsiasi punto all'interno dei 64k (1 byte x l'istruzione e 2 x l'indirizzamento)
SJMP occupa 2 bytes ed effettua un indirizzamento relativo di massimo -128 o +127 bytes rispetto al punto di partenza (1 byte x l'istruzione e 1 x l'indirizzamento)
pincopall
02-07-2004, 00:08
Originariamente inviato da mmx[ngg] 
JMP occupa 1 byte e salta all'indirizzo calcolato dalla somma di A + DPTR
SJMP occupa 2 bytes ed effettua un indirizzamento relativo di massimo -128 o +127 bytes rispetto al punto di partenza (1 byte x l'istruzione e 1 x l'indirizzamento) 
sta cosa ancora nn mi è chiara...che è l'indirizzamento relativo? 
ho controllato sul manuale e dice le tue stesse parole...solo che ancora nn ho capito il significato...jmp salta ad una parte di programma...sjmp oltre a saltare a quella parte cosa fa in pratica???
se io al posto di sjmp mettessi jmp nel programma cosa cambierebbe???
mmx[ngg]
02-07-2004, 02:46
Originariamente inviato da pincopall 
sta cosa ancora nn mi è chiara...che è l'indirizzamento relativo? 
ho controllato sul manuale e dice le tue stesse parole...solo che ancora nn ho capito il significato...jmp salta ad una parte di programma...sjmp oltre a saltare a quella parte cosa fa in pratica???
se io al posto di sjmp mettessi jmp nel programma cosa cambierebbe??? 
Entrambe le istruzioni fanno un salto ma lo fanno in modo diverso...
Dunque....se metti jmp al posto di sjmp non funziona + una sega :D
Xke jmp punta / sposta l'esecuzione in un punto ke nel nostro caso è indefinito....l'accumulatore è un valore a caso e DPTR non l'abbiamo mai valorizzato....quindi dove punta ????
L'indirizzamento relativo invece te lo spiego con un esempio ke è meglio :
Indirizzo   Istruzione
000         mov a, r1
001         mov b, r2
002         push acc
004         push b
006         sjmp @AZZ
008         mov a, r3
009         @AZZ:
009         pop b
00B         pop acc
00D         .....
Il codice parte dall'indirizzo 0
Ogni istruzione è posizionata ad un certo indirizzo ke è incrementato in base al numero di bytes di ogni istruzione
SJMP si trova all'indirizzo 006
Il compilatore cerca la label AZZ e fa :
Indirizzo di SJMP + 2 (ke è il numero di bytes dell'istruzione) - l'indirizzo della label AZZ....quindi 3
Il compilato sarà opcode di SJMP + 3
A runtime quando arrivi all'istruzione SJMP sei all'indirizzo 6 e il microcontrollore fà 6 + 3 a salta all'indirizzo 9 :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.