Encyklopedia w Markpol

Reklama: okna rolety

Wstęp

Asembler do architektury 80x86, czyli popularnych "PCtów", jest skomplikowany i pełen niekonsekwencji. Wynika to z tego, że każdy nowy procesor wprowadzaj±c różne ulepszenia musiał pozostać kompatybilny z poprzednikami. W procesorach 80286 jest około 250 rozkazów, w 80486 już ok. 350 natomiast w najnowszym procesorze – Pentium 4 – ok. 580 (w procesorach firmy AMD jest ich ponad 620). Sprawę asemblera dla x86 komplikuje obecno¶ć dwóch składni: Intela i AT&T (istniej± automatyczne translatory), oraz to, że praktycznie w każdym systemie operacyjnym, w każdym języku programowania i kompilatorze szczegóły wykorzystania tego języka wygl±daj± inaczej.

Tryby pracy procesora

Kod może działać w trzech trybach pracy:
  • real-mode (tryb rzeczywisty) emuluj±c stare procesory 8086;
  • protected-mode (tryb chroniony) wykorzystuj± pełne możliwo¶ci danego modelu procesora;
  • virtual 86 (wirtualny 86) - tworzony jest wirtualny procesor 8086 w trybie protected, ów wirtualny procesor nie ma pełnej władzy nad sprzętem. Tryb wirtualny 86, pocz±wszy od Pentium 4, stał się atrybutem trybu chronionego. W praktyce ten tryb służy do uruchamiana starych programów DOS-owych – system Windows sam rozpoznaje typ aplikacji i ustawia odpowiedni tryb pracy, w systemie Linux do tego celu wykorzystywany jest emulator DOS – dosemu. Ze względu na tryb adresowania mówi się o kodzie 16-bitowym (najczę¶ciej wykorzystywanym w programach DOS-owych), w którym dostęp jest do pierwszego megabajta pamięci. W kodzie 32-bitowym tryb adresowania umożliwia dostęp do czterech gigabajtów pamięci. Istnieje jednak pewien bł±d w procesorach 80386 i nowszych, który pozwala – podczas pracy w trybie chronionym – na tak± manipulacj± strukturami wewnętrznymi procesora, że po przeł±czeniu procesora w tryb rzeczywisty istnieje możliwo¶ć dostępu do 4GB pamięci. Mówi się wówczas, że procesor pracuje w trybie unreal lub voodoo. Ponieważ ten trik został wykorzystany przez producentów BIOS firma Intel nie może poprawić tego błędu.

    Rejestry

    32-bitowe rejestry ogólnego przeznaczenia to:
  • eax – Accumulator (akumulator)
  • ebx – Base Register (rejestr bazowy)
  • ecx – Counter Register (rejestr licznikowy)
  • edx – Data Register
  • esp – Stack Pointer (wskaĽnik stosu)
  • ebp – Base Pointer
  • esi – Source Index
  • edi – Destination Index Możliwy jest też dostęp do ich 16-bitowych mniej znacz±cych czę¶ci – ax, bx, cx, dx, sp, bp, si, di, a w przypadku czterech pierwszych także do młodszego (low) i starszego bajtu (high) - odpowiednio al, ah, bl, bh, cl, ch, dl, dh. S± też dostępne rejestry segmentów:
  • cs – Code Segment (segment kodu)
  • ds – Data Segment (segment danych)
  • es – Extra Segment (dodatkowy segment danych)
  • ss – Stack Segment (segment stosu)
  • fs – dodatkowy rejestr segmentu
  • gs – dodatkowy rejestr segmentu Ponadto istniej±:
  • eflags – rejestr flag
  • eip – wskaĽnik instrukcji – rejestr wskazuj±cy na aktualnie wykonywan± instrukcję
  • rejestry kontrolne procesora crn (n – numer rejestru)
  • rejestry debuggera drn (n – numer rejestru);
  • osiem rejestrów FPU, oznaczanych w zależno¶ci od kompilatora jako st0... st7, 0... 7 lub st(0)... st(7);
  • rejestr kontrolny FPU

    Przykłady

    Pod tym linkiem znajduje się bardzo duży przykład pod Turbo Assembler (kompilator Borlanda dla DOS). Poniżej dwa małe przykłady pod Linuksa. Pierwszy można skompilować as z binutils (lub samym gcc je¶li ma on rozszerzenie .s), drugi programem nasm. Linkowanie w obu przypadkach gcc lub ręcznie.

    Przykład składni Intela - program "100 bottles of beer"

    global main
    extern printf
    
    section .data
    
    beer    db      "%d bottles of beer on the wall, %d bottles of beer."
    db      0x0a
    db      "Take one down and pass it around, %d bottles of beer."
    db      0x0a
    db      0
    
    main:
    mov ecx, 100
    
    _loop:
    dec  ecx
    push ecx
    push ecx
    inc  ecx
    push ecx
    push ecx
    push beer
    call printf
    add  esp,16
    pop  ecx
    or   ecx, ecx
    jne  _loop
    xor  eax,eax
    ret
    

    Przykład składni AT&T - ten sam program "100 bottles of beer"

    .section .rodata
    .beer:
    .ascii "%d bottles of Beer on the wall, %d bottles of Beer.\n"
    .asciz "Take one down and pass it around, %d bottles of Beer.\n"
    
    .text
    .global main
    main:
    
    mov $100, %ecx
    
    loop:
    dec   %ecx
    push  %ecx
    push  %ecx
    inc   %ecx
    push  %ecx
    push  %ecx
    pushl $.beer
    call  printf
    add   $16,%esp
    pop   %ecx
    or    %ecx, %ecx
    jne   loop
    xorl  %eax,%eax
    ret
    

    Chcesz wypromować swoj± stronę w internecie?? - nie zwlekaj pozycjonowanie w Luman.biz to rozs±dny wybór
    2005 Encyklopedia
    These materials are based onWikipedia and licensed under the GNU FDL
    Personal Loans|Cheap Car Insurance|Credit Card Debt Consolidation|Myspace Layouts|The eBay Song