poradite mi se zacatecnickym prog?

ted koukam - pod návěštím “start” mam chybu ve 2 komentarich - ty adresy nemaj bejt 31h, ale 40h :wink: takhle to vypada, kdyz neco napisete, a pak do toho dodelavate dalsi veci :slight_smile:

asi se budu muset zaregistrovat, abych si to mohl po sobe opravovat :unamused:

radsi se neregistuj to bych te pak otravoval pres SZ :wink: jinac program puvodne mel z peti hodnot (se znamenkem)z vnitrni pameti vybrat maximum a to ulozit do vnejsi pameti… kazdopadne oba tvoje prispevky mi pomohly… :stuck_out_tongue: termin sice nestiham ale aspon na priste to snad priblizim realite…
A jeste jednou Dekuju… :open_mouth:

pozde, uz jsem reglej :laughing:

Jinak princip vyberu nejvetsiho cisla je podobnej, akorat nebudes porad dokola nacitat obe cisla - urcis si pevnou pormennou, tam nactes 1. cislo a to pak budes jen porovnavat s tema dalsima a kdyz bude nejaky vetsi, tak ho tam soupnes… do externi pameti ho potom presunes napr. pomoci MOVX @r1,A nebo MOVX @DPTR,A kde bude v cilovych registrech adresa v externi pameti, kam to budes chtit zapsat :wink:

Pokud jde o znamenko, zalezi v jakem formatu jsou cisla ulozena… v pripade doplnkoveho kodu budes muset na x51 trochu premejslet… 8) u avr by to bylo jednodussi, ty uz maji podporu znamenkovejch cisel…

Taky jsem si ve tvem kodu vsim, ze se pokousis pouzivat registry DPTR pro vselijake operace - to jsou pouze ADRESOVE registry a pro nic jineho by byt vyuzivany nemely… ikdyz se v urcitych pripadech daji pouzit pro predavani parametru do podporgramu :wink:

Ted mam mnoho prace s ostatnim takze na tohle se vrhnu prozmenu o vikednu uz se na to tesim :laughing: Musim to nejak sesmolit pac to mam ve stredu odevzdat i s tema znamynkama :wink: wish me good luck! :wink: pripadne se jeste na neco zeptam :blush:

dobra :slight_smile: jen si musis napred ujasnit, jakej format pro zaporny cisla budes pouzivat… jak jsi v uvodu napsal neco jako “x0 equ -2”, to nelze pouzit, procesor zadny znamenko “-” nezna :wink:

pro cely zapolny cisla se pouzivaj dva formaty:

  1. nevim, jak se jmenuje, ale roli znamenka zde zastava nejvyssi bit, tedy napriklad +2 je jako “00000010” a -2 je pak “10000010”
    vtipny je, ze tento format ma 2 nuly - kladnou a zapornou :slight_smile:

  2. doplnkovy format, nejvyssi bit je zde vlastne taky znamenko, ale zde je to spis vedlejsi efekt. Hlavni rozdil je ten, ze cisla 0~127 odpovidaji dekadickym kladnym cislum, a cisla 128 - 255 zastavaji zaporna cisla -128 ~ -1 (255 = -1) Tento druhy format ma urcite vyhody pri vypoctech a ma o 1 vetsi rozsah :wink:

Teprve podle toho, ktery mas zadany, nebo ktery si vyberes, se pak muze resit, jak dal :wink:

akorat behem soboty ti tu nepomuzu - jedu kalit :wink:

S takovým formátem jsem se ještě nikdy nesetkal a silně pochybuju, že by takový formát měl v nějaké implementaci oporu.
Používá se prakticky jediný, kde záporná čísla jsou vyjádřena jako doplněk do přetečení registru. Např. číslo -2 je vyjádřeno jako 256-2= 254. Kladná čísla jsou vyjádřena stejně jako unsigned, ale jen do 127 včetně. Bit 7 vyjadřuje znaménko: 0 - kladné číslo, 1 - záporné.
Hlavní přednost tohoto formátu je, že lze použít stejné instrukce pro signed nebo unsigned operandy. Překroční rozsahu se kontroluje příznakem carry pro unsigned nebo overflow pro signed.

