ted koukam - pod návěštím “start” mam chybu ve 2 komentarich - ty adresy nemaj bejt 31h, ale 40h takhle to vypada, kdyz neco napisete, a pak do toho dodelavate dalsi veci
asi se budu muset zaregistrovat, abych si to mohl po sobe opravovat
ted koukam - pod návěštím “start” mam chybu ve 2 komentarich - ty adresy nemaj bejt 31h, ale 40h takhle to vypada, kdyz neco napisete, a pak do toho dodelavate dalsi veci
asi se budu muset zaregistrovat, abych si to mohl po sobe opravovat
radsi se neregistuj to bych te pak otravoval pres SZ 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… termin sice nestiham ale aspon na priste to snad priblizim realite…
A jeste jednou Dekuju…
pozde, uz jsem reglej
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
Pokud jde o znamenko, zalezi v jakem formatu jsou cisla ulozena… v pripade doplnkoveho kodu budes muset na x51 trochu premejslet… 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
Ted mam mnoho prace s ostatnim takze na tohle se vrhnu prozmenu o vikednu uz se na to tesim Musim to nejak sesmolit pac to mam ve stredu odevzdat i s tema znamynkama wish me good luck! pripadne se jeste na neco zeptam
dobra 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
pro cely zapolny cisla se pouzivaj dva formaty:
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
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
Teprve podle toho, ktery mas zadany, nebo ktery si vyberes, se pak muze resit, jak dal
akorat behem soboty ti tu nepomuzu - jedu kalit
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
Co se tyka doplnkoveho formatu, jsem rad, ze jste potvrdil muj predesly prizpevek ohledne fakticke spravnosti
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
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
Nez dohadovani se o slovickach by me spis zajimalo, jak se dari LL
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 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 ty mne na tom vsem opravdu “stvou”
mj moje mzateny komenty jsem se snazil vymazat nektery tam zustaly… ale pro vas stejne jsou bezpredmetny ;p
Jinak vam vsem moc diky za rady a napady urcite mi to pomaha
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
Co si urcit napriklad jeden z registru jako vysledek 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
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
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
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