Assembler

Presentations

Assembler

   _____                              ___.   .__                
  /  _  \   ______ ______ ____   _____\_ |__ |  |   ___________ 
 /  /_\  \ /  ___//  ___// __ \ /     \| __ \|  | _/ __ \_  __ \
/    |    \\___ \ \___ \\  ___/|  Y Y  \ \_\ \  |_\  ___/|  | \/
\____|__  /____  >____  >\___  >__|_|  /___  /____/\___  >__|   
        \/     \/     \/     \/      \/    \/          \/       

Proč assembler?

  1. Větší efektivita využití CPU
  2. Rychlejší (a predikovatelné) přerušovací rutiny
  3. Efektivita při práci s pamětí (cache+RAM)
  4. Kompaktní kód
    • Některé požadavky se mohou vzájemně vylučovat!
  5. (Lepší pochopení práce s gdb a dalšími debuggery)

Role assembleru

Závislost na platformě

Použití assembleru v minulosti

Použití assembleru v současnosti

  1. Firmware
  2. Kód pracující přímo s HW (senzory, CPU+FPGA)
  3. DSP a MCU - rychlé přerušovací rutiny!
  4. Instrukce nedostupné ve vyšším programovacím jazyce
  5. Specifické subrutiny (SIMD, SSE, rotace, hledání vzorků…)
  6. Zpracování signálů
  7. Kodeky
  8. Virtuální stroje generující strojový kód
  9. Reverse engineering :-)
  10. Samomodifikující se kód
  11. DSP
  12. Fingerprints (A86)

Instrukce nedostupné ve vyšším programovacím jazyce

Použití assembleru v současnosti

Příklad

x264 naprogramovaný v assembleru http://git.videolan.org/?p=x264.git;a=tree;f=common/x86;hb=HEAD

Hodnocení „popularity“ assembleru ½

OpenHub cca 0,5% projektů, <0,2% commitů

Hodnocení „popularity“ assembleru

TIOBE index

02/2017 02/2016 Jazyk            Hodnocení Změna
1       1       Java                16,6%  -4,4%
2       2       C                    8,4%  -7,1%
3       3       C++                  5,4%  -1,4%
4       4       C#                   4,9%  +0,5%
5       5       Python               4,0%  -0,1%
6       6       PHP                  3,0%  +0,3%
7       9       JavaScript           2,8%  +0,6%
8       7       Visual Basic .NET    2,8%  +0,3%
9       10      Delphi/Object Pascal 2,4%  +0,3%
10      8       Perl                 2,1%  -0,0%
11      11      Ruby                 2,1%  +0,1%
12      16      Swift                2,1%  +0,7%
13      13      Assembler ********   2,1%  +0,3%

Kdy/proč psát v assembleru

Assembler a Linux

GNU Assembler

NASM

FASM

Syscally a GNU Assembler

Kostra programu v assembleru

# Linux kernel system call table
sys_exit=1

.section .text
        .global _start          # tento symbol ma byt dostupny i linkeru

_start:
        movl  $sys_exit,%eax    # cislo sycallu pro funkci "exit"
        movl  $0,%ebx           # exit code = 0
        int   $0x80             # volani Linuxoveho kernelu
# Linux kernel system call table
sys_exit=60

.section .text
        .global _start          # tento symbol ma byt dostupny i linkeru

_start:
        movl  $sys_exit,%eax    # cislo sycallu pro funkci "exit"
        movl  $0,%edi           # exit code = 0
        syscall                 # volani Linuxoveho kernelu

„Hello world“ v assembleru

# Linux kernel system call table
sys_exit=1
sys_write=4


.section .data

hello_lbl:
        .string "Hello World!\n"


.section .text
        .global _start          # tento symbol ma byt dostupny i linkeru

_start:
        mov   $sys_write, %eax  # cislo syscallu pro funkci "write"
        mov   $1,%ebx           # standardni vystup
        mov   $hello_lbl,%ecx   # adresa retezce, ktery se ma vytisknout
        mov   $13,%edx          # pocet znaku, ktere se maji vytisknout
        int   $0x80             # volani Linuxoveho kernelu

        movl  $sys_exit,%eax    # cislo sycallu pro funkci "exit"
        movl  $0,%ebx           # exit code = 0
        int   $0x80             # volani Linuxoveho kernelu

Volání funkcí ze standardní céčkové knihovny

puts

.intel_syntax noprefix


.section .data
hello_world_message:
        .asciz "Hello world!\n"    # zprava, ktera se ma vytisknout na standardni vystup


.section .text
        .global main               # tento symbol ma byt dostupny i linkeru

main:
        sub  rsp, 8                # zajistit zarovnani RSP na adresu delitelnou 16

                                   # jedinym parametrem je adresa zpravy
        mov  rdi, offset hello_world_message
        call puts                  # volani funkce 'puts' ze standardni knihovny

        add  rsp, 8                # obnoveni puvodni hodnoty RSP

        xor  eax, eax              # navratova hodnota (exit status)
        ret                        # ukonceni aplikace

printf

.intel_syntax noprefix


.section .data
hello_world_message:
        .asciz "Hello world!\n"    # zprava, ktera se ma vytisknout na standardni vystup


.section .text
        .global main               # tento symbol ma byt dostupny i linkeru

main:
        sub  rsp, 8                # zajistit zarovnani RSP na adresu delitelnou 16

                                   # jedinym parametrem je adresa zpravy
        mov  rdi, offset hello_world_message
        xor  al, al                # pocet parametru predanych ve vektorovych registrech
        call printf                # volani funkce 'printf' ze standardni knihovny

        add  rsp, 8                # obnoveni puvodni hodnoty RSP

        xor  eax, eax              # navratova hodnota (exit status)

        ret                        # ukonceni aplikace

Assembler v C

Zápis v GCC

int main()
{
    __asm__ __volatile__(
        "nop   \n\t"
        : /* zadne vystupni registry */
        : /* zadne vstupni operandy */
        : /* zadne registry pouzivane uvnitr kodu */
    );
    return 0;
}

Specifikace výstupních operandů

Expl## icitní registry pro výstupní operandy a → %rax, %eax, %ax, %al b → %rbx, %ebx, %bx, %bl c → %rcx, %ecx, %cx, %cl d → %rdx, %edx, %dx, %dl S → %rsi, %esi, %si D → %rdi, %edi, %di

Specifikace vstupních operandů

Explicitní určení registru pro výstupní operand

Vliv optimalizací na generovaný kód

Použití syntaxe používané firmou Intel

Assembler a C pro procesory ARM

gdb

Ladicí informace ve vytvářených programech

Spuštění gdb

Základní příkazy gdb

r      run
start            start+zastaví na mian
c      cont      continue
s      step      step into
n      next      step over
bt     backtrace print stacktrace
l      list      výpis zdrojového kódu (fce)
p      print     výpis výrazu
q      quit
h      help

Breakpointy

b          breakpoint na aktuálním řádku
b#         breakpoint na řádku #
b fce      breakpoint na funkci
b file:fce specifikace souboru s funkcí
b file:#   specifikace souboru a čísla řádku

info b     informace o všech breakpointech
delete #   vymazání breakpointu s daným indexem

Breakpointy s podmínkou

Watchpointy

Demo