Chapter 10 - Arithmetic

10.1  Integer Arithmetic

The table below lists the arithmetic operations.  Since the printf command overwrites registers eax, ecx, and edx, you need to store the results into variables. 

In add, CF (carry flag) is set if there is an overflow.  In sub, CF is set if there is a carry.  In imul, the CF and OF (overflow) flags may be set.

Command Description
add eax, ebx Adds value in ebx to the value in eax
add eax, [A] Adds value in variable A to eax
add eax, 32 Add 32 to eax
add [A], 5 Add 5 to variable A
sub eax, ebx Subtracts ebx from eax
sub eax, [A] Subtracts variable A from eax
inc eax Add 1 to eax
inc [A] Add 1 to variable A
dec eax Subtract 1 from eax
dec [A] Subtract 1 from variable A
neg [A] Negates (switches) the sign of variable A
imul eax, ebx Multiplies ebx to eax
imul eax, [A] Multiplies variable A to eax
imul eax, 5 Multiplies eax by 5
idiv [B] Divides 8 byte edx:eax by variable B.  Quotient is stored and eax and remainder in edx.

The program below demonstrates integer division.  The idiv command divides 8 byte edx:eax by ebx.  The quotient is stored in eax and remainder in edx.  These may need to be stored into variables Quotient and Remainder since the printf command overwrites some of the registers.  The cdq instruction converts a 32-bit doubleword in eax to 64-bit quadword in edx:eax by extending the sign bit of eax into edx.

divide.asm

format PE console
include 'win32ax.inc'

;=======================================
section '.code' code readable executable
;=======================================
start:
        mov eax, [A]
        cdq           ;convert eax to 64-bit quad word edx:eax
        idiv [B]
        mov [Quotient], eax
        mov [Remainder], edx 
        cinvoke printf,"%d / %d = %d remainder %d %c",[A],[B],[Quotient],[Remainder],10
        invoke Sleep,-1

;======================================
section '.data' data readable writeable
;======================================
A       dd 50
B       dd 8
Quotient  dd 0
Remainder dd 0

;====================================
section '.idata' import data readable
;====================================
library msvcrt,'msvcrt.dll',kernel32,'kernel32.dll'
import msvcrt,printf,'printf'
import kernel32,Sleep,'Sleep'

Output

50 / 8 = 6 remainder 2


10.2  Floating-Point Arithmetic

TBA
 

10.3  Random Numbers

The program below demonstrates how to use the C++ rand(), srand(), and time() functions to generate a random numbers from 0 to 9.

divide.asm

format PE console
include 'win32ax.inc'

;=======================================
section '.code' code readable executable
;=======================================
start:
        cinvoke time,0           ;call time() - returns Epoch time in eax
        cinvoke srand, eax       ;call srand() with Epoch time
        cinvoke rand             ;call rand() - returns random integer in eax
        mov edx, 0
        mov ebx, 10
        idiv ebx                 ;divide eax:edx by 10 and put remainder in edx
        cinvoke printf, "Random number from 0-9:   %d %c", edx, 10
        cinvoke rand
        mov edx, 0
        mov ebx, 10
        idiv ebx
        cinvoke printf, "Random number from 0-9:   %d %c", edx, 10
        cinvoke rand
        mov edx, 0
        mov ebx, 10
        idiv ebx
        cinvoke printf, "Random number from 0-9:   %d %c", edx, 10
        invoke Sleep,-1

;====================================
section '.idata' import data readable
;====================================
library msvcrt,'msvcrt.dll',kernel32,'kernel32.dll'
import msvcrt,printf,'printf',scanf,'scanf',fscanf,'fscanf',rand,'rand',srand,'srand',time,'time'
import kernel32,Sleep,'Sleep'

Output

Random number from 0-9: 8
Random number from 0-9: 3
Random number from 0-9: 7