Ještě exituje jeden formát, který se používa např. u ADC. Číslelná osa je posunuta o polovinu jejího rozsahu. Pro byte 0 odpovídá hodnota 128, 1 odp. 129 a -1 odp. 127. Odečtemí hodnoty 128 vznikne předchozí formát.

Pro porovnání dvou čísel signed byte lze použít pouze instrukci SUBB (jiná nenastavuje OV). Mezi OV a Acc.7 se provede XOR a podle toho se určí, zda je výsledek rozdílu kladný nebo záporný. Kladný výsledek znamená, že 1. operand je větší.

pouziva se to pro ulozeni mantisy realnych cisel a neexistuje nic, co by mohlo nekomu branit toto pouzit i pro cela znamenkova cisla…

Ze jste se s necim nesetkal neznamena, ze to neexistuje :wink:

Co se tyka doplnkoveho formatu, jsem rad, ze jste potvrdil muj predesly prizpevek ohledne fakticke spravnosti 8)

To je skvělý nápad takto radit tazateli, který se snaží pochopit porovnání celých čísel, a vysvětlovat mu floating point!!! Jen bych rád věděl, jak mu vysvětlíš, jakou direktivou má překladač donutit, aby např, konstantu -2 přeložil dle tvého formátu. Pokud napíšeš např. MOV A,#-2 překladač to přeloží jako MOV A,#254.
Tedy aby bylo jasno, neexistují 2 fomáty pro celá čísla, ale jen jediný a pro něj je ALU procesoru uzpůsobena (viz. příznaky přetečení). Vymýšelní nestandartních formátů povede ke komplikovaným algorytmům a překladače včetne IDE je nebudou schopny správně interpretovat.
Floating point je kapitola sama pro sebe a nemá smysl o ní zde diskutovat.

zadny donucovani prekladace mu nemam v umyslu vysvetlovat, a uz vubec nemam v umyslu tady nekomu vysvetlovat ulozeni realnych cisel v pameti… Az by na to prislo, rovnou bych mu rekl, ze je lepsi doplnkovej format, protoze se s nim lip pocita…

Ale nezalezi na tom, co bysme radsi, ale na jeho zadani… ve skole mu nejakej format museli popsat (nejspis prave doplnkovej) a ten bude muset pouzit.

Ale primej format proste existuje at se vam to libi nebo ne… a neni to nic nestandardniho.

Nejde o to, jestli se mi něco líbí nebo ne. Spolu můžeme vymyslet ještě dalších 10 formátů, ale nebude je možné používat na současných procesorech a tím bude jejich existence odsouzena k zániku.
MCU51 má pouze 2 formáty: doplňkový (jak si jej nazval) a BCD. Ten ale nemůže být se znaménkam, takže jej můžeme hned vyloučit a zbyde jen jediný.
Pokud bys chtěl sčítat přímý formát na 51, tak vyjde
MOV A, #0b10000010 ;-2
ADD A, #0b00000011 ;+3
výsledek 0b10000101, což je -5. To je přeci nesmysl. Negenerují se patřičně příznaky CY a OV, takže podle čeho provádět případnou korekci a jak poznat, že výsledek je mimo rozsah. Formát je dán samotným procesorem, resp. jeho ALU (artimeticko logická jednotka) a né programátorem.
A ještě maličkost k těm reálným číslům. Jsou to čísla jako např. pi, sqrt(2), e (základ přirozeného logaritmu) atd. a nelze je uložit do paměti. Nelze je ani vyjádřit v dekadickým nebo binárním formátu, ale to by vám měli páni profesoři na škole vysvětlit. Floating point je něco jiného. Je to formát s pohyblivou řádovou čárkou a nelze ho nahradit int nebo __int64. Celočíselné proměné selhávají v jistých matemetických operací a výsledky jsou značně nepřesné. Např. podíl celých čísel 23/24 = 0, což je chyba jak prase.

Proti tomu, ze se s doplnkovym formatem pocita snadneji samozrejme nic nenamitam a uvedeny priklat to jen potvrzuje :wink:
Co je floating point vim velice presne (dle normy IEEE 754) a jakekoli cislo (v jeho rozsahu a presnosti) do neho dokazu za par minut na papire prevest… To, ze tomu rikam realne cislo je jen slovickareni. Ikdyz je pravda, ze je to nepresne, protoze cisla s neukoncenym desetinnym rozvojem nejdou vyjadrit uplne presne. Ted me tak napada, FP vlastne neumi vyjadrit presne ani mnoho celych cisel :confused:

Nez dohadovani se o slovickach by me spis zajimalo, jak se dari LL :slight_smile:

Formát čísla je jednoznačně dán programátorem. Je plně v mojí kompetenci, jaké kódování použiji. Jednotkový doplněk, dvojkový doplněk… nebo nějaký jiný kód. Pokud má ALU signalizaci přenosu a výpůjčky a umí sčítat a negovat, pak jsem schopen počítat v oboru celých čísel, reálných čísel atp. Pokud ALU podporuje například operace v BCD nebo plovoucí čárce, tak to může být přínos, ale není to nezbytné.

Ano. Programátor si může určit jakýkoliv formát, ale v okamžiku, kdy bude chtít čísla sečíst, bude je muset převést na standatrní formát a pak součet převádět zpět do původního formátu. To je kontraproduktivní.

Já taky. Stačí jen ty příznaky a sčítaní. Negace je complement+ increment. Ale když už tu vedemte takovou akademickou debatu, přemýšlejte jak se dají nahradit chybějící příznaky half carry u 32b procesoru tak, aby bylo možné pracovat s 8 místným BCD kódem. Je to možné nebo ne?

Joj tak jsem splodil neco velice neprofesionalniho ale vesmes efektivniho :wink: pro zajimaovst zde


	   x0 equ 4
	   x1 equ 5
	   x2 equ 6
	   x3 equ 7
	   x4 equ 8


start:   		  	  		 
		  call 	porovnej0s1   

porovnej0s1: 
			push Acc
			MOV 	a,#x0 
			CLR 	c		
			subb 	a,#x1	 ;porovnani #x0#x1 
			jnc		porovnej0s2 
			call	porovnej1s2
			pop acc
porovnej0s2:
			push acc
			MOV 	a,#x0 
			CLR 	c		; vymazani carrybitu 
			subb 	a,#x2	 ;porovnani #x0#x2 
			jnc	 porovnej0s3 
			call	 porovnej2s3
			pop acc
porovnej0s3:
			 push acc	
			MOV 	a,#x0 
			CLR 	c		
			subb 	a,#x3	 ;porovnani #x0#x3 
			jnc	 porovnej0s4
			call	 porovnej3s4
			 pop acc
porovnej0s4:
			push acc
			MOV 	a,#x0 
			CLR 	c		
			subb 	a,#x4	 ;porovnani #x0#x1 
			jnc	zapisX0jakomax 
			call	zapisX4jakomax		
			 pop acc

porovnej1s2:
 			 push acc
		   MOV 	a,#x1 
			CLR 	c		
			subb 	a,#x2
			jnc		porovnej1s3	; IF 2 > 1 	 GO 2s3
			call	porovnej2s3	   ;if 1>2 go 1s3
			  pop acc
porovnej1s3:
 			push acc
		   MOV 	a,#x1 
			CLR 	c		
			subb 	a,#x3
			jnc		porovnej1s4	 ;If 3>1 go 3s4
			call	porovnej3s4		;If 1>3 go 1s4
			 pop acc
porovnej1s4:
 		 	push acc		
		   MOV 	a,#x1 
			CLR 	c		
			subb 	a,#x4
			jnc		zapisX1jakomax	 ;If 4>1 GO ZAPISS4jakomax
			call	zapisX4jakomax     ;If 1>4 zapisX1jakomax
			  pop acc
