učím se programovat v Assembleru, konkrétně mikrokontrolér Intel 8051. Mám dvě čísla. Obě čísla si po jednotlivých bytech načtu do tabulky pomocí pseudoinstrukce DB. Když bude jedno číslo 4-bytové a druhé 5-bytové, bude mít jedna "tabulka" 4 "políčka" a druhá 5 "políček" (obrazně pojmenováno). Potřebuji zjistit, která z tabulek je větší. Pomocí instrukce EQU umím načíst, jak jsou velké, takže v případě první tabulky umím načíst 4 do registru a v případě druhé tabulky umím načíst 5. Nyní je potřebuji porovnat, která z tabulek je větší a hodnotu uložit do registru, protože to pak použiji s instrukcí DJNZ a bude to určovat počet opakování smyčky. Ve škole jsme řešili, že to údajně nejde vzájemně porovnat klasickou instrukcí pro porovnání, nevím proč. Jednou funkční metodou bylo načíst délku obou tabulek (v uváděném příkladě 4 a 5) a vzájemně je vydělit > instrukce DIV, pak lze dostat, která hodnota je větší. Existuje ještě jiný způsob, jak to porovnat? Fakticky se učím, omlouvám se, pokud jsem napsal špatně nějaké termíny a děkuji za jakoukoliv radu.
Jinak zatím používáme simulátor MCU 8051 IDE, ale protože si simulátor neporadil s instrukcí EQU, pracujeme i v DOSu.
#1R_T
compare -> dle skoku rozhodneš... (jump if greater (or equal) -> jg(e)) Případně si pohraj s matematikou - například odečti a hraj si s výsledkem. (jz, jb, ja, ...)
#5q
Za prvé to nastavuje vlajky a za druhé jsem vlajky zmínil taktéž hoře. Tedy psal jsem mu, nechť odečte, či tak - že dle toho může skákat... (Poněvadž, jak každý znalý ASM ví, se musí počítat s nezjevnými operacemi - jako je nastavování vlajek.) Pokud nevěříš, hle: "The Carry bit (C) is set if operand1 is less than operand2, otherwise it is cleared." Tedy rozhodně compare funkci má - CJNE. + další kombinace - proto jsem uvedl CJ* (ano, přesnější by bylo CJNE *)...
#5q
Stačí tedy 2 operace: CJNE + J*; SUB + J*; či jakkoliv jinak. Každopádně CJNE + JQ to řeší dokonale. Ovšem je možné, že doposud netuším, jak jsem vytvořil svůj operační systém - vážně se v něm již dávno nevyznám.. :S
#7Matěj Andrle
Díky za rady. Určitě si s tím zkusím odpoledne na základě Vašich rad pohrát.
Možná pro upřesnění, proč to chci porovnat. Tu větší délku "tabulky" chci uložit do registru, protože obě čísla zadaná v tabulce musím sečíst. Součet mám řešený tak, že obě čísla jsou do tabulky zadány odzadu, tedy od nejnižšího řádu. Postupně si je načítám (přes DPTR do speciálních registrů A a B) a pak je sečtu. Pak si načtu další byty (vyšší řád), přičtu případný příznak přetečení z předchozího sčítání a takto po bytech sčítám. Smyčka je řešena pomocí DJNZ > od registru, ve kterém je uložen počet opakování odečítám jedničku a až je nula, znamená to, že jsem u nejvyššího řádu, ten sečtu (samozřejmě zachovám případný příznak přetečení a uložím ho před číslo) a smyčka končí. Jednotlivé součty ukládám na adresy, mám zadáno třeba zadávat od adresy 28h. A aby bylo číslo pak čitelné, vypisuji ho také zezadu, takže pokud je to delší číslo 5-bytové a to kratší třeba 3-bytové , potřebuji uložit 5, abych věděl počet opakování smyčky při součtu a zároveň abych si to mohl přičíst k té adrese 28h a odzadu vypisovat, pak mám jistotu, že nejvyšší řád bude právě na požadované adrese (samozřejmě počítám s příznakem přetečení v posledním kroku sčítání).
#8R_T
Jak jsem psal hoře - CJNE lze kombinovat s JC a JNC... (Pokud je Carry flag a není Carry flag... "The Carry bit (C) is set if operand1 is less than operand2, otherwise it is cleared.")
Porovnání dvou čísel jsem na 8051 dělal tak, že jsem udělal jejich rozdíl. Pokud na konci byl nastaven C, rozdíl byl záporný a tím pádem druhé číslo bylo větší. V opačném případě bylo první číslo větší nebo rovno. Na rovnost stačilo (LSB 1 čísla XOR LSB 2 čísla) OR (druhý LSB 1 čísla XOR druhý LSB druhého čísla) ... až byly zpracovány všechny byty. Pokud je výsledek 0, čísla se rovnají.
Pro účely sčítání dvou čísel by asi bylo jednodušší, kdybys pro obě čísla měl stejný počet bytů a ty před zadáním vynuloval a pak teprve zadal čísla - matematicky to znamená doplnit neplatné nuly zleva. Pak sčítám dvě 5-bytová čísla bez složitého koumání. Vhodné je pro sčítání LSB použít ADD a pro další byty ADDC. Druhá možnost je vynulovat C a sčítat pomocí ADDC u všech bytů.
Dále není nutné druhý operand přesouvat do B, může být adresován nepřímo pomocí R0 nebo R1. Tento registr může být současně i řídící proměnnou cyklu.