x86 32 bits Assembly Simulator

The aim of this site is to enable the user to test some x86 assembly instructions on the fly.

This page is still under development, if you find bugs, please report them to Jean-Michel Richer and indicate how to reproduce them.

The features of the interpretor are the following:

  • we use a subset of the x86 32 bits mnemonics (see x86 instructions table) with some SSE vector instructions (see x86 vector instructions table)
  • we have added some non x86 mnemonics (see non x86 instructions table)
  • operands of instructions are only general purpose registers or numerical constants, there is no reference to memory for the moment
  • numerical constants are suffixed with _h for hexadecimal, _b for binary, _o for octal and you can also use the character '_' as a separator. For example FF_FF_h is equivalent to 65_535 in decimal.
  • Only the CF, SF, OF and ZF flags are taken into account
  • to obtain help on an instruction use the mouse to highlight it in the editor and click on the F2 key, it will open a window with the description of the instruction.

To execute a program, you can :

  • click on Run and execute the whole program or click on Next to execute the program step by step

Note that if you modify the program and you want to execute it step by step you have to click first on the Reset button to take into account the modifications. The program will then start from the beginning.

Editor

General Purpose Registers

name binary hexadecimal signed decimal
eax 0000_0000_0000_0000_0000_0000_0000_0000 00_00_00_00 0
ebx 0000_0000_0000_0000_0000_0000_0000_0000 00_00_00_00 0
ecx 0000_0000_0000_0000_0000_0000_0000_0000 00_00_00_00 0
edx 0000_0000_0000_0000_0000_0000_0000_0000 00_00_00_00 0
esi 0000_0000_0000_0000_0000_0000_0000_0000 00_00_00_00 0
edi 0000_0000_0000_0000_0000_0000_0000_0000 00_00_00_00 0
flags

Signed decimal part displayed:

  • 8 bits low (al)
  • 8 bits high (ah)
  • 16 bits low (ax)
  • 32 bits (eax)

SSE Registers

registeruint323uint322uint321uint320
xmm00000
xmm10000
xmm20000
xmm30000
xmm40000
xmm50000
xmm60000
xmm70000
registerw7w6w5w4w3w2w1w0
xmm000000000
xmm100000000
xmm200000000
xmm300000000
xmm400000000
xmm500000000
xmm600000000
xmm700000000
registerb15b14b13b12b11b10b9b8b7b6b5b4b3b2b1b0
xmm00000000000000000
xmm10000000000000000
xmm20000000000000000
xmm30000000000000000
xmm40000000000000000
xmm50000000000000000
xmm60000000000000000
xmm70000000000000000
registerint323int322int321int320
xmm00000
xmm10000
xmm20000
xmm30000
xmm40000
xmm50000
xmm60000
xmm70000
registerw7w6w5w4w3w2w1w0
xmm000000000
xmm100000000
xmm200000000
xmm300000000
xmm400000000
xmm500000000
xmm600000000
xmm700000000
registerb15b14b13b12b11b10b9b8b7b6b5b4b3b2b1b0
xmm00000000000000000
xmm10000000000000000
xmm20000000000000000
xmm30000000000000000
xmm40000000000000000
xmm50000000000000000
xmm60000000000000000
xmm70000000000000000
registerx
xmm00
xmm10
xmm20
xmm30
xmm40
xmm50
xmm60
xmm70

Available x86 instructions

