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