Kihagyás

9. gyakorlat

Mi a ~~[tetszőleges káromkodás]~~ péklapátért pont Assembly?

"Mert hozzátartozik a programozói műveltséghez!"

Assemblyben vannak olyanok, hogy regiszterek

Regiszter - olyan gyors, hogy nem is a RAM-ban van, hanem a processzorban

  • eax (32 bites)
    • ax (az eax felső 16 bitje)
    • al (az ax/eax felső 8 bitje)
|               eax                |
                 |       ax        |
                          |   al   |
00000000 00000000 00000000 00000000

Ugyan ezek működnek a helyett b-vel, c-vel és d-vel.

esp - stack pointer

call read_natural ; Az értéke az eax-be landol
inc eax

push eax ; write_natural paraméterét feldobjuk a stack-re
call write_natural
add esp,4 ; csökkentjük 4 bájttal a stack méretét 4 bájttal, ezzel effektive kitörölni az előbb pusholt értéket

mov eax,0
ret
  • call - procedúra hívás
  • inc - inkrementálás
  • push <reg a> - a regiszter tartalmát push a stack-re
  • pop <reg a> - stackről leveszi a legfelső elemet az a regiszerbe
  • mov <reg a> <reg b> - a b regiszter tartalmát átrakja az a regiszterbe
  • add <reg a> <reg b> - az a és b regisztereket összeadja, majd az a regiszterben tárolja
  • sub <reg a> <reg b> - az a és b regisztereket kivonja, majd az a regiszterben tárolja
  • mul <reg a> - az eax regiszer tartalmát beszorozza az a regiszer tartalmával.
  • div <reg a> - az eax regiszer tartalmát beszorozza az a regiszer tartalmával. Az eax-be kerül a hányados, az edx-be a maradék.
  • not <reg a> - BIT-SZERINTI negálás
  • xor <reg a>,1 - xor 1-el, tehát a legkisebb helyiértékű bit cseréje. Hasznos boolean értékekhez

Assembly buildelése:

nasm -felf inc.asm # Létrehoz egy inc.o fájl
gcc -m32 io.c inc.o # összefabrikálja az inc.o és io.c fájlt egy futtatható fájllá

Ha nem a stack-re szeretnénk rakni az értékeket, foglalhatunk le nekik memóriát is:

section .bss ;block starting storage, according to Arnold

a resd 1 ; reserve double sized, 1 db
b resd 1

section .text
; ...
call read_natural
mov [a],eax ; szögletes zárójel: adott MEMÓRIAHELYEN lévő érték (olyan mint a C-ben a csillag. így `a` gyakorlatilag egy pointer)
call read_natural
mov [b],eax

Ha már itt tartunk, legtöbb instruction-nek meg lehet adni indirekt címlekérdezést is (a szögletes zárójelek) általában csak egy ilyet lehet megadni egy instructionnek.

Miért is használunk regisztereket?

add [a],[b] ; nagyon nem. Invalid combination of opcode and operands

A következő nem működik: mul [b]. Miért? Mert nem tudja, hogy b egy mekkora méretű konstrukcióra mutat. Megadhatjuk a mul-nak a szükséges méretet: mul dword [b].

Boolean

A boolean csak egy sima bájtban van tárolva. Így itt az al és bl etc. regisztereket használjuk, illetve memória rezervációkor resb-t.

Ennek ellenére, mivel a stacken a legkisebb tárolható érték 16 bit (2 bájt), al helyett ax-t pusholjuk a veremre.

  • cmp <reg a>, <reg b> - beállítja a speciális regisztereket (pl. a "nulla" regisztert, ha a és b regiszterek megegyeznek)
  • jne <pointer> - a megadott címre ugrik, ha a nulla regiszter nincs beállítva