porovnej2s3:
 			push acc
		   MOV 	a,#x2 
			CLR 	c		
			subb 	a,#x3
			jnc		porovnej2s4		;If 3>2 go 3s4
			call	porovnej3s4		; if 2>3 go 2s4
			 pop acc
porovnej2s4:
 			 push acc
		   MOV 	a,#x2 
			CLR 	c
			subb 	a,#x4
			jnc		zapisX2jakomax	 ; If 4>2 GO ZAPISS4jakomax 
			call	zapisX4jakomax ;If 2>4 zapisX1jakomax
			 pop acc
porovnej3s4:
 			push acc
		   MOV 	a,#x3 
			CLR 	c		
			subb 	a,#x4
			jnc		zapisX3jakomax	 ; If 4>3 GO ZAPISS4jakomax 
			call	zapisX4jakomax ;If 3>4 zapisX3jakomax
			 pop acc

zapisx0jakomax:	
				MOV DPL,#x0
				jmp konec
zapisx1jakomax:	 
				MOV DPL,#x1
				jmp konec
zapisx2jakomax:
				MOV DPL,#x2
				jmp konec
zapisx3jakomax:
				MOV DPL,#x3
				jmp konec
zapisx4jakomax:
				MOV DPL,#x4
				jmp konec
konec:  jmp konec								 ; 
end

ted uz jen poresit ty znamenka :blush: ty mne na tom vsem opravdu “stvou” :wink:
mj moje mzateny komenty jsem se snazil vymazat :stuck_out_tongue: nektery tam zustaly… ale pro vas stejne jsou bezpredmetny ;p

Jinak vam vsem moc diky za rady a napady urcite mi to pomaha :blush: :exclamation:

Tak tenhle kousek kódu povede k nekontrolovatelnému přetečení zásobníku. Instrukce pop Acc nesmí být podmíněna instrukcí JNC, když je před ní nepodmíněná PUSH Acc. Asi label “porovnej0s2” má být před POP Acc.

jj, v delsim programu toto byt nesmi (v takto kratkem by to jeste nebyl problem, protoze se to projde jen 1x). Tady ale push a pop nepotrebujes vubec, protoze to, co mas v Acc po porovnani uz k nicemu nevyuzivas :wink:

Co si urcit napriklad jeden z registru jako vysledek :wink: Prvni cislo bys do nej nacetl primo, a ty dalsi bys jenom porovnaval… Pokud by nektere z nasledujicich cisel bylo vetsi, jenom bys ho do toho registru presunul a bylo by… Potom by ti stacily jen 4 porovnani a mel bys vysledek :slight_smile:

Pokud jde o znamenkova cisla, pro ucely porovnani bez znalosti funkce bitu v PSW ti staci asi toto:
jsou-li obe cisla do 127 vcetne(obe kladna), vetsi cislo je vetsi
jsou-li obe cisla od 128 do 255 vcetne(nejvyssi bit = 1, obe cisla zaporna), vetsi cislo je vetsi
pouze je-li jedno cislo do 127(kladne) vcetne a druhe vetsi(zaporne), tak to mensi je ve skutecnosti vetsi :wink:
K porovnani lze celkem pohodlne vyuzit instrukci CJNE
Jinak pokud by byla cisla umistena v bitove oblasti (adresa 20-30h), tak by bylo mozno testovat nejvyssi bit primo :wink:

Proč tak komplikovaný algoritmus. Co třeba takhle:

         mov A,Operand1          ;signed byte
         clr C
         subb A,Operand2          ;signed byte
         jnb PSW.OV, Negace
         cpl Acc.7
Negace:                                 ;Acc.7 = Acc.7 xor OV
         jnb Acc.7,JeVetsi            ;Operand1>=Operand2 

Rychlejsi to urcite bude, ale nevim, jesli to The_LL pochopi

Ale jo mam nejaky scripta a kdyz si prectu co konkretni prikaz dela tak to rozlouzknu :wink: