YouTip LogoYouTip

Assembly Arithmetic

Assembly Language - Arithmetic Instructions

\\\\n\\\\n

Arithmetic instructions are the foundation of mathematical operations executed by the CPU. This chapter provides a detailed introduction to addition, subtraction, multiplication, division, and related carry operations in the x86 architecture.

\\\\n\\\\n
\\\\n\\\\n

ADD - Addition Instruction

\\\\n\\\\n

ADD adds the source operand and destination operand, storing the result in the destination operand.

\\\\n\\\\n

Example

\\\\n\\\\n
; File path: add_demo.asm\\\\n\\\\n; ADD Instruction example:Calculate 100 + 200 + 300\\\\n\\\\nsection.data\\\\n\\\\n a dd 100\\\\n\\\\n b dd 200\\\\n\\\\n c dd 300\\\\n\\\\n sum dd 0\\\\n\\\\nsection.text\\\\n\\\\nglobal _start\\\\n\\\\n_start:\\\\n\\\\n; Method 1: Register += Immediatei.e.number\\\\n\\\\nmov eax,; eax = 100\\\\n\\\\nadd eax,200; eax = 100 + 200 = 300\\\\n\\\\n; Method 2: Register += Register\\\\n\\\\nmov ebx,; ebx = 200\\\\n\\\\nadd eax,ebx; eax = 300 + 200 = 500\\\\n\\\\n; Method 3: Register += RAM\\\\n\\\\nadd eax,; eax = 500 + 300 = 800\\\\n\\\\n; Store result\\\\n\\\\nmov,eax; sum = 800\\\\n\\\\n; Impact of Addition on Flag Characters\\\\n\\\\nmov eax,0xFFFFFFFF; eax = Largest 32 characters unsigned number\\\\n\\\\nadd eax,1; eax = 0(overflow wraparound)\\\\n\\\\n; CF = 1(produces Carry)characters)\\\\n\\\\n; ZF = 1(Resultis 0)\\\\n\\\\n; OF = 0(No overflow from signed perspective)\\\\n\\\\nmov eax,1\\\\n\\\\nmov ebx,0\\\\n\\\\nint 0x80
\\\\n\\\\n
\\\\n\\\\n

SUB - Subtraction Instruction

\\\\n\\\\n

SUB subtracts the source operand from the destination operand, storing the result in the destination operand.

\\\\n\\\\n

Example

\\\\n\\\\n
; File path: sub_demo.asm\\\\n\\\\n; SUB Instruction example\\\\n\\\\nsection.data\\\\n\\\\n x dd 1000\\\\n\\\\n y dd 300\\\\n\\\\nsection.text\\\\n\\\\nglobal _start\\\\n\\\\n_start:\\\\n\\\\n; Basic subtraction\\\\n\\\\nmov eax,; eax = 1000\\\\n\\\\nsub eax,; eax = 1000 - 300 = 700\\\\n\\\\n; Impact of Subtraction on Flag Characters\\\\n\\\\nmov eax,10\\\\n\\\\nsub eax,20; eax = -10(i.e. 0xFFFFFFF6)\\\\n\\\\n; CF = 1(Generates borrow characters: 10 < 20)\\\\n\\\\n; SF = 1(ResultisNegative)\\\\n\\\\n; ZF = 0(ResultNon-zero)\\\\n\\\\n; OF = 0(Unsigned overflow)\\\\n\\\\n; Subtract from itself: commonly used to zero out\\\\n\\\\nmov eax,12345\\\\n\\\\nsub eax,eax; eax = 0\\\\n\\\\n; ZF = 1, CF = 0\\\\n\\\\n; This is a classic method to zero out a SetRegister (Compare mov eax, 0 Efficiency High)\\\\n\\\\nmov eax,1\\\\n\\\\nmov ebx,0\\\\n\\\\nint 0x80
\\\\n\\\\n
\\\\n

sub eax, eax is a classic trick to zero out a register. It only takes 2 bytes, while mov eax, 0 takes 5 bytes. It is commonly used in scenarios requiring extreme size optimization (such as shellcode).

\\\\n
\\\\n\\\\n
\\\\n\\\\n

INC / DEC - Increment/Decrement Instructions

\\\\n\\\\n

Simpler instructions for adding or subtracting 1 compared to ADD/SUB:

\\\\n\\\\n

Example

\\\\n\\\\n
; INC and DEC Example\\\\n\\\\nsection.data\\\\n\\\\n counter dd 0\\\\n\\\\nsection.text\\\\n\\\\nglobal _start\\\\n\\\\n_start:\\\\n\\\\nmov dword,0; counter = 0\\\\n\\\\ninc dword; counter = 1(RAMOperand)\\\\n\\\\ninc dword; counter = 2\\\\n\\\\nmov ecx,10\\\\n\\\\ndec ecx; ecx = 9\\\\n\\\\ndec ecx; ecx = 8\\\\n\\\\n; INC/DEC Does not affect the CF flag characters (this is an important difference from ADD/SUB)\\\\n\\\\n; But will affect ZF, SF, OF, PF\\\\n\\\\n; Use INC in loop\\\\n\\\\nmov ecx,5\\\\n\\\\nmov eax,0\\\\n\\\\n loop_inc:\\\\n\\\\ninc eax; eax Every time add 1\\\\n\\\\nloop loop_inc ; Repeat 5 times, eax final = 5\\\\n\\\\nmov ebx,eax; Return Value = 5\\\\n\\\\nmov eax,1\\\\n\\\\nint 0x80
\\\\n\\\\n
\\\\n\\\\n

MUL - Unsigned Multiplication

\\\\n\\\\n

MUL performs unsigned multiplication. The rules for multiplication are somewhat special:

\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n
Operand SizeMultiplierMultiplicand (Implicit)Result Storage
1 byteAny 8-bit register or memoryALAX = AL × operand
2 bytesAny 16-bit register or memoryAXDX:AX = AX × operand
4 bytesAny 32-bit register or memoryEAXEDX:EAX = EAX × operand
\\\\n\\\\n

Example

\\\\n\\\\n
; File path: mul_demo.asm\\\\n\\\\n; MUL Unsigned multiplication example\\\\n\\\\nsection.data\\\\n\\\\n val1 dd 1000\\\\n\\\\n val2 dd 2000\\\\n\\\\n result_low dd 0\\\\n\\\\n result_high dd 0\\\\n\\\\nsection.text\\\\n\\\\nglobal _start\\\\n\\\\n_start:\\\\n\\\\n; 32 charactersMultiplication: EDX:EAX = EAX × Operands\\\\n\\\\nmov eax,; eax = 1000\\\\n\\\\nmul dword; edx:eax = 1000 × 2000 = 2,000,000\\\\n\\\\n; Result = 2,000,000 = 0x001E8480\\\\n\\\\n; EAX = 0x001E8480(Low 32 characters)\\\\n\\\\n; EDX = 0x00000000(High 32 characters,Due to / SinceisResultdoes not exceed 32 bits) characters)\\\\n\\\\n; Large number multiplication demonstration (Result exceeds 32 characters)\\\\n\\\\nmov eax,0xFFFFFFFF; eax = 4,294,967,295\\\\n\\\\nmov ebx,2; ebx = 2\\\\n\\\\nmul ebx; edx:eax = 0xFFFFFFFF × 2\\\\n\\\\n; EAX = 0xFFFFFFFE\\\\n\\\\n; EDX = 0x00000001(High 32 characters)\\\\n\\\\n; CF = 1(ResultExceeds 32 characters)\\\\n\\\\n; Store Result\\\\n\\\\nmov,eax\\\\n\\\\nmov,edx\\\\n\\\\nmov eax,1\\\\n\\\\nmov ebx,0\\\\n\\\\nint 0x80
\\\\n\\\\n
\\\\n\\\\n

IMUL - Signed Multiplication

\\\\n\\\\n

IMUL is used for multiplication of signed numbers and has three forms:

\\\\n\\\\n

Example

\\\\n\\\\n
; File path: imul_demo.asm\\\\n\\\\n; IMUL Signed multiplication example\\\\n\\\\nsection.data\\\\n\\\\n a dd-100\\\\n\\\\n b dd 3\\\\n\\\\nsection.text\\\\n\\\\nglobal _start\\\\n\\\\n_start:\\\\n\\\\n; SingleOperandsFormat: same as MUL\\\\n\\\\nmov eax,; eax = -100\\\\n\\\\nimul dword; edx:eax = -100 × 3 = -300\\\\n\\\\n; EAX = -300(0xFFFFFED4)\\\\n\\\\n; EDX = 0xFFFFFFFF(Sign extension)\\\\n\\\\n; Two-Operand form: reg = reg × Operands\\\\n\\\\nmov ebx,; ebx = -100\\\\n\\\\nimul ebx,; ebx = -100 × 3 = -300\\\\n\\\\n; ResultMust fit within 32 characters\\\\n\\\\n; Three-Operand form: reg = Operand 1 × Immediatei.e.number\\\\n\\\\nimul ecx,,5; ecx = -100 × 5 = -500\\\\n\\\\nmov eax,1\\\\n\\\\nmov ebx,0\\\\n\\\\nint 0x80
\\\\n\\\\n
\\\\n

The main difference between MUL and IMUL is how they handle signs: MUL interprets operands as unsigned numbers, while IMUL interprets them as signed numbers. For example, 0xFFFFFFFF is 4294967295 in MUL but -1 in IMUL.

\\\\n
\\\\n\\\\n
\\\\n\\\\n

DIV - Unsigned Division

\\\\n\\\\n

DIV performs unsigned division, with rules symmetric to MUL:

\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n
Divisor SizeDividend (Implicit)QuotientRemainder
1 byteAXALAH
2 bytesDX:AXAXDX
4 bytesEDX:EAXEAXEDX
\\\\n\\\\n

Example

\\\\n\\\\n
; File path: div_demo.asm\\\\n\\\\n; DIV Unsigned division example\\\\n\\\\nsection.data\\\\n\\\\n dividend dd 1000\\\\n\\\\n divisor dd 7\\\\n\\\\n quotient dd 0\\\\n\\\\n remainder dd 0\\\\n\\\\nsection.text\\\\n\\\\nglobal _start\\\\n\\\\n_start:\\\\n\\\\n; 32 charactersDivision: edx:eax / Divisor\\\\n\\\\n; Dividend Divisorneeds to be extended to EDX first:EAX\\\\n\\\\nmov eax,; eax = 1000\\\\n\\\\nmov edx,0; edx = 0(High 32 charactersZero out)\\\\n\\\\ndiv dword; edx:eax / 7\\\\n\\\\n; EAX = 142(Quotient)\\\\n\\\\n; EDX = 6(Remainder: 1000 = 142×7 + 6)\\\\n\\\\nmov,eax; quotient = 142\\\\n\\\\nmov,edx; remainder = 6\\\\n\\\\n; Byte division example: 55 / 4\\\\n\\\\nmov ax,55; Dividend Divisor\\\\n\\\\nmov bl,4; Divisor\\\\n\\\\ndiv bl; al = 13(Quotient), ah = 3(Remainder)\\\\n\\\\nmov eax,1\\\\n\\\\nmov ebx,0\\\\n\\\\nint 0x80
\\\\n\\\\n
\\\\n

Before performing division, always clear EDX with mov edx, 0 or xor edx, edx! If EDX contains old data, the dividend value will be incorrect. This is the most common division bug for beginners.

\\\\n
\\\\n\\\\n
\\\\n\\\\n

IDIV - Signed Division

\\\\n\\\\n

IDIV is used for signed division. Before division, use the CDQ instruction to sign-extend EAX into EDX:EAX:

\\\\n\\\\n

Example

\\\\n\\\\n
; IDIV Signed division example\\\\n\\\\n; Calculate -100 / 3\\\\n\\\\nmov eax,-100; eax = -100\\\\n\\\\ncdq; Sign extension: edx:eax = -100\\\\n\\\\n; cdq Set eax Sign of characters copied to all characters of edx\\\\n\\\\nmov ebx,3; Divisor\\\\n\\\\nidiv ebx; eax = -33(Quotient), edx = -1(Remainder)\\\\n\\\\n; Verification: -100 = -33 × 3 + (-1)
\\\\n\\\\n
\\\\n\\\\n

ADC / SBB - Add/Subtract with Carry/Borrow

\\\\n\\\\n

Used for large number operations (data exceeding 32 bits):

\\\\n\\\\n

Example

\\\\n\\\\n
; File path: adc_sbb_demo.asm\\\\n\\\\n; 64 charactersaddmethod:two 64 charactersnumberAdd\\\\n\\\\nsection.data\\\\n\\\\n; 64 charactersOperand a = 0x00000001 FFFFFFFF\\\\n\\\\n a_low dd 0xFFFFFFFF\\\\n\\\\n a_high dd 0x00000001\\\\n\\\\n; 64 charactersOperand b = 0x00000000 00000005\\\\n\\\\n b_low dd 0x00000005\\\\n\\\\n b_high dd 0x00000000\\\\n\\\\n; Result\\\\n\\\\n result_low dd 0\\\\n\\\\n result_high dd 0\\\\n\\\\nsection.text\\\\n\\\\nglobal _start\\\\n\\\\n_start:\\\\n\\\\n; Low 32 charactersAdd\\\\n\\\\nmov eax,\\\\n\\\\nadd eax,; eax = 0xFFFFFFFF + 5 = 0x00000004\\\\n\\\\n; CF = 1(Generates Carry characters!)\\\\n\\\\nmov,eax; result_low = 0x00000004\\\\n\\\\n; High 32 charactersaddCarrycharacters\\\\n\\\\nmov eax,\\\\n\\\\nadc eax,; adc = add + CF\\\\n\\\\n; eax = 1 + 0 + 1(Carry characters) = 2\\\\n\\\\nmov,eax; result_high = 2\\\\n\\\\n; Final 64-bit result: 0x00000002 00000004\\\\n\\\\n; Verification: 0x1FFFFFFF + 5 = 0x200000004\\\\n\\\\n; SBB Subtraction similarly (with borrow characters)\\\\n\\\\nmov eax,\\\\n\\\\nsub eax,; Low 32 charactersSubtract\\\\n\\\\nmov,eax\\\\n\\\\nmov eax,\\\\n\\\\nsbb eax,; sbb = sub - CF\\\\n\\\\nmov eax,1\\\\n\\\\nmov ebx,0\\\\n\\\\nint 0x80
\\\\n\\\\n
\\\\n\\\\n

Arithmetic Instructions Quick Reference

\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n
InstructionFormatFunctionAffected Flags
ADDadd dest, srcdest = dest + srcCF, ZF, SF, OF, PF
SUBsub dest, srcdest = dest - srcCF, ZF, SF, OF, PF
INCinc destdest = dest + 1ZF, SF, OF, PF (does not affect CF)
DECdec destdest = dest - 1ZF, SF, OF, PF (does not affect CF)
MULmul srcUnsigned multiplicationCF, OF
IMULimul srcSigned multiplicationCF, OF
DIVdiv srcUnsigned divisionUndefined
IDIVidiv srcSigned divisionUndefined
ADCadc dest, srcdest = dest + src + CFCF, ZF, SF, OF, PF
SBBsbb dest, srcdest = dest - src - CFCF, ZF, SF, OF, PF
NEGneg destdest = -dest (negate)CF, ZF, SF, OF, PF
← Assembly ConditionAssembly Variables →