poradite mi se zacatecnickym prog?

Ahoj v ramci studia mam udelat jednoduchou ulohu zatim jsem stvrotil toto s tim ze bych to mel asi rozdelit na 4 vetve a uz u toho ulkadani do vnitrni pameti mam nejakou hcybku kterou nechapu…

Nerad bych abyste nabyli dojmu ze to od vas chci stvorit ale urcite bych vam byl vdecen kdybyste me postrcili spravnym smerem ci mi poopravili nejaky nesmysly co jsem tam napsal… Predem moc diky…


; porovnavani peti cisel se znamenkem ulozenych ve vnitrni pameti 
; vysledek do vnejsi pameti ..	 

	   x0 equ -2
	   x1 equ  3
	   x2 equ  1
	   x3 equ  5
	   x4 equ -6


start:    mov	a,#x0	; plneni vnitrni uz tady je naka chyba?
		  mov r0,a
		  mov a,#x1
		  inc r0
		  mov r0,a
		  mov a,#x2
		  inc r0
		  mov r0,a
		  mov a,#x3
		  inc r0
		  mov r0,a
		  mov a,#x4
		  inc r0
		  mov r0,a
		  	  		 
		  call 	porovnej   ;skok na navesti
	  jmp 	$    

;podprogram

porovnej: 	Push 	acc
			MOV 	a,DPH 
			CLR 	 c		
			subb 	a,dpl
			jnc	  porovnej1 
			mov 	a,dpl	  
			mov 	dpl,dph
			mov 	dph,a
			pop		acc	
porovnej1:  ret				

end

v tom podprogramu to zatim porovnava jen dve cisla s tim ze ani nezohlednuju jejich znamenko unika mi logicka souvislost a nejak sem se na tom zadrhl a dal nedostal (zatim) :frowning: priznavam ze mi v tom zatim zustava mnoho nejasnosti…

V prvom rade equ takto nemozes pouzit. Ty tam mas, nazvu X0 prirad pamatove miesto -2 (to neexistuje) …spravne ma byt (podla mna) X0 db -2.

Pred tym musis urcit oblast ukladania… xx51 zacinaju program na adrese 00h, kde je miesto pre ulozenie startu (asi) 7 bytov, potom su dalsie miesta na obsluhu prerusenia, takze zaciatok by mal byt asi takto :

org 00H

jmp start

org 30H

X0 db -2
X1 …

org 37H

start: …

Mozno je tam niekde (z dovodu plasenia sa) chyba, ale snad nie…

Zdar, to se poda 8)
Prozacatek neres zaporny cisla - pro jejich ulozeni v pameti se pouzivaj 2 formaty, tezko ric, kterej by si prekladac vybral… (pokud vubec nejakej) a tudiz to nemuzes radit - to je nepatrne narocnejci, je tam potreba koukat i do PSW…

Kolega vyse asi presne nepochopil pouziti direktivy EQU pro rizeni prekladace, v uvodnim prispevku je to spravne - pokud k x0 pomoci EQU priradis cislo, prekladac vsude x0 nahradi cislem, to je dobre :wink:
pouziti # u mov je taky spravne - znamena to, ze cislo (ktere tam prekladac doplni) je hodnota (nikoli adresa).

  1. problem bude v plneni pameti - mov r0,a - u r0 chybi zavinac… takhle totiz nactec cislo do r0 a pak prictes 1, to asi nechces :wink: Spravne to bude mov @r0,a - tzn. na adresu, ktera je ulozena v r0, zapis cislo z “a” :wink:
    ale v tomto pripade lepsi reseni: mov @r0, #x0 - mov umi pri neprimym adresovani pracovat s konstantou jako druhym operandem :wink:
    jinak obecne by se asi pracovalo s primou adresou :wink:

Dalsi zasadni nedostatek je, ze neinicializujes r0 - je potreba do nej na zacatku zadat adresu, od ktere se budou cisla ukladat… Oblast registrovych bank konci adresou 2Fh, oblast SFR zacina na 80h, takze mas k dispozici misto MEZI temito adresami - takze nejlepsi bude nastavit nazacatku r0 na 30h, jelikoz tu pamet plnis odspod nahoru. Taky je nutne brat v uvahu nasmerovani Stack Pointeru, protoze pouzivas podprogram a instrukce push a pop, ale ve tvem pripade to nebude problem, kdyz budes pouzivat RAM od adresy 30h, stack bude mit dost mista (22bytu, pokud nepouzijes bitovou oblast, stack zacina na 07h a roste nahoru)

Na porovnavani cisel je lepsi instrukce CJNE (compare and jump if not equal). kdyz nejsou cisla shodna, tak skoci, potom podle podle toho, ktery operand je vetsi, se ridi bit Carry v PSW: je-li prvni operand mensi nez druhy, C = 1, jinak 0

to je odemne prozacatek vsechno, chtel jsem jeste smotnout zacatek toho kodu, ale tlaci me cas, tak kdyztak vecir :wink:

Dkuju mockrat za rady a pripominky zkusim si s tim pohrat… bohuzel to sou mnohdy pro me gorilly v mlze :slight_smile: ale snad casem to budou jen ty gorilly… :smiley:

tu mas kus zdrojaku :slight_smile: Nepsal jsi, co to po tom porovnani ma delat, tak jsem napsal 1 pruchod polem řadiciho algoritmu bublesort :wink: Pokud ten pruchod budes opakovat tak dlouho, dokud se behem pruchodu bude provadet zamena cisel, tak ti to setridi cely pole :wink: Az se behem pruchodu zadna zamena neprovede, je serazeno…

[code]$NOPAGING
; porovnavani peti cisel se znamenkem ulozenych ve vnitrni pameti
; vysledek do vnejsi pameti …

x0 EQU 2
x1 EQU 3
x2 EQU 1
x3 EQU 5
x4 EQU 6

z_pole DATA 30h ;promenna v RAM - obsahuje zacatek pole razenych cisel
k_pole DATA 31h ;konec pole
temp DATA 32h ;pomocna prom.

ORG 0h
sjmp start

start: mov z_pole, #40h ;rekneme, ze pole bude zacinat napriklad adresou 40h

mov r0, z_pole		;pole bude ulozeno od adresy 31h (nad registry a bit. oblast)
mov @r0, #x0		;nacteni cisel do RAM, cislo x0 nacteno na adresu 31h
inc r0
mov @r0, #x1
inc r0
mov @r0, #x2
inc r0
mov @r0, #x3
inc r0
mov @r0, #x4		;x4 na adr. 35h
mov k_pole, r0		;ulozit adresu konce pole



;jedina pouzitelna varianta CJNE: "CJNE A, direct_addres, jump_relativ_addres"
;cisla budu radit sestupne (od zacatku pole), nizsi adresa bude obsahovat vetsi cislo

;-----------------------------------------
;------ 1 pruchod polem ------------------
;-----------------------------------------
mov r0, z_pole
dalsi: mov a, r0
cjne a, k_pole, pokr1 ;kontrola, zda jiz nebylo projito cele pole
sjmp stop ;doslo se na konec, stop

pokr1: mov a, @r0 ;A <- 1. cislo
inc r0
mov temp, @r0 ;temp (30h) <- 2. cislo
cjne a, temp, pokr2 ;v C vysledek porovnani, pokracuje se nasledujicim radkem (pripadny skok je tamtez)
pokr2: jnc dalsi ;pokud je 1. cislo vetsi (na nizsi adrese), porovnej dasli 2 cisla

mov @r0, a		;jinak cisla prohodime, v A je mensi cislo a r0 miri na vyssi adresu (adresa
			;toho vetsiho cisla) tam to mensi zapisem.
dec r0			;presmerujem r0 zpatky na nizsi adresu
mov @r0, temp		;a zapisem vetsi cislo
inc r0			;vratime r0 zpatky o misto vys a jdem porovnavat dalsi 2 cisla
sjmp dalsi

;-----------------------------------------
;-----------------------------------------
;-----------------------------------------
stop: sjmp $

end[/code]

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: