Assembly/Aritmetikai műveletek

Összefoglalás

szerkesztés

Cél: 1-gyel megnövelni egy regiszter vagy egy memóriabeli változó értékét.

Használat:

inc reg/mem

Megjegyzések: Hatékonyabb, mint 1-et hozzáadni add-dal, ezért ha lehetséges, érdemes ezt használni.

Példák:

inc      eax                 ; eax := eax + 1
inc      dword [0aaaah]      ; A 0aaaah memóriaterületen lévő négy bájtos egész 1-gyel növekszik.

Cél: 1-gyel csökkenteni egy regiszter vagy egy memóriabeli változó értékét.

Használat:

dec reg/mem

Megjegyzések: Hatékonyabb, mint 1-et kivonni sub-bal, ezért ha lehetséges, érdemes ezt használni.

Példák:

dec       byte [x]      ; Az x memóriacímen lévő bájt 1-gyel csökken.

Cél: Valamilyen értéket hozzáadni egy regiszterhez vagy memóriabeli változóhoz.

Használat:

add      reg, reg/mem/konst
add      mem, reg/konst

Megjegyzések: Amint látható, nem lehet közvetlenül egy változóhoz egy másik változót hozzáadni. Ehhez először az egyiket be kell tölteni egy regiszterbe, és a regiszter értékét kell hozzáadni a másik memóriaterülethez. Egy ilyen értékadás tehát egy mov és egy add utasításból fog állni.

Példák:

add      eax, ebx      ; eax := eax + ebx

Az x memóriacímen lévő bájtot például a következőképpen tudjuk hozzáadni az y címen lévőhöz:

mov      al, [x]
add      [y], al

Cél: Egy értéket hozzáadni egy regiszterhez vagy változóhoz úgy, hogy az átviteli jelzőbit (carry flag) is hozzáadódik.

Használat:

adc      reg, reg/mem,/konst
adc      mem, reg/konst

Megjegyzések: Itt is érvényes az a megállapítás, hogy nem lehet közvetlenül összeadni két változót, hanem először az egyiket be kell olvasni egy regiszterbe, és a regiszter értékét kell hozzáadni a másikhoz. Ennek az utasításnak a segítségével kényelmesen implementálható összeadó művelet olyan nagy bitszélességű számokon, amelyeket az architektúra már nem támogat, például 64 bites architektúrákon a 128 bites összeadás (lásd lejjebb a kidolgozott példáknál).

Cél: Egy értéket kivonni egy regiszterből vagy egy változóból.

Használat:

sub      reg, reg/mem/konst
sub      mem, reg/konst

Megjegyzések: Hasonlóan az add-hoz nem lehet közvetlenül egy változóból egy másik változót kivonni. Ehhez először az egyiket be kell tölteni egy regiszterbe, és a regiszter értékét kell kivonni a másik változóból. Egy ilyen kivonás tehát egy mov és egy sub utasításból fog állni.

Példák:

dec      eax, ebx      ; eax := eax - ebx

Az x memóriacímen lévő bájtot vonjuk ki az y címen lévőből:

mov      al, [x]
sub      [y], al

Kidolgozott példák

szerkesztés

64 bites összeadás

szerkesztés

Feladat: 32 bites architekektúrán implementáljunk 64 bites összeadást. Számítsuk ki [x]+[y]-t [z]-be.

Megoldás: Egy 64 bites számot két 32 bites számmal tudunk reprezentálni. Az összeadást úgy végezzük, hogy először összeadjuk az alacsonyabb helyiértéken lévő 32 bites szavakat, aztán az adc művelet segítségével összeadjuk a magasabb helyiértéken lévő szavakat. Így egy utasítással az átvitel is hozzáadódik, és helyes eredményt kapunk.

mov      eax, [x]
add      eax, [y]
mov      [z], eax
mov      eax, [x+4]
adc      eax, [y+4]
mov      [z+4], eax