Díky za článek - je zajímavé připomenout si, před čím jsem před 30 lety utíkal a proč: jsa odkojen 8bit Atari (Motorola 6502), pod tíhou tabulek instrukcí (a jejich doby trvání!) a adresních režimů se mi málem podlomila kolena. A to jsme se ještě nedostali ani k 386... (Trochu mi to připomíná Z80.)
Nicméně ani tak jste mě nezmátl a na vaši otázku "co by se stalo, kdyby v registru AX byla nula?", odpovídám: "potvrdí se chyba v článku o pár vět později :)". Rozsah počtu opakování této smyčky je ve skutečnosti přesně o jedna větší, tj. 1--2^16. Zaprvé smyčka s podmínkou na konci nemůže nikdy mít 0 opakování a zadruhé právě s AX=0 má pak smyčka přesně 2^16 opakování. V dalším odstavci je už i smyčka s podmínkou na začátku, pro kterou platí 0--2^16-1, nicméně otázka se týká ještě té původní.
Takže děkuju ještě jednou, že mě článek donutil zapojit šedou kůru mozkovou :)
Díky za zpětnou vazbu!
Jinak já jsem 8086 assembler nikdy neměl rád, taky jsem vyrostl na Atárku s pár instrukcemi a ošahal si i 8080 a Z80 (to nebylo tak špatné). Do 8086 toho napatlali strašně moc, včetně ASCII aritmetiky atd. (probereme), což je IMHO naprosto zbytečné.
Ale zase po letech uznávám, že je 8086 pro programátora výzva. Už se tím nemusíme živit a je to koníček. Nějaký RISC (třeba mě napadá MIPS) je v tomto ohledu strašně triviální a evidentně je to dělaný pro překladače, kdežto na 8086 to člověk pořád dokáže napsat lépe (doufám), než překladač :-)
Oproti Z80 byl 8086 assembler vyšší programovací jazyk.
AMD mělo s přechodem na 64bit jedinečnou příležitost zlikvidovat spoustu pohrobků ze starších architektur, pár instrukcí bylo obětováno, ale jinak se zásadně nic nezměnilo.
RISC asm se špatně čte, ale možná je to jen o zvyku.
Za výzvu považuju assembler na Itaniu.
jo no na RISC asm záleží, co to je za architekturu. Pokud to má branch delay sloty nebo ještě lépe registrová okna, tak to fakt delší kód prostě nedám :-)
Zdravím kolegu z VUT!
Předně musím pochválit za velmi pěkně napsaný úvod do x86 assembleru. Vyrostl jsem na něm od roku 1989, ale některé v článku zmíněné širší spojitosti jsem neznal.
V článku se vyskytuje několik nepřesností:
* Kapitola 7. na konci:
- Poznámka: povolení a zákaz přerušení se provádí instrukcemi STI (Enable Interrupt) a CLI (Disable Interrupt).
(Instrukce EI a DI měly procesory i8080 a Z-80)
* Kapitola 14. Použití instrukcí DEC a JZN pro implementaci počítané programové smyčky
- Překlep: instrukce se jmenuje JNZ
* Systémové volání na ukončení procesu má DVA parametry:
AH=0x4C (Terminate process with return code)
AL=návratový kód (return code, ErrorLevel v .BAT skriptech), měl by být 0 při úspěšném dokončení programu
Tedy všechny tyto kusy kódu:
; ukonceni procesu a navrat do DOSu
mov ah, 0x4c
int 0x21
by měly vypadat takto:
; ukonceni procesu a navrat do DOSu s navratovym kodem 0
mov ax, 0x4c00
int 0x21
nebo
mov ah, 0x4c
mov al, 0 ; pripadne xor al, al
int 0x21
Alternativně lze v .COM programech použít již dávno nedoporučovanou (ale funkční) instrukci int 0x20
, která ukončí program a neočekává na vstupu žádný návratový kód. Totéž dělá i mov ah, 0
a int 0x21
.
Frajer ovšem prostě zavolá ret
, protože na vrcholu zásobníku je uložena 0, ret
skočí na offset 0, kde se na začátku Program Segment Prefixu nachází instrukce int 0x20
(Exit program). :)
Toto funguje jen pokud je CS segment registr je identický s PSP segmentem, tj. v .COM programech startujících od adresy 0x100. MS-DOS má kořeny v systému CP/M a je to všude znát.
(Vidím, že můj manuál k OPL3 FM čipu si vesele žije dál svým životem). :)
12. 9. 2024, 04:15 editováno autorem komentáře
Zdravím!
Díky za upozornění, hnedle opravím ty DI/EI, nějak to mám v hlavě už pomotané :-)
Hele OPL3 - zrovna tady s mladým stavíme nad OPL3 syntetizér (s RP2040
), tak se na to po letech dívám znovu. A nic lepšího, než ten tvůj manuál asi není, všichni si to jen linkují, ale pořád je to origoš.
Tak kromě toho exitu opraveno. My jsme si už ten trik s "ret" probírali někdy u prvního článku, asi se k tomu i vrátím, než natahovat COM soubory kvůli exitu, nejsme na Linuxu :-)
"MS-DOS má kořeny v systému CP/M " no to je kulantne receno :) Hodne tech syscallu je snad uplne identickych, kdyz se namisto AX doplni A
Tisk řetězce v CP/M (8080/Z80):
- řetězec musí být ukončen dolarem
- C=9
- DE=adresa stringu
Tisk řetězce v DOSu (8086):
- řetězec musí být ukončen dolarem
- AH=9
- DX=adresa stringu
Čistá náhoda, no ne?
Popravdě, když si člověk ošahal Motorolu 68k, tak mu 8086 přišel jako o generaci starší čip. Jako vím, proč si IBM vybralo 8086 (měli pro to dobrý ne-technologický důvod), ale byla to chyba :/
no svět IT by vypadal jinak, protože by nastala situace, kdy všechny hlavní platformy běží na 68k - IBM PC, Sun, Atari, Amiga, Macintosh. To by mohlo být hodně zajímavé i z hlediska operačních systémů a tak.
Mohlo, ale když ze seznamu vynecháme PC, tak stalo se ve čtveřici SAMA, díky společné rodině procesorů, něco zajímavého z hlediska operačních systémů?
Ale otázka nebyla, jestli Amiga předběhla PC nebo jestli Mac předběhl PC nebo Sun předběhl PC (a neznám nikoho, kdo by nahlas řekl, že PC někoho z těch čtyř předběhlo), ale jestli si v tomto spolku nějak pomohli tím, že používali stejný procesor, nebo jestli to mělo nějaký pozitivní vliv na vývoj jejich operačních systémů.
težko říct, jestli si pomohli, když si konkurovali. Chyběl tam právě ten prvek komoditního HW (i když jednu dobu to Apple zkoušel, ostatní do toho nešli, jestli si dobře pamatuju).
Třeba že by OS byl od začátku v základním 32 bit. modu procesoru a nikoliv mix 16real a následně 386protected ?
Dík za článek. Avšak titulek sliboval "specifika instrukční sady 8086" a nenašel jsem v čem autor spatřuje tuto specifičnost. V čem byl 8086 jiný než v době jeho vzniku bylo obvyklé.
ta specifika (kromě adresování, výpočtu EA a specifičnosti registrů) probereme hlavně příště. Mě to strašně narostlo, tak musím rozdělit na dva díly :/
(mě osobně nejvíc připadly divný právě výpočty EA, taková magie co jde a co už nejde).
12. 9. 2024, 13:51 editováno autorem komentáře
Díky za článek!
Jako člověka, který začal programovat až po roce 2010 a low level programování jsem moc času nevěnoval, by mě zajímalo další info o ne úplně běžně používaných instrukcích jako IN, OUT, HLT.
Věděl by někdo o webu, kam by mě odkázal? Případně chystá se další článek, věnující se těmto instrukcím?
Díky.
Díky. Budeme se tomu věnovat příště, tedy konkrétně instrukcím IN, OUT a jejich "blokovým" variantám (to je taky specialitka 8086).
HLT se používalo společně s mat. koprocesorem a popravdě si to musím hodně nastudovat, protože 8087 se právě v tom "čekání" odlišoval (tedy kde a na jak dlouho vkládat HLT a kde právě ne - je to trošku černá magie)
S koprocesorem se používal FWAIT pro synchronizaci s CPU, s integrací FPU do CPU se stal zbytečný.
HLT čekalo na přerušení a CPU mezitím moh šetřit energií, když nebylo nic jiného na práci.
HLT je privilegovaná instrukce, použitelná jen na DOSu.
FWAIT jsme resili oftopic ve vlaknu pro ZX Spectrum a Z80.
https://www.root.cz/clanky/vyvoj-pro-zx-spectrum-dokonceni-realizace-prikazu-plot/nazory/
Nakonec jsme dosli k zaveru ze u 8087 s 8086 se musi delat FWAIT za/pred? (uz zas nevim...) KAZDOU instrukci... a ZAROVEN se to NIKAM nepise, protoze to za tebe dela prekladac!
Proto v dobove literature to bude popsano ruzne (protichudne) a ani studium vzorovych asm nepomaha, dokud se clovek nezacne divat primo na strojak... kde najednou vsude bude videt 9B.
Je to hodne prekvapiva vec, ze kdyz pises neco v asembleru tak to neni ta nejnizsi vrstva a linker ti tam bude klidne cpat jeste dalsi instrukce podle toho co das za cilovou architekturu.
Ale asi to byla snad jedina vyjmecna vec tohoto druhu, ktera resila vadny design toho hw. Kdo vi?
Od 286 to uz bylo zase vsechno jinak.
jj presne a ja jsem od te debaty nasel jeste dalsi popisy:
https://roboticelectronics.in/8087-interfacing-with-8086/
a https://www.ques10.com/p/10902/explain-interfacing-of-8087-co-processor-with-80-1/
(jinak NASM se snazi byt kompatibilni s MASMem, a to i v reseni wait/nowait instrukci, coz me osobne mate)
bude to v clancich?
14. 9. 2024, 09:16 editováno autorem komentáře
to nevim jak je mysleno, v NASMu explicitne zapisujes typ instrukce, takze treba FINIT nebo FNINIT:
BITS 16 ; 16bitovy vystup pro DOS
CPU 8086 ; specifikace pouziteho instrukcniho souboru
org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
start:
finit
fninit
se prelozi jako:
7 00000000 9BDBE3 finit
8 00000003 DBE3 fninit
A FWAIT se muze zapisovat primo jako instrukce (ne jako prefix - to je pravda matouci).
14. 9. 2024, 09:41 editováno autorem komentáře
Koprocesor pracoval asynchronně k CPU.
FWAIT "za" by zbytečně vynucoval plnou serializaci instrukcí, FWAIT "před" umožňoval maximální paralelizaci FPU s CPU.
Většina instrukcí měla WAIT implicitní, u pár výjimek byla volba.
Dalším efektem WAITu bylo vynucení volání handlerů FP výjimek (když byly povoleny), v tomto místě byla zaručena přerušitelnost + pokračovatelnost, předchozí FP instrukce byly již dokončeny a další ještě nezahájeny.
Koprocesor škudlil čekající výjimky ve stavovém registru a bez WAITu byly doručeny až na další FP instrukci.
FWAIT na 387 byl potřeba jen když koprocesor zapisoval výsledek/status do paměti odkud si jej vyzvedával CPU jinou než FPU instrukcí.
Podla vypisu na konci 4. kapitoly to vyzera ze 8086 nemal instrukciu mov ax, [bp] (8B4600) ale vzdy to bola len mov ax, [bp+0x00] (8B4600)
14 00000008 8B4600 mov ax, [bp]
19 00000014 8B461F mov ax, [bp+0x1f]