mnemonic format description examples meaning
adc rdst , rsrc|cst add source register or constant to destination register with carry from previous calculation adc eax, ecx
adc eax, 3
eax += ecx + (c)
eax += 3 + (c)
add rdst , rsrc|cst add source register or constant to destination register add eax, ecx
add eax, 3
eax += ecx
eax += 3
and rdst , rsrc|cst compute binary and and eax, ebx
and esi, 3
bsf rsrc , rsrc find least significant bit, if source register is zero then ZF is set to 1 otherwise ZF is set to 0 bsr eax,ebx eax = msb(ebx)
bsr rsrc , rsrc find most significant bit, if source register is zero then ZF is set to 1 otherwise ZF is set to 0 bsr eax,ebx eax = msb(ebx)
bt rdst , rsrc|cst bit test, test if bit given by source operand is set in destination register bt eax, 1
bt ebx, edx
btc rdst , rsrc|cst bit test and complement
-CF = bit given by source operand in destination register
- in destination register bit is complemented
btr eax, 1
btr ebx, edx
btr btr rdst , rsrc|cst bit test and reset
-CF = bit given by source operand in destination register
- in destination register bit is set to 0
btr eax, 1
btr ebx, edx
bts rdst , rsrc|cst bit test and set
-CF = bit given by source operand in destination register
- in destination register bit is set to 1
bts eax, 1
bts ebx, edx
cdq extends the sign bit of eax into the edx register cdq
clc clear carry flag CF clc CF=0
cmc complement carry flag cmc CF=not(CF)
cmp rsrc1 , rsrc2|cst compare src1 to src2 or constant, i.e. set flags from the result of src1 - src2 cmp eax, ebx
cmp edx, 5
eax <,=,> ebx
edx <,=,> 5
cwd extends the sign bit of ax into the dx register cwd
div rsrc divide respectively ax|dx:ax|edx:eax by source register depending on its size, get result in ah,al|dx,ax|edx,eax where ah,dx,edx contains the remainder div ecx edx:eax/ebx = eax
remainder in edx
ja label Jump Above for unsigned integers ja .l1 CF = 0 and ZF = 0
jae label Jump Above Or Equal for unsigned integers jae .l1 CF = 0
jb label Jump Below for unsigned integers jb .end CF = 1
jbe label Jump Below Or Equal for unsigned integers jbe .while CF = 1 or ZF = 1
jg label Jump if Greater for signed integers jg .l1 ZF = 0 and (SF = OF)
jge label Jump if Greater or Equal for signed integers jge .l1 SF = OF
jl label Jump if Less for signed integers jl .l1 SF != OF
jle label Jump if Less or Equal for signed integers jle .l1 ZF = 1 or (SF != OF)
jne label Jump if Not Equal jne .stop ZF=0
jns label Jump if Not Signed jns .positive SF = 0
jnz label Jump if Not Zero jnz .exit ZF=0
js label Jump if Signed bit set js .negative SF = 1
jz label Jump if Zero jz .end ZF=1
mov rdst , rsrc|cst assign source register or constant to destination register
flags are not affected
mov eax, ebx
mov eax, 1
eax = ebx
eax = 1
mul rsrc multiply respectively al|ax|eax by source register, get result in ax|dx:ax|edx:eax mul ebx edx:eax = eax*ebx
neg rdst compute two's complement of destination register, i.e. -1 becomes 1 and conversely
set CF to 1 if destination register is not 0
neg eax eax = -eax
not rdst compute one's complement of destination register not ecx
or rdst , rsrc|cst compute binary or or eax, edi
or edx, 7
sar rdst , cst shift destination register of constant bits on the right and preserve sign, this is equivalent to a signed division by 2cst sar eax, 31 if eax >= 0, 0
otherwise -1
sbb rdst , rsrc|cst substract source register or constant to destination register with borrow sbb ebx, edx
sbb edx, 2
ebx -= edx + (c)
edx -= 2 + (c)
shl rdst , cst shift destination register of constant bits on the left, this is equivalent to a multiplication by 2cst shl eax,3 eax *= 2^3
shr rdst , cst shift destination register of constant bits on the right, this is equivalent to a division by 2cst shr eax,2 eax /= 2^2
stc set carry flag CF stc CF=1
sub rdst , rsrc|cst substract source register or constant to destination register sub ebx, edx
sub edx, 2
ebx -= edx
edx -= 2
test rsrc1 , rsrc2|cst compare src1 to src2 or constant, i.e. set flags from the result of src1 and src2 test eax, eax
test edx, 5
eax =? 0
edx and 5 =? 0
xadd rdst , rsrc destination register is the sum of destination and source register but source register gets initial value of destination register xadd edx, eax eax = edx
edx += eax
xchg rdst , rsrc exchange values of source and destination registers xchg eax, ebx eax <-> ebx
xor rdst , rsrc|cst compute binary exclusive or xor eax, eax eax = 0

Available x86 vector instructions

mnemonic format description examples meaning
movd rdst|xmmi, rsrc|xmmj mov data from SSE register to general register and conversely movd eax, xmm2
movd xmm1, ecx
eax = xmm2.d[0]
xmm1.d[0] = ecx
movdqa xmmi , xmmj mov data from SSE source register to SSE destination register movdqa xmm1, xmm7 xmm1 = xmm7
paddd xmmi , xmmj vector addition of 16 bytes in parallel paddb xmm3, xmm4
paddd xmmi , xmmj vector addition of 4 double words in parallel paddd xmm0, xmm1
paddw xmmi , xmmj vector addition of 8 words in parallel paddw xmm2, xmm7
pmovmskb rdst , xmm mov most significant bit of each byte of SSE register to lowest 16 bits of general purpose register pmovmskb eax, xmm0
pshufd xmmi , xmmj , cst parallel/packed shuffle pshufd xmm0, xmm1, 93_h

Available non x86 instructions

mnemonic format description examples meaning
assertf flag , 0|1 check if flag (CF, OF, SF, ZF) has given value, if no generate an exception check CF, 0
check ZF, 1
CF ?= 0
ZF ?= 1
assertr rdst , rsrc|cst check if destination register has given value, if no generate an exception assertr eax, ebx
assertr eax, 1
eax ?= ebx
eax ?= 1
ldv1d xmmi , cst0,...,cst3 load four 32 bits signed integers into a SSE register ld4sdw xmm0, 1,2,-1,-2
ldv4d xmmi , cst0,...,cst3 load four 32 bits signed integers into a SSE register ld4sdw xmm0, 1,2,-1,-2
signdec type change signed decimal value reported where type can be -8 (al,bl,cl,dl), 8 (ah,bh,ch,dh), 16 (ax,bx,cx,dx,si,di), 32 (eax, ...) signdec -8 -
st1dv rdst , xmmi, rsrc store in destination register the double word from SSE register at position given by source register, note that source register should only contain 0, 1, 2 or 3 st1dv eax, xmm2, ebx eax = xmm.d[ebx]