====== 1. Seznámení s učebnou, překladačem, simulátorem a základy reprezentace dat ====== * pro vyučující: [[..:..:internal:tutorials:01:start|cvičení 1]] ===== Osnova cvičení ===== - požadavky na zápočet, hodnocení - seznámení s učebnou - od Pythonu přes C do assembleru - seznámení se simulátorem [[..:..:documentation:qtmips:start|QtMips]] - pořadí ukládání bajtů - základní reprezentace čísel bez znaménka a se znaménkem ===== Co bych si měl na první cvičení zopakovat / připravit ===== - K přihlášení ke GNU/Linuxu v KN:E-2 se používá Hlavní přístupové heslo (více na stránce {{https://support.dce.felk.cvut.cz/mediawiki/index.php/Hesla_a_jejich_spr%C3%A1va_na_%C4%8CVUT/FEL|o přístupových heslech}} na Wiki IT skupiny) - binární a hexadecimální reprezentace celých čísel čísel - doplňkový kód - operace sčítání, odčítání, násobení a dělení - logické operace s binárními čísly (and, or, rotace, ...) - přečíst/zopakovat kapitolu 3 z {{ ..:..:lectures:apolos_v11.pdf|APOLOS}} - binární soustava a modulo aritmentika ===== Náplň cvičení ===== Cílem cvičení je seznámení s učebnou, zopakování základních pojmů na téma reprezentace dat v počítači a seznámení s návazností jazyků různé úrovně abstrakce až po strojový kód. Počítejte s tím, že se jedná pouze o přehled a získání představy o čím se v našem předmětu a pro program KyR paralelně v předmětu [[https://cw.fel.cvut.cz/wiki/courses/b3b36prg/start|B3B36PRG - Programování v C]] budete zabývat. Pro první půli semestru pak programovací jazyk C budeme používat jen pro obecný zápis algoritmů (většina konstrukcí je pochopitelná jako ekvivalent algoritmu například v jazyce Python) a ve druhé půli již bude v rámci B3B36PRG probraný po dostatečnou hloubku mohl být použitý pro řešení vlastních úloh. ==== Od pohodlného programování na vyšší úrovni k strojovému kódu ==== === Python === Jedná se o dynamicky typovaný jazyk vyšší úrovně, pro spuštění programu je nutné použít interpretr (může se jednat i o běhové prostředí s částečným překladem za běhu) nejčastěji napsaný v jazyce C. Otestujte následující jednoduchý příklad v jazyce Python. Pro vytvoření souboru ''sum2vars.py'' využijte některý z nainstalovaných editorů (geany, vim, emacs, qtcreator, clion, ...). Pro ty, co nemají vlastní preferenci je vhodné začít třeba s programem [[https://www.geany.org/|geany]]. #!/usr/bin/python3 var_a = 0x1234 var_b = 0x2222 var_c = var_a + var_b print('sum %d + %d -> %d'%(var_a, var_b, var_c)) print('sum 0x%x + 0x%x -> 0x%x'%(var_a, var_b, var_c)) Program můžeme předat jako parametr a spustit v interpretru python3 sum2vars.py Pokud vlastní soubor označíme jako spustitelný chmod +x sum2vars.py Bude ho možné "přímo" spustit i přesto, že mu procesor ani operační systém přímo nerozumí. První řádka ([[https://en.wikipedia.org/wiki/Shebang_(Unix)|shebang]]) zajistí, že interpreter příkazové řádky ([[https://en.wikipedia.org/wiki/Shell_(computing)|shell]]) nepředá přímo soubor ke spuštění operačnímu systému, ale zavolá v první řádce specifikovaný interpreter a soubor mu předá jako parametr. Drobné úskalí a zároveň kritický zvyk pro zvýšení ochrany napadnutí uživatele (zkuste přijít proč) spočívá v tom, že příkaz bez zpecifikace cesty je hledaný jen v adresářích specifikovaných v seznamu cest (proměnná prostředí [[https://en.wikipedia.org/wiki/PATH_(variable)|PATH]]) a ta na rozumně navržených a spravovaných systémech neobsahuje aktuální adresář. Proto pro spuštění programu musíme uvést i cestu. V tomto případě aktuální adresář - zastoupený symbolem tečka "''.''". ./sum2vars.py === Programovací jazyk C === Jedná se o jazyk se striktně programátorem definovanými datovými typy. Vlastní vazba identifikátorů typů na způsob reprezentace se ovšem může lišit mezi architekturami, protože například typ pro celá čísla se znaménkem (''int'') reprezentuje takové kódování celých čísel alespoň v rozsahu −32,767 až +32,767, které nejlépe na zpracování vyhovuje danému cílovému procesoru. Na většině v dnešní době využívaných architektur je pak rozsah datového typu ''int'' −2,147,483,648 až +2,147,483,647 ($-2^{31}$ až $2^{31}-1$) a hodnota je ukládaná ve 32-bitech. Program je obvykle nutné před spuštěním zkompilovat (existují i jiné alternativy - [[https://root.cern.ch/cling|CERN ROOT Cling]]) do binární podoby, ve které může být načtený operačním systémem do paměti vlastní výpočet pak provádí přímo procesor podle přeložených/binárních strojových instrukcí . Přepis výše uvedeného kódu v jazyce C do souboru ''sum2vars.c'' vyžaduje definici funkce ''main()'', která je vstupním bodem programu v jazyce C. Dále je pro zpřístupnění funkce ''printf()'' potřeba zavést hlavičkový soubor ''stdio.h''. #include int var_a = 0x1234; int var_b = 0x2222; int var_c = 0x3333; int main() { var_c = var_a + var_b; printf("sum %d + %d -> %d\n", var_a, var_b, var_c); printf("sum 0x%x + 0x%x -> 0x%x\n", var_a, var_b, var_c); return 0; } Program zkompilujeme do binární podoby [[https://www.gnu.org/|GNU]] kompilátorem jazyka C ([[https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/|manuál]]). gcc -Wall sum2vars.c Standardní jméno výstupního spustitelného souboru je ''a.out''. Program spustíme udáním názvu s cestou ''./a.out''. Požadované jméno binárního souboru můžeme specifikovat na příkazové řádce přepínačem ''-o'' stejně jako specifikovat vložení ladících informací ''-ggdb''. Kompilátor je dále možné požádat o optimalizaci programu na délku přepínačem ''-Os''. gcc -Wall -Os -ggdb -o sum2vars sum2vars.c Obsah binárního souboru ve formátu [[https://en.wikipedia.org/wiki/Executable_and_Linkable_Format|ELF]] je možné zkoumat například nástrojem [[https://sourceware.org/binutils/docs/binutils/objdump.html#objdump|objdump]]. objdump -S sum2vars Překlad na jednotlivé strojové instrukce je možné prozkoumat i online [[https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(fontScale:14,j:1,lang:c%2B%2B,selection:(endColumn:1,endLineNumber:18,positionColumn:1,positionLineNumber:18,selectionStartColumn:1,selectionStartLineNumber:18,startColumn:1,startLineNumber:18),source:'%23include+%3Cstdio.h%3E%0A%0Aint+var_a+%3D+0x1234%3B%0Aint+var_b+%3D+0x2222%3B%0A%0Aint+var_c+%3D+0x3333%3B%0A%0Aint+main()%0A%7B%0A++var_c+%3D+var_a+%2B+var_b%3B%0A%0A++printf(%22sum+%25d+%2B+%25d+-%3E+%25d%5Cn%22,+var_a,+var_b,+var_c)%3B%0A%0A++printf(%22sum+0x%25x+%2B+0x%25x+-%3E+0x%25x%5Cn%22,+var_a,+var_b,+var_c)%3B%0A%0A++return+0%3B%0A%7D%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:g92,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'1',trim:'1'),fontScale:14,j:1,lang:c%2B%2B,libs:!(),options:'-Os',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'x86-64+gcc+9.2+(Editor+%231,+Compiler+%231)+C%2B%2B',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4|Godbolt Compiler Explorer]] === Assembler - jazyk symbolických adres === Zápis v jazyce C je přeložený na takovou posloupnost strojových instrukcí, která vykoná nad přesně specifikovanými datovými typy takové operace, že výsledek celého běhu programu, nebo běhu do sekvenčního bodu, je ekvivalentní zapsanému algoritmu. Výstup kompilátoru ve formátu již přesně daných instrukcí, ale bez rozhodnutí o jejich finálním umístění v paměťovém prostoru získáme pro nativní překlad (překlad pro systém, na kterém aktuálně kompilátor běží) příkazem gcc -Wall -Os -S -o sum2vars.s sum2vars.c Plné pochopení jak psát programy v assembleru pro architekturu x86_64 a pro běh pod operačním systémem GNU/Linux je náročné a proto jsme pro výuku procesorových architektur zvolili architekturu MIPS ([[..:..:documentation:qtmips:start#volba_architektury_mips|důvody]]) a na začátek jí budeme používat v její maximálně omezené a zjednodušené podobě. Aby bylo možné sledovat vnitřní stavy a princip činnosti procesoru, nebudeme používat přímo procesorové desky s [[..:..:documentation:embedded_systems/start#pic32mxpic32mx_levne_vykonnejsi_mikrokontrolery_na_bazi_architektury_mips|čipy]] implementujícími architekturu, ale grafický simulátor vytvořený přímo pro účely našeho kurzu - [[..:..:documentation:qtmips:start|QtMips]] ([[https://pretalx.linuxdays.cz/2019/talk/EAYAGG/|materiály]] a [[https://youtu.be/fhcdYtpFsyw|video]] z jeho představení na akci [[https://www.linuxdays.cz/2019/|LinuxDays 2019]]). Přitom následující ukázky jsou uvedené především pro získání přehledu, čím se budete během semestru zabývat. K zápisu algoritmu v instrukcích procesoru se vrátíme ve třetí přednášce a [[..:03:start|třetím cvičení]]. Pro první přiblížení zkompilujeme kód křížovým překladačem pro architekturu MIPS. mips-linux-gnu-gcc -ggdb -static -Os -o sum2vars-mips sum2vars.c Program je možné v naší laboratoři pustit i na GNU/Linux systému s architekturou x86_64, protože binární soubory pro architekturu MIPS jsou automaticky interpretované emulátorem [[https://www.qemu.org/|QEMU]] v režimu user-space emulace. Manuální přepis do assembleru (sobor ''sum2vars.S'') může vypadat následovně (pro zjednodušení bez volání funkce tisku) .globl main .globl _start .text _start: main: lw $4, var_a($0) lw $5, var_b($0) add $6, $4, $5 sw $6, var_c($0) addi $2, $0, 0 jr $ra nop .data var_a: .word 0x1234; var_b: .word 0x2222; var_c: .word 0x3333; Program můžeme přeložit mips-elf-gcc -o sum2vars sum2vars.S nahrát do simulátoru {{ ..:qtmips-load-sum2vars.png?direct&400 |}} a odkrokovat. Program lze zkompilovat i přímo v simulátoru. Aby simulátor nenahrával externí program, spustíme ho v režimu bez nahrání ELF souboru. {{ ..:qtmips-start-empty.png?direct&400 |}} Zvolíme File -> New source Program tentokrát doplníme o přesnou specifikaci umístění proměnných (direktiva ''.org 2000''). _start: main: lw $4, var_a($0) lw $5, var_b($0) add $6, $4, $5 sw $6, var_c($0) addi $2, $0, 0 jr $ra nop .data .org 0x2000 var_a: .word 0x1234; var_b: .word 0x2222; var_c: .word 0x3333; #pragma qtmips show registers #pragma qtmips show memory #pragma qtmips focus memory var_a #pragma qtmips tab core Přidané jsou i direktivy pro rychlé nastavení pozice ve výpisu paměti na proměnnou ''var_a'' a další. Zkompilujeme volbou Machine -> Compile source a můžeme ho odkrokovat. {{ ..:qtmips-with-legend.png?direct&400 |}} Dále lze hodnotu 0x1234 nahradit hodnotou 0x12345678 a ve výpisu paměti pozorovat, jak se hodnota rozloží do bytů a nebo 16-bit polovičních slov. Využijte přepínač zobrazení dat, zkuste měnit šířku výpisu. Příklad, jak vyzkoušet zobrazování čísel z Pythonu hlavně pro ty, co ještě neumí základy jazyka C #!/usr/bin/python3 import struct a = 0x1234567 b = -12345678 c = a + b buf = struct.pack(' Více o ukládání proměnných v specifikovaném formátu datové reprezentace v moduly jazyka Python [[https://docs.python.org/3/library/struct.html|struct — Interpret bytes as packed binary data]]. ===== Úkoly ===== - S cvičícím si projděte výše uvedený přehled, čím se budete během semestru zabývat * zkontrolujte si, že umíte na počítačích v laboratoři používat simulátor QtMips * v případě, že vám není jasné, jak si simulátor nainstalovat doma, tak se zeptejte cvičících - Studenti OI a pokročilejší z programu KyR se pokusí upravit program pro součet dvou čísel tak * aby vypisoval výsledek po jednotlivých bitech od bitu číslo 31 po bit 0 * aby bylo možné vstupní hodnoty specifikovat na příkazové řádce (argc, argv, atoi) * aby používal datové typy s menším rozsahem (short int, unsigned short int, unsigned char, signed char) * vyzkoušejte operace s kladnými i zápornými čísly, zaměřte se i na takové hodnoty, kdy po provedení operace dojde k přetečení - Studenti KyR bez znalosti jazyka C * použijí pro seznámení jazyk Python s modulem ''struct'' z výše uvedeného příkladu. * vyzkouší změnu ukládání v nativním pořadí byte a big-endian pořadí * navrhnou algoritmus pro výpis celočíselné proměnné po bitech * vyzkouší si binární formátování ''print("{0:08b}".format(a))'' - Vyzkoušejte si ručně sčítání a odčítání celých čísel v doplňkovém kódu * demonstrujte výpočet např. 7+6, 7-6 * procvičte výpočet na dalších číslech a s pomocí programu výsledky ověřte * Kdy může dojít k přetečení a jak poznáte, že k němu došlo? - Násobení celých čísel * demonstrujte výpočet např. 7*6 * jak se výpočet změní v případě záporných čísel? např. -7*6, -7*(-6), 7*(-6) * rychlá verze hw násobičky (jak zrychlit opakované sčítání na jedné sčítačce použitím většího množství sčítaček?) - Dělení celých čísel * demonstrujte výpočet např. 42/7, 43/7 * jak se výpočet změní v případě záporných čísel? ===== Užitečné odkazy ===== * [[https://support.dce.felk.cvut.cz/pos/cv1/|https://support.dce.felk.cvut.cz/pos/cv1/]] - Práce v příkazové řádce POSIXového systému, kompilace a její automatizace (make) * [[http://support.dce.felk.cvut.cz/pos/cv-langc/|http://support.dce.felk.cvut.cz/pos/cv-langc/]] - Základy jazyka C * [[http://www.gnu.org/software/libc/manual/html_node/Formatted-Output.html|http://www.gnu.org/software/libc/manual/html_node/Formatted-Output.html]] - Dokumentace k řízení formátovaného výstupu pro implementaci **printf** z knihovny funkcí pro jazyk C ([[http://www.gnu.org/software/libc/|GLIBC]]) z projektu [[http://www.gnu.org/|GNU]] * [[https://bootlin.com/doc/legacy/command-line/command_memento.pdf|Základní příkazy pro práci v příkazové řádce]] na [[https://bootlin.com/|Bootlin]] ===== Domácí úkoly ===== * domácí úkoly 1 až 4 budou zadané a odevzdávané elektronickou formou * vstup k zadání a odevzdání úkolů 1 a 3 je přes adresu [[https://dcenet.felk.cvut.cz/apo/|https://dcenet.felk.cvut.cz/apo/]] * Na stránce "Assignments" naleznete seznam zadaných úkolů * Pro vyzkoušení práce s odevzdávacím systémem je k dispozici nehodnocená varianta prvního úkolu **1st training homework** * Případnými problémy s odevzdávacím systémem se obracejte na svého cvičícího nebo přímo na autora/správce sytému [[courses:b35apo:teacher:susta:start|Richarda Šustu]] ===== Počítačová síť v učebně KN:E-2 ===== Učebna KN:E-2 je vybavena počítači se síťovou instalací operačního systému [[https://www.debian.org/|Debian]] GNU/Linux Bullseye Po zapnutí počítače je zaveden z lokálního serveru přes PXE zavaděč PXElinux. Ten umožňuje volit * boot z lokálního disku stanice (nebudeme používat) * volba ''DCE Linux Bullseye (Debian)'' spuštění síťové verze operačního systému [[http://www.debian.org/|Debian Bullseye]] Volba menu zajistí natažení image jádra GNU/Linux a počátečního RAM-disku ze sítě s využitím protokolu TFTP. Po spuštění jádra je připojen přes NFS kořenový svazek. Ten je ale připojen jen v režimu pro čtení. Pro dočasné uložení lokálních změn je pak nad tuto adresářovou strukturu namapovaný souborový systém pro dočasné uložení lokálních změn. Jedná se o modul [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/overlayfs.txt|Overlayfs]] (dříve se používal [[http://aufs.sourceforge.net/|AUFS]]). Pro ověření přihlašovacích údajů se používá systém Kerberos a ověřuje se proti hlavnímu ČVUT heslo. Po úspěšném přihlášení je pak do adresářové struktury stanice připojen přes NFS svazek s uživatelským kontem, ke kterému má uživatel práva pro čtení a zápis. Další informace o použitém řešení lze nalézt na stránce Wiki [[https://support.dce.felk.cvut.cz/mediawiki/index.php/Jak_vytvo%C5%99it_bezdiskov%C3%BD_stroj_s_opera%C4%8Dn%C3%ADm_syst%C3%A9mem_GNU/Linux|Jak vytvořit bezdiskový stroj s operačním systémem GNU/Linux]]. Dále jsou k dispozici slide [[http://cmp.felk.cvut.cz/~pisa/linux/diskless/diskless_dce_slides.pdf|DiskLess Debian/GNU Linux]] z prezentace našeho řešení na konferenci/akci [[http://installfest.cz/|Install Fest]]. ===== Studentská konta a hesla ===== Pro ověření oprávnění k přístupu do systému a se používá centrální ČVUT/FEL heslo. ===== Vzdálený přístup k datům na uživatelských kontech ===== Kromě místnosti KN:E-2 je prostředí dostupné v místnostech KN:E-s109, KN:E-23, KN:E-24 a na externě přístupném serveru ''postel.felk.cvut.cz'' přes SSH spojení. Pro přenos souborů lze pak použít příkaz SCP případně jiné klienty podporující SCP/SFTP protokol. Konto si lze připojit do vlastního GNU/Linux systému přes utilitu [[http://man7.org/linux/man-pages/man1/sshfs.1.html|sshfs]], např.: sshfs jmeno@postel.felk.cvut.cz: /mnt/tmp Odpojení konta se dá provést příkazem: fusermount -u /mnt/tmp Server nabízí i vzdálené připojení k na něm spouštěným grafickým aplikacím ssh -X jmeno@postel.felk.cvut.cz Poznámka: Jméno nebylo zvoleno pouze z důvodu pohodlného přístupu z pohodlí domova, ale je především připomínkou jedné z klíčových osobností počítačové sítě Internet - [[http://en.wikipedia.org/wiki/Jon_Postel|Jona Postela]]. ===== Řešení problémů s konty, obnova dat ===== V případě problémů s instalací GNU/Linxu kontaktuje Aleše Kapicu ze skupiny IT (http://support.dce.felk.cvut.cz/mediawiki/index.php/IT_kontakty) případně další kolegy ze skupiny IT, kteří mají správu hardware a sítí ne jen v KN:E-2 na starosti.