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.
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
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ů.
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)
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í.