Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 7838 → Rev 7839

/programs/develop/fasm/trunk/parser.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/fasm.txt
File deleted
/programs/develop/fasm/trunk/fasm.asm
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/x86_64.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/avx.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/symbdump.inc
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/exprcalc.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/build_ru.bat
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/exprpars.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/whatsnew.txt
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/messages.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/tables.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/formats.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/errors.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/build_en.bat
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/preproce.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/Tupfile.lua
File deleted
/programs/develop/fasm/trunk/system.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/variable.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/version.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/fasm.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/license.txt
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/trunk/assemble.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/programs/develop/fasm/1.71/fasm.asm
0,0 → 1,770
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; flat assembler source ;;
;; Copyright (c) 1999-2012, Tomasz Grysztar ;;
;; All rights reserved. ;;
;; ;;
;; KolibriOS port by KolibriOS Team ;;
;; Menuet port by VT ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
NORMAL_MODE = 8
CONSOLE_MODE = 32
 
MAGIC1 = 6*(text.line_size-1)+14
MAX_PATH = 100
 
DEFAULT_WIN_W = 450
DEFAULT_WIN_H = 350
LINE_H = 25
RIGHT_BTN_W = 80
 
APP_MEMORY = 0x00800000
 
;; Menuet header
 
appname equ "flat assembler "
;---------------------------------------------------------------------
use32
org 0x0
db 'MENUET01' ; 8 byte id
dd 0x01 ; header version
dd START ; program start
dd program_end ; program image size
dd stacktop ; required amount of memory
dd stacktop ; stack
dd params,cur_dir_path ; parameters,icon
;---------------------------------------------------------------------
include 'lang.inc'
include '../../../macros.inc'
purge add,sub ; macros.inc does incorrect substitution
include 'fasm.inc'
 
include '../../../develop/libraries/box_lib/trunk/box_lib.mac'
include '../../../develop/libraries/box_lib/load_lib.mac'
@use_library
 
center fix true
;---------------------------------------------------------------------
START: ; Start of execution
mov edi, fileinfos
mov ecx, (fileinfos_end-fileinfos)/4
or eax, -1
rep stosd
push 68
pop eax
push 11
pop ebx
mcall
 
cmp [params],0
jz start_1
;---------GerdtR
or ecx,-1
mov esi,params
cmp byte[esi],' '
jne @f
mov edi,esi
mov al,' '
repe scasb
mov esi,edi
dec esi
@@:
 
mov edi,dbgWord
@@: lodsb
scasb
jne NoOutDebugInfo
cmp byte[edi],0
jnz @b
 
cmp byte[esi],' '
jne NoOutDebugInfo
 
mov edi,esi
mov al,' '
repe scasb
mov esi,edi
dec esi
 
mov edi,params
@@: lodsb
stosb
test al,al
jnz @b
 
; mov [bGenerateDebugInfo], 1
or dword[ch1_dbg.flags],10b
 
 
NoOutDebugInfo:
;---------/GerdtR
 
 
 
 
mov ecx,10
mov eax,' '
mov edi,infile
push ecx
cld
rep stosd
mov ecx,[esp]
mov edi,outfile
rep stosd
pop ecx
mov edi,path
rep stosd
mov esi,params
; DEBUGF "params: %s\n",esi
mov edi,infile
call mov_param_str
; mov edi,infile
; DEBUGF " input: %s\n",edi
mov edi,outfile
call mov_param_str
; mov edi,outfile
; DEBUGF "output: %s\n",edi
mov edi,path
call mov_param_str
; mov edi,path
; DEBUGF " path: %s\n",edi
dec esi
cmp [esi], dword ',run'
jne @f
mov [_run_outfile],1
@@:
cmp [esi], dword ',dbg'
jne @f
mov [_run_outfile],2
@@:
mov [_mode],CONSOLE_MODE
jmp start
;---------------------------------------------------------------------
start_1:
;sys_
load_libraries l_libs_start,load_lib_end
 
cmp eax,-1
jne @f
mcall -1 ;exit if not open box_lib.obj
@@:
mcall 40,0x80000027 ;¬ áª  á¨á⥬­ëå ᮡë⨩
;---------------------------------------------------------------------
init_checkboxes2 ch1_dbg,ch1_dbg+ch_struc_size
;---------------------------------------------------------------------
; OpenDialog initialisation
push dword OpenDialog_data
call dword [OpenDialog_Init]
;---------------------------------------------------------------------
red: ; Redraw
call draw_window
 
still:
mcall 10 ; Wait here for event
cmp al,6
je call_mouse
dec eax
je red ; Redraw request
dec eax
jne button ; Button in buffer
key: ; Key
mcall 2 ; Read it and ignore
push dword edit1
call [edit_box_key]
push dword edit2
call [edit_box_key]
push dword edit3
call [edit_box_key]
jmp still
;---------------------------------------------------------------------
call_mouse:
call mouse
jmp still
;---------------------------------------------------------------------
button: ; Button in Window
mcall 17
cmp ah,1
jne noclose
or eax,-1
mcall
;---------------------------------------------------------------------
noclose:
cmp ah,5 ;press button for OpenDialog
jne @f
call fun_opn_dlg
@@:
cmp ah,2 ; Start compiling
je start
cmp ah,3 ; Start compiled file
jnz norunout
mov edx,outfile
call make_fullpaths
mcall 70,file_info_start
; xor ecx,ecx
jmp still
;---------------------------------------------------------------------
norunout:
cmp ah,4
jnz norundebug
mov edx,outfile
call make_fullpaths
mcall 70,file_info_debug
jmp still
;---------------------------------------------------------------------
norundebug:
jmp still
;---------------------------------------------------------------------
mouse:
push dword edit1
call [edit_box_mouse]
push dword edit2
call [edit_box_mouse]
push dword edit3
call [edit_box_mouse]
push dword ch1_dbg
call [check_box_mouse]
ret
;---------------------------------------------------------------------
draw_window:
pusha
mcall 12,1 ; Start of draw
get_sys_colors 1,0
edit_boxes_set_sys_color edit1,editboxes_end,sc
;check_boxes_set_sys_color2 ch1_dbg,ch1_dbg+ch_struc_size,sc
mov eax,[sc.work_text]
or eax, 0x90000000
mov [ch1_dbg.text_color], eax
m2m [ch1_dbg.border_color], [sc.work_graph]
 
mov edx,[sc.work]
or edx,0x33000000
xor eax,eax
xor esi,esi
mcall ,<150,DEFAULT_WIN_W>,<150,DEFAULT_WIN_H>,edx,,title
 
mcall 9,PROCESSINFO,-1
 
mov eax,[PROCESSINFO+70] ;get status of window
test eax,100b
jne .end
 
WIN_MIN_W = 350
WIN_MIN_H = 300
 
cmp dword[pinfo.client_box.width],WIN_MIN_W
jge @f
mcall 67,-1,-1,WIN_MIN_W+20,-1
jmp .end
@@:
cmp dword[pinfo.client_box.height],WIN_MIN_H
jge @f
mcall 67,-1,-1,-1,WIN_MIN_H+50
jmp .end
@@:
mpack ebx,[pinfo.client_box.width],RIGHT_BTN_W
msub ebx,RIGHT_BTN_W+1,0
mcall 8,ebx,<LINE_H*0+3,LINE_H-4>,ID_COMPILE_BTN,[sc.work_button]
mcall ,ebx,<LINE_H*1+3,LINE_H-4>,ID_EXECUTE_BTN
mcall ,ebx,<LINE_H*2+3,LINE_H-4>,ID_EXECDBG_BTN
mcall ,<5,62>,<LINE_H*2+3,LINE_H-5>,ID_OPENDLG_BTN
 
mov ecx, [sc.work_text]
or ecx, $10000000
mcall 4,<6,LINE_H*0+6>,,text+text.line_size*0,text.line_size ;InFile
mcall ,<6,LINE_H*1+6>,,text+text.line_size*1,esi ;OutFile
mov ecx, [sc.work_button_text]
or ecx, $10000000
mcall ,<0,LINE_H*2+6>,,text+text.line_size*2,esi ;Path
 
mov ebx,[pinfo.client_box.width]
sub ebx,RIGHT_BTN_W-12
shl ebx,16
add ebx,LINE_H/2-6
mov ecx, [sc.work_button_text]
or ecx, $10000000
mcall ,ebx,ecx,s_compile,7
add ebx,LINE_H
mcall ,ebx,ecx,s_run
add ebx,LINE_H
mcall ,ebx,ecx,s_debug
mpack ebx,MAGIC1+6,1+ 14/2-3+ 14*0
mov esi,[pinfo.client_box.width]
sub esi,MAGIC1*2+6+3
mov eax,esi
mov cl,6
div cl
cmp al,MAX_PATH
jbe @f
mov al,MAX_PATH
@@:
movzx esi,al
 
call draw_messages
mov eax,dword [pinfo.client_box.width]
sub eax,[edit1.left]
sub eax,RIGHT_BTN_W+6
mov dword[edit1.width],eax ; óñòàíàâëèâàåì øèðèíó òåêñòîâûõ ïîëåé
mov dword[edit2.width],eax
mov dword[edit3.width],eax
push dword edit1
call [edit_box_draw]
push dword edit2
call [edit_box_draw]
push dword edit3
call [edit_box_draw]
push dword ch1_dbg
call [check_box_draw]
.end:
mcall 12,2 ; End of Draw
popa
ret
;---------------------------------------------------------------------
bottom_right dd ?
 
align 4
fun_opn_dlg: ;äã­ªæ¨ï ¤«ï ¢ë§®¢  OpenFile ¤¨ «®£ 
pushad
copy_path open_dialog_name,communication_area_default_path,library_path,0
mov [OpenDialog_data.type],0
 
xor al,al
mov edi,dword [edit3.text]
mov ecx,dword [edit3.max]
cld
repne scasb
cmp byte[edi-2],'/'
jne @f
mov byte[edi-2],0 ;¥á«¨ ¢ ª®­æ¥ ¯ã⨠¥áâì á«¥è, â® ¯ãâì 㪮à ç¨¢ ¥¬ ­  1 ᨬ¢®«
@@:
push dword OpenDialog_data
call dword [OpenDialog_Start]
cmp [OpenDialog_data.status],2
je @f
 
xor al,al
mov edi,dword [edit3.text]
mov ebx,edi ;copy text pointer
mov ecx,dword [edit3.max]
cld
repne scasb
cmp byte[edi-2],'/'
jne .no_slash
dec edi ;¥á«¨ ¢ ª®­æ¥ ¯ã⨠¥áâì á«¥è, â® ¯ãâì 㪮à ç¨¢ ¥¬ ­  1 ᨬ¢®«
.no_slash:
mov byte[edi-1],'/' ;áâ ¢¨¬ ¢ ª®­æ¥ ¯ã⨠᫥è
mov byte[edi],0 ;®â१ ¥¬ ¨¬ï ­ ©¤¥­­®£® ä ©« 
sub edi,ebx ;edi = strlen(edit3.text)
mov [edit3.size],edi
mov [edit3.pos],edi
 
push dword [OpenDialog_data.filename_area]
push dword edit1
call dword [edit_box_set_text]
 
push dword [OpenDialog_data.filename_area]
push dword edit2
call dword [edit_box_set_text]
 
mov esi,[edit2.text]
xor eax,eax
cld
.cycle:
lodsb
test eax,eax
jnz .cycle
 
sub esi,5
cmp esi,[edit2.text]
jle .short_fn
mov byte[esi],0
sub dword [edit2.size],4
sub dword [edit2.pos],4
 
.short_fn:
push dword edit1
call dword [edit_box_draw]
push dword edit2
call dword [edit_box_draw]
push dword edit3
call dword [edit_box_draw]
@@:
popad
ret
;---------------------------------------------------------------------
draw_messages:
mpack ebx,5,[pinfo.client_box.width]
sub ebx,9
mpack ecx,0,[pinfo.client_box.height]
madd ecx, LINE_H*4,-( LINE_H*4+5)
mov word[bottom_right+2],bx
mov word[bottom_right],cx
msub [bottom_right],7,11
add [bottom_right],7 shl 16 + 53
mcall 13,,,0xFeFefe ; clear work area
; draw top shadow
push ecx
mov cx,1
mov edx,0xDADEDA
mcall
; draw left shadow
pop ecx
push ebx
mov bx,1
mcall
pop ebx
_cy = 0
_sy = 2
_cx = 4
_sx = 6
push ebx ecx
mpack ebx,4,5
add bx,[esp+_cx]
mov ecx,[esp+_sy-2]
mov cx,[esp+_sy]
msub ecx,1,1
mcall 38,,,[sc.work_graph]
mov si,[esp+_cy]
add cx,si
shl esi,16
add ecx,esi
madd ecx,1,1
mcall
mpack ebx,4,4
mov esi,[esp+_sy-2]
mov si,cx
mov ecx,esi
mcall
mov si,[esp+_cx]
add bx,si
shl esi,16
add ebx,esi
madd ebx,1,1
mcall
pop ecx ebx
ret
;---------------------------------------------------------------------
; DATA
;---------------------------------------------------------------------
if lang eq ru
text:
db ' ‚å” ©«:'
.line_size = $-text
db '‚ë唠©«:'
db ' ãâì:'
;db 'x'
 
s_compile db 'Š®¬¯¨«.'
s_run db ' ã᪠'
s_debug db 'Žâ« ¤ª '
s_dbgdescr db '‘®§¤ ¢ âì ®â« ¤®ç­ãî ¨­ä®à¬ æ¨î',0
 
 
err_message_found_lib0 db '¥ ­ ©¤¥­  ¡¨¡«¨®â¥ª  box_lib.obj',0 ;áâப , ª®â®à ï ¡ã¤¥â ¢ áä®à¬¨à®¢ ­­®¬ ®ª­¥, ¥á«¨ ¡¨¡«¨®â¥ª  ­¥ ¡ã¤¥â ­ ©¤¥­ 
err_message_import0 db 'Žè¨¡ª  ¯à¨ ¨¬¯®à⥠¡¨¡«¨®â¥ª¨ box_lib.obj',0
err_message_found_lib1 db '¥ ­ ©¤¥­  ¡¨¡«¨®â¥ª  proc_lib.obj',0
err_message_import1 db 'Žè¨¡ª  ¯à¨ ¨¬¯®à⥠¡¨¡«¨®â¥ª¨ proc_lib.obj',0
head_f_i:
head_f_l db '‘¨á⥬­ ï ®è¨¡ª ',0 ;§ £®«®¢®ª ®ª­ , ¯à¨ ¢®§­¨ª­®¢¥­¨¨ ®è¨¡ª¨
else
text:
db ' InFile:'
.line_size = $-text
db 'OutFile:'
db ' Path:'
;db 'x'
 
s_compile db 'COMPILE'
s_run db ' RUN '
s_debug db ' DEBUG '
s_dbgdescr db 'Generate debug information',0
 
 
err_message_found_lib0 db 'Sorry I cannot found library box_lib.obj',0
err_message_import0 db 'Error on load import library box_lib.obj',0
err_message_found_lib1 db 'Sorry I cannot found library proc_lib.obj',0
err_message_import1 db 'Error on load import library proc_lib.obj',0
 
head_f_i:
head_f_l db 'System error',0 ;§ £®«®¢®ª ®ª­ , ¯à¨ ¢®§­¨ª­®¢¥­¨¨ ®è¨¡ª¨
end if
 
system_dir0 db '/sys/lib/'
lib0_name db 'box_lib.obj',0
 
system_dir1 db '/sys/lib/'
lib1_name db 'proc_lib.obj',0
;---------------------------------------------------------------------
align 4
import_box_lib:
edit_box_draw dd aEdit_box_draw
edit_box_key dd aEdit_box_key
edit_box_mouse dd aEdit_box_mouse
edit_box_set_text dd aEdit_box_set_text
;version_ed dd aVersion_ed
 
init_checkbox dd aInit_checkbox
check_box_draw dd aCheck_box_draw
check_box_mouse dd aCheck_box_mouse
;version_ch dd aVersion_ch
 
dd 0,0
 
aEdit_box_draw db 'edit_box',0
aEdit_box_key db 'edit_box_key',0
aEdit_box_mouse db 'edit_box_mouse',0
aEdit_box_set_text db 'edit_box_set_text',0
;aVersion_ed db 'version_ed',0
 
aInit_checkbox db 'init_checkbox2',0
aCheck_box_draw db 'check_box_draw2',0
aCheck_box_mouse db 'check_box_mouse2',0
;aVersion_ch db 'version_ch2',0
;---------------------------------------------------------------------
align 4
import_proc_lib:
OpenDialog_Init dd aOpenDialog_Init
OpenDialog_Start dd aOpenDialog_Start
dd 0,0
aOpenDialog_Init db 'OpenDialog_init',0
aOpenDialog_Start db 'OpenDialog_start',0
;---------------------------------------------------------------------
;library structures
l_libs_start:
lib0 l_libs lib0_name, cur_dir_path, library_path, system_dir0, err_message_found_lib0, head_f_l, import_box_lib, err_message_import0, head_f_i
lib1 l_libs lib1_name, cur_dir_path, library_path, system_dir1, err_message_found_lib1, head_f_l, import_proc_lib,err_message_import1, head_f_i
load_lib_end:
 
edit1 edit_box 153, 72, 3, 0xffffff, 0xA4C4E4, 0x80ff, 0, 0x10000000,(outfile-infile-1), infile, mouse_dd, 0, 11,11
edit2 edit_box 153, 72, LINE_H+3, 0xffffff, 0xA4C4E4, 0x80ff, 0, 0x10000000,(path-outfile-1), outfile, mouse_dd, 0, 7,7
edit3 edit_box 153, 72, LINE_H*2+3, 0xffffff, 0xA4C4E4, 0x80ff, 0, 0x10000000,(path_end-path-1), path, mouse_dd, 0, 6,6
editboxes_end:
ch1_dbg check_box2 (5 shl 16)+15, ((LINE_H*3+3) shl 16)+15, 6, 0xffffff, 0x80ff, 0x10000000, s_dbgdescr,ch_flag_top
;---------------------------------------------------------------------
align 4
OpenDialog_data:
.type dd 0
.procinfo dd pinfo ;+4
.com_area_name dd communication_area_name ;+8
.com_area dd 0 ;+12
.opendir_path dd path ;+16
.dir_default_path dd default_dir ;+20
.start_path dd library_path ;+24 ¯ãâì ª ¤¨ «®£ã ®âªàëâ¨ï ä ©«®¢
.draw_window dd draw_window ;+28
.status dd 0 ;+32
.openfile_path dd path ;+36 ¯ãâì ª ®âªà뢠¥¬®¬ã ä ©«ã
.filename_area dd filename_area ;+40
.filter_area dd Filter
.x:
.x_size dw 420 ;+48 ; Window X size
.x_start dw 10 ;+50 ; Window X position
.y:
.y_size dw 320 ;+52 ; Window y size
.y_start dw 10 ;+54 ; Window Y position
 
default_dir db '/rd/1',0 ;¤¨à¥ªâ®à¨ï ¯® 㬮«ç ­¨î
 
communication_area_name:
db 'FFFFFFFF_open_dialog',0
open_dialog_name:
db 'opendial',0
communication_area_default_path:
db '/rd/1/File managers/',0
 
Filter:
dd Filter.end - Filter
.1:
db 'ASM',0
.end:
db 0
;---------------------------------------------------------------------
mouse_dd dd 0 ;íóæíî äëÿ Shift-à â editbox
;---------------------------------------------------------------------
infile db 'example.asm'
times MAX_PATH-$+infile db 0
outfile db 'example'
times MAX_PATH-$+outfile db 0
path db '/rd/1//' ;OpenDialog ¯à¨ § ¯ã᪥ 㡨ࠥ⠯®á«¥¤­¨© á«¥è, ­® ¤¨ «®£ ¬®¦¥â ¨á¯®«ì§®¢ âìáï ­¥ ¢á¥£¤ , ¯®â®¬ã á«¥è  2
times MAX_PATH-$+path db 0
path_end:
lf db 13,10,0
;---------------------------------------------------------------------
mov_param_str:
cld
@@:
lodsb
cmp al,','
je @f
stosb
test al,al
jnz @b
@@:
xor al,al
stosb
ret
;---------------------------------------------------------------------
start:
cmp [_mode],NORMAL_MODE
jne @f
call draw_messages
mov [textxy],8 shl 16 + LINE_H*4+4
@@:
mov esi,_logo
call display_string
 
;---------------------------------------------------------------------
; Fasm native code
;---------------------------------------------------------------------
mov [input_file],infile
mov [output_file],outfile
call init_memory
call make_timestamp
mov [start_time],eax
call preprocessor
call parser
call assembler
bt dword[ch1_dbg.flags],1 ;cmp [bGenerateDebugInfo], 0
jae @f ;jz @f
call symbol_dump
@@:
call formatter
call display_user_messages
movzx eax,[current_pass]
inc eax
call display_number
mov esi,_passes_suffix
call display_string
call make_timestamp
sub eax,[start_time]
xor edx,edx
mov ebx,100
div ebx
or eax,eax
jz display_bytes_count
xor edx,edx
mov ebx,10
div ebx
push edx
call display_number
mov dl,'.'
call display_character
pop eax
call display_number
mov esi,_seconds_suffix
call display_string
display_bytes_count:
mov eax,[written_size]
call display_number
mov esi,_bytes_suffix
call display_string
xor al,al
cmp [_run_outfile],0
je @f
mov edx,outfile
call make_fullpaths
xor ecx,ecx
 
cmp [_run_outfile],2 ; param is ',dbg'
jne run
mcall 70,file_info_debug
jmp @f
run:
mcall 70,file_info_start
@@:
jmp exit_program
;---------------------------------------------------------------------
include 'system.inc'
include 'version.inc'
include 'errors.inc'
include 'symbdump.inc'
include 'preproce.inc'
include 'parser.inc'
include 'exprpars.inc'
include 'assemble.inc'
include 'exprcalc.inc'
include 'formats.inc'
include 'x86_64.inc'
include 'avx.inc'
include 'tables.inc'
include 'messages.inc'
;---------------------------------------------------------------------
title db appname,VERSION_STRING,0
 
_logo db 'flat assembler version ',VERSION_STRING,13,10,0
 
_passes_suffix db ' passes, ',0
_seconds_suffix db ' seconds, ',0
_bytes_suffix db ' bytes.',13,10,0
 
_include db 'INCLUDE',0
 
_counter db 4,'0000'
 
_mode dd NORMAL_MODE
_run_outfile dd 0
;bGenerateDebugInfo db 0
 
dbgWord db '-d',0
 
sub_table:
times $41 db $00
times $1A db $20
times $25 db $00
times $10 db $20
times $30 db $00
times $10 db $50
times $04 db $00,$01
times $08 db $00
 
;include_debug_strings
program_end:
; params db 0 ; 'TINYPAD.ASM,TINYPAD,/HD/1/TPAD4/',
params rb 4096
cur_dir_path rb 4096
library_path rb 4096
filename_area rb 256
 
align 4
 
include 'variable.inc'
 
program_base dd ?
buffer_address dd ?
memory_setting dd ?
start_time dd ?
memblock dd ?
 
predefinitions rb 1000h
 
dbgfilename rb MAX_PATH+4
 
sc system_colors
max_handles = 8
fileinfos rb (4+20+MAX_PATH)*max_handles
fileinfos_end:
pinfo process_information
 
align 1000h
rb 1000h
stacktop:
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/system.inc
0,0 → 1,692
; flat assembler
; Copyright (c) 1999-2012, Tomasz Grysztar
; All rights reserved.
 
struc FILEIO
{ .cmd dd ?
.offset dd ?
dd ?
.count dd ?
.buff dd ?
db ?
.name dd ?
};
 
struc FILEINFO
{ .attr dd ?
.flags dd ?
.cr_time dd ?
.cr_date dd ?
.acc_time dd ?
.acc_date dd ?
.mod_time dd ?
.mod_date dd ?
.size dd ?
}
 
 
 
;file_info_open: dd 0,0,0xffffff,0x20000,0xf0000
fullpath_open: ; db '/RD/1/EXAMPLE.ASM'
times MAX_PATH db 0
 
 
;file_info_write: dd 1,0,0,0,0xf0000
fullpath_write:; db '/RD/1/EXAMPLE'
times MAX_PATH db 0
 
file_info_start:
dd 7
dd 0
dd 0
dd 0
dd 0
fullpath_start: ; db '/RD/1/EXAMPLE'
times MAX_PATH db 0
 
file_info_debug:
dd 7
dd 0
dd fullpath_start
dd 0, 0
db '/SYS/DEVELOP/MTDBG',0
 
_ramdisk db '/RD/1/'
filepos dd 0x0
 
 
init_memory:
 
; mov ecx, 16*1024*1024
;
; allocate_memory:
mcall 18, 16
cmp eax, 0x38000000 shr 9
jbe @f
mov eax, 0x38000000 shr 9
@@:
shl eax, 9
xchg eax, ecx
mov [memory_setting],ecx
mcall 68, 12
or eax,eax
jz out_of_memory
mov [memblock], eax
mov [additional_memory],eax
add eax,[memory_setting]
mov [memory_end],eax
mov eax,[memory_setting]
shr eax,2
add eax,[additional_memory]
mov [additional_memory_end],eax
mov [memory_start],eax
ret
 
exit_program:
cmp [_mode],NORMAL_MODE
jne @f
mcall 68, 13, [memblock]
jmp still
@@:
or eax,-1
mcall
 
make_timestamp:
push ebx
mcall 26,9
imul eax,10
pop ebx
ret
 
symbol_dump:
 
push edi
mov edx,[memory_end]
symb_dump:
cmp edx,[labels_list]
jbe symbols_dumped
sub edx,LABEL_STRUCTURE_SIZE
cmp dword [edx+24],0
je symb_dump ; do not dump anonymous symbols
test byte [edx+8],1
jz symb_dump ; do not dump symbols that didn't get defined
mov ax,[current_pass]
cmp ax,[edx+16]
jne symb_dump
test byte [edx+8],4 or 2
jnz symb_dump ; do not dump assembly-time variables
; do not dump variables defined with '='
cmp word [edx+12], 0
jnz symb_dump ; do not dump register-based variables
 
mov al, '0'
stosb
mov al, 'x'
stosb
mov eax, [edx+4]
mov ecx, 8
@@:
rol eax, 4
test al, 0xF
loopz @b
jz .nohigh
inc ecx
@@:
push eax
and al, 0xF
cmp al, 10
sbb al, 69h
das
stosb
pop eax
rol eax, 4
loop @b
mov eax, [edx]
mov ecx, 8
jmp .low
.nohigh:
mov eax, [edx]
mov ecx, 8
@@:
rol eax, 4
test al, 0xF
loopz @b
inc ecx
.low:
push eax
and al, 0xF
cmp al, 10
sbb al, 69h
das
stosb
pop eax
rol eax, 4
loop .low
 
mov al, ' '
stosb
 
mov esi,[edx+24]
movzx ecx,byte [esi-1]
rep movsb
 
mov ax,0A0Dh
stosw
 
jmp symb_dump
 
symbols_dumped:
mov edx,dbgfilename
push esi edi
mov esi, outfile
mov edi, edx
@@:
lodsb
stosb
test al, al
jnz @b
lea ecx, [edi-1]
@@:
dec edi
cmp edi, edx
jb @f
cmp byte [edi], '/'
jz @f
cmp byte [edi], '.'
jnz @b
mov ecx, edi
@@:
mov dword [ecx], '.dbg'
mov byte [ecx+4], 0
pop edi esi
call create
mov edx,[esp]
mov ecx,edi
sub ecx,edx
call write
call close
pop edi
 
ret
 
get_environment_variable:
mov ecx,[memory_end]
sub ecx,edi
cmp ecx,7
jb out_of_memory
cmp dword[esi],'INCL'
jne .finish
mov esi,_ramdisk
mov ecx,6
cld
rep movsb
.finish:
; stc
ret
 
alloc_handle:
call make_fullpaths
mov ebx, fileinfos+4
@@:
cmp dword [ebx], -1
jz .found
add ebx, 4+20+MAX_PATH
cmp ebx, fileinfos_end
jb @b
stc
ret
.found:
and dword [ebx+4], 0
and dword [ebx+8], 0
push esi edi ecx
mov esi, fullpath_open
lea edi, [ebx+20]
mov ecx, MAX_PATH
rep movsb
pop ecx edi esi
ret ; CF=0
 
create:
call alloc_handle
jc .ret
and dword [ebx-4], 0
mov dword [ebx], 2
.ret:
ret
 
 
open:
; call make_fullpaths
 
;; mov eax,fullpath_open
;; DEBUGF '"%s"\n',eax
 
; mov dword[file_info_open+8],-1
; mcall 58,file_info_open
; or eax,eax ; found
; jz @f
; cmp eax,6
; jne file_error
;@@: mov [filesize],ebx
; clc
; ret
;file_error:
; stc
; ret
 
call alloc_handle
jc .ret
mov dword [ebx], 5
and dword [ebx+12], 0
mov dword [ebx+16], fileinfo
mov eax, 70
push ebx
mcall
pop ebx
test eax, eax
jnz .fail
mov eax, [fileinfo.size]
mov [ebx-4], eax
and dword [ebx], 0
.ret:
ret
.fail:
or dword [ebx], -1 ; close handle
stc
ret
 
read:
; pusha
; mov edi,edx
; mov esi,[filepos]
; add esi,0x20000
; cld
; rep movsb
; popa
;; ret
 
mov [ebx+12], ecx
mov [ebx+16], edx
push ebx
mov eax, 70
mcall
xchg eax, [esp]
add [eax+4], ebx
adc [eax+8], dword 0
mov ebx, eax
pop eax
test eax, eax
jz .ok
cmp eax, 6
jz .ok
stc
.ok:
ret
 
close:
or dword [ebx], -1
ret
 
 
; ebx file handle
; ecx count of bytes to write
; edx pointer to buffer
write:
; pusha
; mov [file_info_write+8],ecx
; mov [file_info_write+12],edx
; mov [filesize],edx
; mov eax,58
; mov ebx,file_info_write
; mcall
; popa
; ret
 
mov [ebx+12], ecx
mov [ebx+16], edx
push ebx
mov eax, 70
mcall
xchg eax, [esp]
add [eax+4], ebx
adc [eax+8], dword 0
mov ebx, eax
pop eax
mov byte [ebx], 3
cmp eax, 1
cmc
ret
 
make_fullpaths:
pusha
push edx
 
mov esi,path ; open
; DEBUGF " '%s'",esi
mov edi,fullpath_open
cld
newc1:
movsb
cmp byte[esi],0;' '
jne newc1
mov esi,[esp]
 
cmp byte[esi],'/'
jne @f
mov edi,fullpath_open
 
@@:
lodsb
stosb
cmp al,0
jne @b
; mov ecx,12
; cld
; rep movsb
; mov byte[edi],0
 
mov esi,path ; write
mov edi,fullpath_write
cld
newc2:
movsb
cmp byte[esi],0;' '
jne newc2
mov esi,[esp]
 
cmp byte[esi],'/'
jne @f
mov edi,fullpath_write
 
@@:
lodsb
stosb
cmp al,0
jne @b
; mov ecx,12
; cld
; rep movsb
; mov byte[edi],0
 
mov esi,path ; start
mov edi,fullpath_start
cld
newc3:
movsb
cmp byte[esi],0;' '
jne newc3
; mov esi,[esp]
pop esi
 
cmp byte[esi],'/'
jne @f
mov edi,fullpath_start
 
@@:
lodsb
stosb
cmp al,0
jne @b
; mov ecx,12
; cld
; rep movsb
; mov byte[edi],0
 
; add esp,4
popa
ret
 
 
 
lseek:
cmp al,0
jnz @f
and dword [ebx+4], 0
and dword [ebx+8], 0
@@: cmp al,2
jnz @f
mov eax, [ebx-4]
mov [ebx+4], eax
and dword [ebx+8], 0
@@: add dword [ebx+4], edx
adc dword [ebx+8], 0
ret
 
display_character:
pusha
cmp [_mode],NORMAL_MODE
jne @f
cmp dl,13
jz dc2
cmp dl,0xa
jnz dc1
and [textxy],0x0000FFFF
add [textxy], 7 shl 16 +53 and 0xFFFF0000 + 16
dc2:
popa
ret
dc1:
mov eax,[textxy]
cmp ax,word[bottom_right]
ja dc2
shr eax,16
cmp ax,word[bottom_right+2]
ja dc2
mov [dc],dl
mcall 4,[textxy],0x10000000,dc,1
add [textxy],0x00080000
popa
ret
@@:
mov eax,63
mov ebx,1
mov cl,dl
mcall
popa
ret
 
 
display_string:
pusha
@@:
cmp byte[esi],0
je @f
mov dl,[esi]
call display_character
add esi,1
jmp @b
@@:
popa
ret
 
display_number:
push ebx
mov ecx,1000000000
xor edx,edx
xor bl,bl
display_loop:
div ecx
push edx
cmp ecx,1
je display_digit
or bl,bl
jnz display_digit
or al,al
jz digit_ok
not bl
display_digit:
mov dl,al
add dl,30h
push ebx ecx
call display_character
pop ecx ebx
digit_ok:
mov eax,ecx
xor edx,edx
mov ecx,10
div ecx
mov ecx,eax
pop eax
or ecx,ecx
jnz display_loop
pop ebx
ret
 
display_user_messages:
; push [skinh]
; pop [textxy]
; add [textxy], 7 shl 16 +53
mov [displayed_count],0
call show_display_buffer
cmp [displayed_count],1
jb line_break_ok
je make_line_break
mov ax,word[last_displayed]
cmp ax,0A0Dh
je line_break_ok
cmp ax,0D0Ah
je line_break_ok
make_line_break:
mov esi,lf
call display_string
line_break_ok:
ret
 
display_block:
pusha
@@: mov dl,[esi]
call display_character
inc esi
loop @b
popa
ret
 
fatal_error:
mov esi,error_prefix
call display_string
pop esi
call display_string
mov esi,error_suffix
call display_string
mov esi,lf
call display_string
mov al,0FFh
jmp exit_program
 
assembler_error:
call display_user_messages
push dword 0
mov ebx,[current_line]
get_error_lines:
push ebx
test byte [ebx+7],80h
jz display_error_line
mov edx,ebx
find_definition_origin:
mov edx,[edx+12]
test byte [edx+7],80h
jnz find_definition_origin
push edx
mov ebx,[ebx+8]
jmp get_error_lines
display_error_line:
mov esi,[ebx]
call display_string
mov esi,line_number_start
call display_string
mov eax,[ebx+4]
and eax,7FFFFFFFh
call display_number
mov dl,']'
call display_character
pop esi
cmp ebx,esi
je line_number_ok
mov dl,20h
call display_character
push esi
mov esi,[esi]
movzx ecx,byte [esi]
inc esi
call display_block
mov esi,line_number_start
call display_string
pop esi
mov eax,[esi+4]
and eax,7FFFFFFFh
call display_number
mov dl,']'
call display_character
line_number_ok:
mov esi,line_data_start
call display_string
mov esi,ebx
mov edx,[esi]
call open
mov al,2
xor edx,edx
call lseek
mov edx,[esi+8]
sub eax,edx
push eax
xor al,al
call lseek
mov ecx,[esp]
mov edx,[additional_memory]
lea eax,[edx+ecx]
cmp eax,[additional_memory_end]
ja out_of_memory
call read
call close
pop ecx
mov esi,[additional_memory]
get_line_data:
mov al,[esi]
cmp al,0Ah
je display_line_data
cmp al,0Dh
je display_line_data
cmp al,1Ah
je display_line_data
or al,al
jz display_line_data
inc esi
loop get_line_data
display_line_data:
mov ecx,esi
mov esi,[additional_memory]
sub ecx,esi
call display_block
mov esi,cr_lf
call display_string
pop ebx
or ebx,ebx
jnz display_error_line
mov esi,error_prefix
call display_string
pop esi
call display_string
mov esi,error_suffix
call display_string
jmp exit_program
 
align 4
fileinfo FILEINFO
 
character db ?,0
bytes_count dd ?
 
textxy dd 0x000500A0
dc db 0x0
filesize dd 0x0
 
displayed_count dd ?
last_displayed rb 2
 
error_prefix db 'error: ',0
error_suffix db '.',0
line_data_start db ':'
cr_lf db 0Dh,0Ah,0
line_number_start db ' [',0
 
macro dm string { db string,0 }
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/fasm.inc
0,0 → 1,59
ID_CLOSE_BTN = 1
ID_COMPILE_BTN = 2
ID_EXECUTE_BTN = 3
ID_EXECDBG_BTN = 4
ID_OPENDLG_BTN = 5
 
center fix false
SYSTEMCOLORS fix sc
PROCESSINFO fix pinfo
 
macro get_sys_colors wnd_skin,font_1 {
mcall 48,3,SYSTEMCOLORS,sizeof.system_colors
if wnd_skin <> 0
or [SYSTEMCOLORS+system_colors.work],0x03000000
end if
if font_1 <> 0
or [SYSTEMCOLORS+system_colors.grab_text],0x10000000
end if
}
 
macro draw_caption _edx,_esi {
mov edx,_edx
mov esi,_esi
call __draw_caption
}
 
macro mmov reg,a1,a2 {
mov reg,(a1) shl 16 + (a2)
}
 
macro madd reg,a1,a2 {
add reg,(a1) shl 16 + (a2)
}
 
macro msub reg,a1,a2 {
sub reg,(a1) shl 16 + (a2)
}
 
macro jmpe reg,def,[val,lab] {
forward
cmp reg,val
je lab
common
if ~def eq
jmp def
end if
}
 
macro func name {
if used name
name:
}
 
macro endf {
end if
}
 
@^ fix macro comment {
^@ fix }
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/assemble.inc
0,0 → 1,2030
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
assembler:
xor eax,eax
mov [stub_size],eax
mov [current_pass],ax
mov [resolver_flags],eax
mov [number_of_sections],eax
mov [actual_fixups_size],eax
assembler_loop:
mov eax,[labels_list]
mov [tagged_blocks],eax
mov eax,[additional_memory]
mov [free_additional_memory],eax
mov eax,[additional_memory_end]
mov [structures_buffer],eax
mov esi,[source_start]
mov edi,[code_start]
xor eax,eax
mov dword [adjustment],eax
mov dword [adjustment+4],eax
mov [addressing_space],eax
mov [error_line],eax
mov [counter],eax
mov [format_flags],eax
mov [number_of_relocations],eax
mov [undefined_data_end],eax
mov [file_extension],eax
mov [next_pass_needed],al
mov [output_format],al
mov [adjustment_sign],al
mov [evex_mode],al
mov [code_type],16
call init_addressing_space
pass_loop:
call assemble_line
jnc pass_loop
mov eax,[additional_memory_end]
cmp eax,[structures_buffer]
je pass_done
sub eax,18h
mov eax,[eax+4]
mov [current_line],eax
jmp missing_end_directive
pass_done:
call close_pass
mov eax,[labels_list]
check_symbols:
cmp eax,[memory_end]
jae symbols_checked
test byte [eax+8],8
jz symbol_defined_ok
mov cx,[current_pass]
cmp cx,[eax+18]
jne symbol_defined_ok
test byte [eax+8],1
jz symbol_defined_ok
sub cx,[eax+16]
cmp cx,1
jne symbol_defined_ok
and byte [eax+8],not 1
or [next_pass_needed],-1
symbol_defined_ok:
test byte [eax+8],10h
jz use_prediction_ok
mov cx,[current_pass]
and byte [eax+8],not 10h
test byte [eax+8],20h
jnz check_use_prediction
cmp cx,[eax+18]
jne use_prediction_ok
test byte [eax+8],8
jz use_prediction_ok
jmp use_misprediction
check_use_prediction:
test byte [eax+8],8
jz use_misprediction
cmp cx,[eax+18]
je use_prediction_ok
use_misprediction:
or [next_pass_needed],-1
use_prediction_ok:
test byte [eax+8],40h
jz check_next_symbol
and byte [eax+8],not 40h
test byte [eax+8],4
jnz define_misprediction
mov cx,[current_pass]
test byte [eax+8],80h
jnz check_define_prediction
cmp cx,[eax+16]
jne check_next_symbol
test byte [eax+8],1
jz check_next_symbol
jmp define_misprediction
check_define_prediction:
test byte [eax+8],1
jz define_misprediction
cmp cx,[eax+16]
je check_next_symbol
define_misprediction:
or [next_pass_needed],-1
check_next_symbol:
add eax,LABEL_STRUCTURE_SIZE
jmp check_symbols
symbols_checked:
cmp [next_pass_needed],0
jne next_pass
mov eax,[error_line]
or eax,eax
jz assemble_ok
mov [current_line],eax
cmp [error],undefined_symbol
jne error_confirmed
mov eax,[error_info]
or eax,eax
jz error_confirmed
test byte [eax+8],1
jnz next_pass
error_confirmed:
call error_handler
error_handler:
mov eax,[error]
sub eax,error_handler
add [esp],eax
ret
next_pass:
inc [current_pass]
mov ax,[current_pass]
cmp ax,[passes_limit]
je code_cannot_be_generated
jmp assembler_loop
assemble_ok:
ret
 
create_addressing_space:
mov ebx,[addressing_space]
test ebx,ebx
jz init_addressing_space
test byte [ebx+0Ah],1
jnz illegal_instruction
mov eax,edi
sub eax,[ebx+18h]
mov [ebx+1Ch],eax
init_addressing_space:
mov ebx,[tagged_blocks]
mov dword [ebx-4],10h
mov dword [ebx-8],20h
sub ebx,8+20h
cmp ebx,edi
jbe out_of_memory
mov [tagged_blocks],ebx
mov [addressing_space],ebx
xor eax,eax
mov [ebx],edi
mov [ebx+4],eax
mov [ebx+8],eax
mov [ebx+10h],eax
mov [ebx+14h],eax
mov [ebx+18h],edi
mov [ebx+1Ch],eax
ret
 
assemble_line:
mov eax,[tagged_blocks]
sub eax,100h
cmp edi,eax
ja out_of_memory
lods byte [esi]
cmp al,1
je assemble_instruction
jb source_end
cmp al,3
jb define_label
je define_constant
cmp al,4
je label_addressing_space
cmp al,0Fh
je new_line
cmp al,13h
je code_type_setting
cmp al,10h
jne illegal_instruction
lods byte [esi]
jmp segment_prefix
code_type_setting:
lods byte [esi]
mov [code_type],al
jmp instruction_assembled
new_line:
lods dword [esi]
mov [current_line],eax
and [prefix_flags],0
cmp [symbols_file],0
je continue_line
cmp [next_pass_needed],0
jne continue_line
mov ebx,[tagged_blocks]
mov dword [ebx-4],1
mov dword [ebx-8],14h
sub ebx,8+14h
cmp ebx,edi
jbe out_of_memory
mov [tagged_blocks],ebx
mov [ebx],eax
mov [ebx+4],edi
mov eax,[addressing_space]
mov [ebx+8],eax
mov al,[code_type]
mov [ebx+10h],al
continue_line:
cmp byte [esi],0Fh
je line_assembled
jmp assemble_line
define_label:
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
mov ebx,eax
lods byte [esi]
mov [label_size],al
call make_label
jmp continue_line
make_label:
mov eax,edi
xor edx,edx
xor cl,cl
mov ebp,[addressing_space]
sub eax,[ds:ebp]
sbb edx,[ds:ebp+4]
sbb cl,[ds:ebp+8]
jp label_value_ok
call recoverable_overflow
label_value_ok:
mov [address_sign],cl
test byte [ds:ebp+0Ah],1
jnz make_virtual_label
or byte [ebx+9],1
xchg eax,[ebx]
xchg edx,[ebx+4]
mov ch,[ebx+9]
shr ch,1
and ch,1
neg ch
sub eax,[ebx]
sbb edx,[ebx+4]
sbb ch,cl
mov dword [adjustment],eax
mov dword [adjustment+4],edx
mov [adjustment_sign],ch
or al,ch
or eax,edx
setnz ah
jmp finish_label
make_virtual_label:
and byte [ebx+9],not 1
cmp eax,[ebx]
mov [ebx],eax
setne ah
cmp edx,[ebx+4]
mov [ebx+4],edx
setne al
or ah,al
finish_label:
mov ebp,[addressing_space]
mov ch,[ds:ebp+9]
mov cl,[label_size]
mov edx,[ds:ebp+14h]
mov ebp,[ds:ebp+10h]
finish_label_symbol:
mov al,[address_sign]
xor al,[ebx+9]
and al,10b
or ah,al
xor [ebx+9],al
cmp cl,[ebx+10]
mov [ebx+10],cl
setne al
or ah,al
cmp ch,[ebx+11]
mov [ebx+11],ch
setne al
or ah,al
cmp ebp,[ebx+12]
mov [ebx+12],ebp
setne al
or ah,al
or ch,ch
jz label_symbol_ok
cmp edx,[ebx+20]
mov [ebx+20],edx
setne al
or ah,al
label_symbol_ok:
mov cx,[current_pass]
xchg [ebx+16],cx
mov edx,[current_line]
mov [ebx+28],edx
and byte [ebx+8],not 2
test byte [ebx+8],1
jz new_label
cmp cx,[ebx+16]
je symbol_already_defined
btr dword [ebx+8],10
jc requalified_label
inc cx
sub cx,[ebx+16]
setnz al
or ah,al
jz label_made
test byte [ebx+8],8
jz label_made
mov cx,[current_pass]
cmp cx,[ebx+18]
jne label_made
requalified_label:
or [next_pass_needed],-1
label_made:
ret
new_label:
or byte [ebx+8],1
ret
define_constant:
lods dword [esi]
inc esi
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
push eax
or [operand_flags],1
call get_value
pop ebx
xor cl,cl
mov ch,[value_type]
cmp ch,3
je invalid_use_of_symbol
make_constant:
and byte [ebx+9],not 1
cmp eax,[ebx]
mov [ebx],eax
setne ah
cmp edx,[ebx+4]
mov [ebx+4],edx
setne al
or ah,al
mov al,[value_sign]
xor al,[ebx+9]
and al,10b
or ah,al
xor [ebx+9],al
cmp cl,[ebx+10]
mov [ebx+10],cl
setne al
or ah,al
cmp ch,[ebx+11]
mov [ebx+11],ch
setne al
or ah,al
xor edx,edx
cmp edx,[ebx+12]
mov [ebx+12],edx
setne al
or ah,al
or ch,ch
jz constant_symbol_ok
mov edx,[symbol_identifier]
cmp edx,[ebx+20]
mov [ebx+20],edx
setne al
or ah,al
constant_symbol_ok:
mov cx,[current_pass]
xchg [ebx+16],cx
mov edx,[current_line]
mov [ebx+28],edx
test byte [ebx+8],1
jz new_constant
cmp cx,[ebx+16]
jne redeclare_constant
test byte [ebx+8],2
jz symbol_already_defined
or byte [ebx+8],4
and byte [ebx+9],not 4
jmp instruction_assembled
redeclare_constant:
btr dword [ebx+8],10
jc requalified_constant
inc cx
sub cx,[ebx+16]
setnz al
or ah,al
jz instruction_assembled
test byte [ebx+8],4
jnz instruction_assembled
test byte [ebx+8],8
jz instruction_assembled
mov cx,[current_pass]
cmp cx,[ebx+18]
jne instruction_assembled
requalified_constant:
or [next_pass_needed],-1
jmp instruction_assembled
new_constant:
or byte [ebx+8],1+2
jmp instruction_assembled
label_addressing_space:
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
mov cx,[current_pass]
test byte [eax+8],1
jz make_addressing_space_label
cmp cx,[eax+16]
je symbol_already_defined
test byte [eax+9],4
jnz make_addressing_space_label
or [next_pass_needed],-1
make_addressing_space_label:
mov dx,[eax+8]
and dx,not (2 or 100h)
or dx,1 or 4 or 400h
mov [eax+8],dx
mov [eax+16],cx
mov edx,[current_line]
mov [eax+28],edx
mov ebx,[addressing_space]
mov [eax],ebx
or byte [ebx+0Ah],2
jmp continue_line
assemble_instruction:
; mov [operand_size],0
; mov [operand_flags],0
; mov [operand_prefix],0
; mov [rex_prefix],0
and dword [operand_size],0
; mov [opcode_prefix],0
; mov [vex_required],0
; mov [vex_register],0
; mov [immediate_size],0
and dword [opcode_prefix],0
call instruction_handler
instruction_handler:
movzx ebx,word [esi]
mov al,[esi+2]
add esi,3
add [esp],ebx
ret
instruction_assembled:
test [prefix_flags],not 1
jnz illegal_instruction
mov al,[esi]
cmp al,0Fh
je line_assembled
or al,al
jnz extra_characters_on_line
line_assembled:
clc
ret
source_end:
dec esi
stc
ret
 
org_directive:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_qword_value
mov cl,[value_type]
test cl,1
jnz invalid_use_of_symbol
push eax
mov ebx,[addressing_space]
mov eax,edi
sub eax,[ebx+18h]
mov [ebx+1Ch],eax
test byte [ebx+0Ah],1
jnz in_virtual
call init_addressing_space
jmp org_space_ok
in_virtual:
call close_virtual_addressing_space
call init_addressing_space
or byte [ebx+0Ah],1
org_space_ok:
pop eax
mov [ebx+9],cl
mov cl,[value_sign]
sub [ebx],eax
sbb [ebx+4],edx
sbb byte [ebx+8],cl
jp org_value_ok
call recoverable_overflow
org_value_ok:
mov edx,[symbol_identifier]
mov [ebx+14h],edx
cmp [output_format],1
ja instruction_assembled
cmp edi,[code_start]
jne instruction_assembled
cmp eax,100h
jne instruction_assembled
bts [format_flags],0
jmp instruction_assembled
label_directive:
lods byte [esi]
cmp al,2
jne invalid_argument
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
inc esi
mov ebx,eax
mov [label_size],0
lods byte [esi]
cmp al,':'
je get_label_size
dec esi
cmp al,11h
jne label_size_ok
get_label_size:
lods word [esi]
cmp al,11h
jne invalid_argument
mov [label_size],ah
label_size_ok:
cmp byte [esi],80h
je get_free_label_value
call make_label
jmp instruction_assembled
get_free_label_value:
inc esi
lods byte [esi]
cmp al,'('
jne invalid_argument
push ebx ecx
or byte [ebx+8],4
cmp byte [esi],'.'
je invalid_value
call get_address_value
or bh,bh
setnz ch
xchg ch,cl
mov bp,cx
shl ebp,16
xchg bl,bh
mov bp,bx
pop ecx ebx
and byte [ebx+8],not 4
mov ch,[value_type]
test ch,1
jnz invalid_use_of_symbol
make_free_label:
and byte [ebx+9],not 1
cmp eax,[ebx]
mov [ebx],eax
setne ah
cmp edx,[ebx+4]
mov [ebx+4],edx
setne al
or ah,al
mov edx,[address_symbol]
mov cl,[label_size]
call finish_label_symbol
jmp instruction_assembled
load_directive:
lods byte [esi]
cmp al,2
jne invalid_argument
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
inc esi
push eax
mov al,1
cmp byte [esi],11h
jne load_size_ok
lods byte [esi]
lods byte [esi]
load_size_ok:
cmp al,8
ja invalid_value
mov [operand_size],al
and dword [value],0
and dword [value+4],0
lods byte [esi]
cmp al,82h
jne invalid_argument
call get_data_point
jc value_loaded
push esi edi
mov esi,ebx
mov edi,value
rep movs byte [edi],[esi]
pop edi esi
value_loaded:
mov [value_sign],0
mov eax,dword [value]
mov edx,dword [value+4]
pop ebx
xor cx,cx
jmp make_constant
get_data_point:
mov ebx,[addressing_space]
mov ecx,edi
sub ecx,[ebx+18h]
mov [ebx+1Ch],ecx
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],11h
jne get_data_address
cmp word [esi+1+4],'):'
jne get_data_address
inc esi
lods dword [esi]
add esi,2
cmp byte [esi],'('
jne invalid_argument
inc esi
cmp eax,0Fh
jbe reserved_word_used_as_symbol
mov edx,undefined_symbol
test byte [eax+8],1
jz addressing_space_unavailable
mov edx,symbol_out_of_scope
mov cx,[eax+16]
cmp cx,[current_pass]
jne addressing_space_unavailable
test byte [eax+9],4
jz invalid_use_of_symbol
mov ebx,eax
mov ax,[current_pass]
mov [ebx+18],ax
or byte [ebx+8],8
cmp [symbols_file],0
je get_addressing_space
cmp [next_pass_needed],0
jne get_addressing_space
call store_label_reference
get_addressing_space:
mov ebx,[ebx]
get_data_address:
push ebx
cmp byte [esi],'.'
je invalid_value
or [operand_flags],1
call get_address_value
pop ebp
call calculate_relative_offset
cmp [next_pass_needed],0
jne data_address_type_ok
cmp [value_type],0
jne invalid_use_of_symbol
data_address_type_ok:
mov ebx,edi
xor ecx,ecx
add ebx,eax
adc edx,ecx
mov eax,ebx
sub eax,[ds:ebp+18h]
sbb edx,ecx
jnz bad_data_address
mov cl,[operand_size]
add eax,ecx
cmp eax,[ds:ebp+1Ch]
ja bad_data_address
clc
ret
addressing_space_unavailable:
cmp [error_line],0
jne get_data_address
push [current_line]
pop [error_line]
mov [error],edx
mov [error_info],eax
jmp get_data_address
bad_data_address:
call recoverable_overflow
stc
ret
store_directive:
cmp byte [esi],11h
je sized_store
lods byte [esi]
cmp al,'('
jne invalid_argument
call get_byte_value
xor edx,edx
movzx eax,al
mov [operand_size],1
jmp store_value_ok
sized_store:
or [operand_flags],1
call get_value
store_value_ok:
cmp [value_type],0
jne invalid_use_of_symbol
mov dword [value],eax
mov dword [value+4],edx
lods byte [esi]
cmp al,80h
jne invalid_argument
call get_data_point
jc instruction_assembled
push esi edi
mov esi,value
mov edi,ebx
rep movs byte [edi],[esi]
mov eax,edi
pop edi esi
cmp ebx,[undefined_data_end]
jae instruction_assembled
cmp eax,[undefined_data_start]
jbe instruction_assembled
mov [undefined_data_start],eax
jmp instruction_assembled
 
display_directive:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],0
jne display_byte
inc esi
lods dword [esi]
mov ecx,eax
push edi
mov edi,[tagged_blocks]
sub edi,8
sub edi,eax
cmp edi,[esp]
jbe out_of_memory
mov [tagged_blocks],edi
rep movs byte [edi],[esi]
stos dword [edi]
xor eax,eax
stos dword [edi]
pop edi
inc esi
jmp display_next
display_byte:
call get_byte_value
push edi
mov edi,[tagged_blocks]
sub edi,8+1
mov [tagged_blocks],edi
stos byte [edi]
mov eax,1
stos dword [edi]
dec eax
stos dword [edi]
pop edi
display_next:
cmp edi,[tagged_blocks]
ja out_of_memory
lods byte [esi]
cmp al,','
je display_directive
dec esi
jmp instruction_assembled
show_display_buffer:
mov eax,[tagged_blocks]
or eax,eax
jz display_done
mov esi,[labels_list]
cmp esi,eax
je display_done
display_messages:
sub esi,8
mov eax,[esi+4]
mov ecx,[esi]
sub esi,ecx
test eax,eax
jnz skip_block
push esi
call display_block
pop esi
skip_block:
cmp esi,[tagged_blocks]
jne display_messages
display_done:
ret
 
times_directive:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
cmp eax,0
je zero_times
cmp byte [esi],':'
jne times_argument_ok
inc esi
times_argument_ok:
push [counter]
push [counter_limit]
mov [counter_limit],eax
mov [counter],1
times_loop:
mov eax,esp
sub eax,100h
jc stack_overflow
cmp eax,[stack_limit]
jb stack_overflow
push esi
or [prefix_flags],1
call continue_line
mov eax,[counter_limit]
cmp [counter],eax
je times_done
inc [counter]
pop esi
jmp times_loop
times_done:
pop eax
pop [counter_limit]
pop [counter]
jmp instruction_assembled
zero_times:
call skip_symbol
jnc zero_times
jmp instruction_assembled
 
virtual_directive:
lods byte [esi]
cmp al,80h
jne virtual_at_current
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_address_value
mov ebp,[address_symbol]
or bh,bh
setnz ch
jmp set_virtual
virtual_at_current:
dec esi
mov ebp,[addressing_space]
mov al,[ds:ebp+9]
mov [value_type],al
mov eax,edi
xor edx,edx
xor cl,cl
sub eax,[ds:ebp]
sbb edx,[ds:ebp+4]
sbb cl,[ds:ebp+8]
mov [address_sign],cl
mov bx,[ds:ebp+10h]
mov cx,[ds:ebp+10h+2]
xchg bh,bl
xchg ch,cl
mov ebp,[ds:ebp+14h]
set_virtual:
xchg bl,bh
xchg cl,ch
shl ecx,16
mov cx,bx
push ecx eax
call allocate_structure_data
mov word [ebx],virtual_directive-instruction_handler
mov ecx,[addressing_space]
mov [ebx+12],ecx
mov [ebx+8],edi
mov ecx,[current_line]
mov [ebx+4],ecx
mov ebx,[addressing_space]
mov eax,edi
sub eax,[ebx+18h]
mov [ebx+1Ch],eax
call init_addressing_space
or byte [ebx+0Ah],1
pop eax
mov cl,[address_sign]
not eax
not edx
not cl
add eax,1
adc edx,0
adc cl,0
add eax,edi
adc edx,0
adc cl,0
mov [ebx],eax
mov [ebx+4],edx
mov [ebx+8],cl
pop dword [ebx+10h]
mov [ebx+14h],ebp
mov al,[value_type]
test al,1
jnz invalid_use_of_symbol
mov [ebx+9],al
jmp instruction_assembled
allocate_structure_data:
mov ebx,[structures_buffer]
sub ebx,18h
cmp ebx,[free_additional_memory]
jb out_of_memory
mov [structures_buffer],ebx
ret
find_structure_data:
mov ebx,[structures_buffer]
scan_structures:
cmp ebx,[additional_memory_end]
je no_such_structure
cmp ax,[ebx]
je structure_data_found
add ebx,18h
jmp scan_structures
structure_data_found:
ret
no_such_structure:
stc
ret
end_virtual:
call find_structure_data
jc unexpected_instruction
push ebx
call close_virtual_addressing_space
pop ebx
mov eax,[ebx+12]
mov [addressing_space],eax
mov edi,[ebx+8]
remove_structure_data:
push esi edi
mov ecx,ebx
sub ecx,[structures_buffer]
shr ecx,2
lea esi,[ebx-4]
lea edi,[esi+18h]
std
rep movs dword [edi],[esi]
cld
add [structures_buffer],18h
pop edi esi
ret
close_virtual_addressing_space:
mov ebx,[addressing_space]
mov eax,edi
sub eax,[ebx+18h]
mov [ebx+1Ch],eax
test byte [ebx+0Ah],2
jz addressing_space_closed
push esi edi ecx edx
mov ecx,eax
mov eax,[tagged_blocks]
mov dword [eax-4],11h
mov dword [eax-8],ecx
sub eax,8
sub eax,ecx
mov [tagged_blocks],eax
lea edi,[eax+ecx-1]
xchg eax,[ebx+18h]
lea esi,[eax+ecx-1]
mov eax,edi
sub eax,esi
std
shr ecx,1
jnc virtual_byte_ok
movs byte [edi],[esi]
virtual_byte_ok:
dec esi
dec edi
shr ecx,1
jnc virtual_word_ok
movs word [edi],[esi]
virtual_word_ok:
sub esi,2
sub edi,2
rep movs dword [edi],[esi]
cld
xor edx,edx
add [ebx],eax
adc dword [ebx+4],edx
adc byte [ebx+8],dl
pop edx ecx edi esi
addressing_space_closed:
ret
repeat_directive:
test [prefix_flags],1
jnz unexpected_instruction
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
cmp eax,0
je zero_repeat
call allocate_structure_data
mov word [ebx],repeat_directive-instruction_handler
xchg eax,[counter_limit]
mov [ebx+10h],eax
mov eax,1
xchg eax,[counter]
mov [ebx+14h],eax
mov [ebx+8],esi
mov eax,[current_line]
mov [ebx+4],eax
jmp instruction_assembled
end_repeat:
test [prefix_flags],1
jnz unexpected_instruction
call find_structure_data
jc unexpected_instruction
mov eax,[counter_limit]
inc [counter]
cmp [counter],eax
jbe continue_repeating
stop_repeat:
mov eax,[ebx+10h]
mov [counter_limit],eax
mov eax,[ebx+14h]
mov [counter],eax
call remove_structure_data
jmp instruction_assembled
continue_repeating:
mov esi,[ebx+8]
jmp instruction_assembled
zero_repeat:
mov al,[esi]
or al,al
jz missing_end_directive
cmp al,0Fh
jne extra_characters_on_line
call find_end_repeat
jmp instruction_assembled
find_end_repeat:
call find_structure_end
cmp ax,repeat_directive-instruction_handler
jne unexpected_instruction
ret
while_directive:
test [prefix_flags],1
jnz unexpected_instruction
call allocate_structure_data
mov word [ebx],while_directive-instruction_handler
mov eax,1
xchg eax,[counter]
mov [ebx+10h],eax
mov [ebx+8],esi
mov eax,[current_line]
mov [ebx+4],eax
do_while:
push ebx
call calculate_logical_expression
or al,al
jnz while_true
mov al,[esi]
or al,al
jz missing_end_directive
cmp al,0Fh
jne extra_characters_on_line
stop_while:
call find_end_while
pop ebx
mov eax,[ebx+10h]
mov [counter],eax
call remove_structure_data
jmp instruction_assembled
while_true:
pop ebx
jmp instruction_assembled
end_while:
test [prefix_flags],1
jnz unexpected_instruction
call find_structure_data
jc unexpected_instruction
mov eax,[ebx+4]
mov [current_line],eax
inc [counter]
jz too_many_repeats
mov esi,[ebx+8]
jmp do_while
find_end_while:
call find_structure_end
cmp ax,while_directive-instruction_handler
jne unexpected_instruction
ret
if_directive:
test [prefix_flags],1
jnz unexpected_instruction
call calculate_logical_expression
mov dl,al
mov al,[esi]
or al,al
jz missing_end_directive
cmp al,0Fh
jne extra_characters_on_line
or dl,dl
jnz if_true
call find_else
jc instruction_assembled
mov al,[esi]
cmp al,1
jne else_true
cmp word [esi+1],if_directive-instruction_handler
jne else_true
add esi,4
jmp if_directive
if_true:
xor al,al
make_if_structure:
call allocate_structure_data
mov word [ebx],if_directive-instruction_handler
mov byte [ebx+2],al
mov eax,[current_line]
mov [ebx+4],eax
jmp instruction_assembled
else_true:
or al,al
jz missing_end_directive
cmp al,0Fh
jne extra_characters_on_line
or al,-1
jmp make_if_structure
else_directive:
test [prefix_flags],1
jnz unexpected_instruction
mov ax,if_directive-instruction_handler
call find_structure_data
jc unexpected_instruction
cmp byte [ebx+2],0
jne unexpected_instruction
found_else:
mov al,[esi]
cmp al,1
jne skip_else
cmp word [esi+1],if_directive-instruction_handler
jne skip_else
add esi,4
call find_else
jnc found_else
call remove_structure_data
jmp instruction_assembled
skip_else:
or al,al
jz missing_end_directive
cmp al,0Fh
jne extra_characters_on_line
call find_end_if
call remove_structure_data
jmp instruction_assembled
end_if:
test [prefix_flags],1
jnz unexpected_instruction
call find_structure_data
jc unexpected_instruction
call remove_structure_data
jmp instruction_assembled
find_else:
call find_structure_end
cmp ax,else_directive-instruction_handler
je else_found
cmp ax,if_directive-instruction_handler
jne unexpected_instruction
stc
ret
else_found:
clc
ret
find_end_if:
call find_structure_end
cmp ax,if_directive-instruction_handler
jne unexpected_instruction
ret
find_structure_end:
push [error_line]
mov eax,[current_line]
mov [error_line],eax
find_end_directive:
call skip_symbol
jnc find_end_directive
lods byte [esi]
cmp al,0Fh
jne no_end_directive
lods dword [esi]
mov [current_line],eax
skip_labels:
cmp byte [esi],2
jne labels_ok
add esi,6
jmp skip_labels
labels_ok:
cmp byte [esi],1
jne find_end_directive
mov ax,[esi+1]
cmp ax,prefix_instruction-instruction_handler
je find_end_directive
add esi,4
cmp ax,repeat_directive-instruction_handler
je skip_repeat
cmp ax,while_directive-instruction_handler
je skip_while
cmp ax,if_directive-instruction_handler
je skip_if
cmp ax,else_directive-instruction_handler
je structure_end
cmp ax,end_directive-instruction_handler
jne find_end_directive
cmp byte [esi],1
jne find_end_directive
mov ax,[esi+1]
add esi,4
cmp ax,repeat_directive-instruction_handler
je structure_end
cmp ax,while_directive-instruction_handler
je structure_end
cmp ax,if_directive-instruction_handler
jne find_end_directive
structure_end:
pop [error_line]
ret
no_end_directive:
mov eax,[error_line]
mov [current_line],eax
jmp missing_end_directive
skip_repeat:
call find_end_repeat
jmp find_end_directive
skip_while:
call find_end_while
jmp find_end_directive
skip_if:
call skip_if_block
jmp find_end_directive
skip_if_block:
call find_else
jc if_block_skipped
cmp byte [esi],1
jne skip_after_else
cmp word [esi+1],if_directive-instruction_handler
jne skip_after_else
add esi,4
jmp skip_if_block
skip_after_else:
call find_end_if
if_block_skipped:
ret
end_directive:
lods byte [esi]
cmp al,1
jne invalid_argument
lods word [esi]
inc esi
cmp ax,virtual_directive-instruction_handler
je end_virtual
cmp ax,repeat_directive-instruction_handler
je end_repeat
cmp ax,while_directive-instruction_handler
je end_while
cmp ax,if_directive-instruction_handler
je end_if
cmp ax,data_directive-instruction_handler
je end_data
jmp invalid_argument
break_directive:
mov ebx,[structures_buffer]
mov al,[esi]
or al,al
jz find_breakable_structure
cmp al,0Fh
jne extra_characters_on_line
find_breakable_structure:
cmp ebx,[additional_memory_end]
je unexpected_instruction
mov ax,[ebx]
cmp ax,repeat_directive-instruction_handler
je break_repeat
cmp ax,while_directive-instruction_handler
je break_while
cmp ax,if_directive-instruction_handler
je break_if
add ebx,18h
jmp find_breakable_structure
break_if:
push [current_line]
mov eax,[ebx+4]
mov [current_line],eax
call remove_structure_data
call skip_if_block
pop [current_line]
mov ebx,[structures_buffer]
jmp find_breakable_structure
break_repeat:
push ebx
call find_end_repeat
pop ebx
jmp stop_repeat
break_while:
push ebx
jmp stop_while
 
data_bytes:
call define_data
lods byte [esi]
cmp al,'('
je get_byte
cmp al,'?'
jne invalid_argument
mov eax,edi
mov byte [edi],0
inc edi
jmp undefined_data
get_byte:
cmp byte [esi],0
je get_string
call get_byte_value
stos byte [edi]
ret
get_string:
inc esi
lods dword [esi]
mov ecx,eax
lea eax,[edi+ecx]
cmp eax,[tagged_blocks]
ja out_of_memory
rep movs byte [edi],[esi]
inc esi
ret
undefined_data:
mov ebp,[addressing_space]
test byte [ds:ebp+0Ah],1
jz mark_undefined_data
ret
mark_undefined_data:
cmp eax,[undefined_data_end]
je undefined_data_ok
mov [undefined_data_start],eax
undefined_data_ok:
mov [undefined_data_end],edi
ret
define_data:
cmp edi,[tagged_blocks]
jae out_of_memory
cmp byte [esi],'('
jne simple_data_value
mov ebx,esi
inc esi
call skip_expression
xchg esi,ebx
cmp byte [ebx],81h
jne simple_data_value
inc esi
call get_count_value
inc esi
or eax,eax
jz duplicate_zero_times
cmp byte [esi],91h
jne duplicate_single_data_value
inc esi
duplicate_data:
push eax esi
duplicated_values:
cmp edi,[tagged_blocks]
jae out_of_memory
call near dword [esp+8]
lods byte [esi]
cmp al,','
je duplicated_values
cmp al,92h
jne invalid_argument
pop ebx eax
dec eax
jz data_defined
mov esi,ebx
jmp duplicate_data
duplicate_single_data_value:
cmp edi,[tagged_blocks]
jae out_of_memory
push eax esi
call near dword [esp+8]
pop ebx eax
dec eax
jz data_defined
mov esi,ebx
jmp duplicate_single_data_value
duplicate_zero_times:
cmp byte [esi],91h
jne skip_single_data_value
inc esi
skip_data_value:
call skip_symbol
jc invalid_argument
cmp byte [esi],92h
jne skip_data_value
inc esi
jmp data_defined
skip_single_data_value:
call skip_symbol
jmp data_defined
simple_data_value:
cmp edi,[tagged_blocks]
jae out_of_memory
call near dword [esp]
data_defined:
lods byte [esi]
cmp al,','
je define_data
dec esi
add esp,4
jmp instruction_assembled
data_unicode:
or [base_code],-1
jmp define_words
data_words:
mov [base_code],0
define_words:
call define_data
lods byte [esi]
cmp al,'('
je get_word
cmp al,'?'
jne invalid_argument
mov eax,edi
and word [edi],0
scas word [edi]
jmp undefined_data
ret
get_word:
cmp [base_code],0
je word_data_value
cmp byte [esi],0
je word_string
word_data_value:
call get_word_value
call mark_relocation
stos word [edi]
ret
word_string:
inc esi
lods dword [esi]
mov ecx,eax
jecxz word_string_ok
lea eax,[edi+ecx*2]
cmp eax,[tagged_blocks]
ja out_of_memory
xor ah,ah
copy_word_string:
lods byte [esi]
stos word [edi]
loop copy_word_string
word_string_ok:
inc esi
ret
data_dwords:
call define_data
lods byte [esi]
cmp al,'('
je get_dword
cmp al,'?'
jne invalid_argument
mov eax,edi
and dword [edi],0
scas dword [edi]
jmp undefined_data
get_dword:
push esi
call get_dword_value
pop ebx
cmp byte [esi],':'
je complex_dword
call mark_relocation
stos dword [edi]
ret
complex_dword:
mov esi,ebx
cmp byte [esi],'.'
je invalid_value
call get_word_value
push eax
inc esi
lods byte [esi]
cmp al,'('
jne invalid_operand
mov al,[value_type]
push eax
cmp byte [esi],'.'
je invalid_value
call get_word_value
call mark_relocation
stos word [edi]
pop eax
mov [value_type],al
pop eax
call mark_relocation
stos word [edi]
ret
data_pwords:
call define_data
lods byte [esi]
cmp al,'('
je get_pword
cmp al,'?'
jne invalid_argument
mov eax,edi
and dword [edi],0
scas dword [edi]
and word [edi],0
scas word [edi]
jmp undefined_data
get_pword:
push esi
call get_pword_value
pop ebx
cmp byte [esi],':'
je complex_pword
call mark_relocation
stos dword [edi]
mov ax,dx
stos word [edi]
ret
complex_pword:
mov esi,ebx
cmp byte [esi],'.'
je invalid_value
call get_word_value
push eax
inc esi
lods byte [esi]
cmp al,'('
jne invalid_operand
mov al,[value_type]
push eax
cmp byte [esi],'.'
je invalid_value
call get_dword_value
call mark_relocation
stos dword [edi]
pop eax
mov [value_type],al
pop eax
call mark_relocation
stos word [edi]
ret
data_qwords:
call define_data
lods byte [esi]
cmp al,'('
je get_qword
cmp al,'?'
jne invalid_argument
mov eax,edi
and dword [edi],0
scas dword [edi]
and dword [edi],0
scas dword [edi]
jmp undefined_data
get_qword:
call get_qword_value
call mark_relocation
stos dword [edi]
mov eax,edx
stos dword [edi]
ret
data_twords:
call define_data
lods byte [esi]
cmp al,'('
je get_tword
cmp al,'?'
jne invalid_argument
mov eax,edi
and dword [edi],0
scas dword [edi]
and dword [edi],0
scas dword [edi]
and word [edi],0
scas word [edi]
jmp undefined_data
get_tword:
cmp byte [esi],'.'
jne complex_tword
inc esi
cmp word [esi+8],8000h
je fp_zero_tword
mov eax,[esi]
stos dword [edi]
mov eax,[esi+4]
stos dword [edi]
mov ax,[esi+8]
add ax,3FFFh
jo value_out_of_range
cmp ax,7FFFh
jge value_out_of_range
cmp ax,0
jg tword_exp_ok
mov cx,ax
neg cx
inc cx
cmp cx,64
jae value_out_of_range
cmp cx,32
ja large_shift
mov eax,[esi]
mov edx,[esi+4]
mov ebx,edx
shr edx,cl
shrd eax,ebx,cl
jmp tword_mantissa_shift_done
large_shift:
sub cx,32
xor edx,edx
mov eax,[esi+4]
shr eax,cl
tword_mantissa_shift_done:
jnc store_shifted_mantissa
add eax,1
adc edx,0
store_shifted_mantissa:
mov [edi-8],eax
mov [edi-4],edx
xor ax,ax
test edx,1 shl 31
jz tword_exp_ok
inc ax
tword_exp_ok:
mov bl,[esi+11]
shl bx,15
or ax,bx
stos word [edi]
add esi,13
ret
fp_zero_tword:
xor eax,eax
stos dword [edi]
stos dword [edi]
mov al,[esi+11]
shl ax,15
stos word [edi]
add esi,13
ret
complex_tword:
call get_word_value
push eax
cmp byte [esi],':'
jne invalid_operand
inc esi
lods byte [esi]
cmp al,'('
jne invalid_operand
mov al,[value_type]
push eax
cmp byte [esi],'.'
je invalid_value
call get_qword_value
call mark_relocation
stos dword [edi]
mov eax,edx
stos dword [edi]
pop eax
mov [value_type],al
pop eax
call mark_relocation
stos word [edi]
ret
data_file:
lods word [esi]
cmp ax,'('
jne invalid_argument
add esi,4
call open_binary_file
mov eax,[esi-4]
lea esi,[esi+eax+1]
mov al,2
xor edx,edx
call lseek
push eax
xor edx,edx
cmp byte [esi],':'
jne position_ok
inc esi
cmp byte [esi],'('
jne invalid_argument
inc esi
cmp byte [esi],'.'
je invalid_value
push ebx
call get_count_value
pop ebx
mov edx,eax
sub [esp],edx
jc value_out_of_range
position_ok:
cmp byte [esi],','
jne size_ok
inc esi
cmp byte [esi],'('
jne invalid_argument
inc esi
cmp byte [esi],'.'
je invalid_value
push ebx edx
call get_count_value
pop edx ebx
cmp eax,[esp]
ja value_out_of_range
mov [esp],eax
size_ok:
xor al,al
call lseek
pop ecx
mov edx,edi
add edi,ecx
jc out_of_memory
cmp edi,[tagged_blocks]
ja out_of_memory
call read
jc error_reading_file
call close
lods byte [esi]
cmp al,','
je data_file
dec esi
jmp instruction_assembled
open_binary_file:
push esi
push edi
mov eax,[current_line]
find_current_source_path:
mov esi,[eax]
test byte [eax+7],80h
jz get_current_path
mov eax,[eax+8]
jmp find_current_source_path
get_current_path:
lodsb
stosb
or al,al
jnz get_current_path
cut_current_path:
cmp edi,[esp]
je current_path_ok
cmp byte [edi-1],'\'
je current_path_ok
cmp byte [edi-1],'/'
je current_path_ok
dec edi
jmp cut_current_path
current_path_ok:
mov esi,[esp+4]
call expand_path
pop edx
mov esi,edx
call open
jnc file_opened
mov edx,[include_paths]
search_in_include_paths:
push edx esi
mov edi,esi
mov esi,[esp+4]
call get_include_directory
mov [esp+4],esi
mov esi,[esp+8]
call expand_path
pop edx
mov esi,edx
call open
pop edx
jnc file_opened
cmp byte [edx],0
jne search_in_include_paths
mov edi,esi
mov esi,[esp]
push edi
call expand_path
pop edx
mov esi,edx
call open
jc file_not_found
file_opened:
mov edi,esi
pop esi
ret
reserve_bytes:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
mov ecx,eax
mov edx,ecx
add edx,edi
jc out_of_memory
cmp edx,[tagged_blocks]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_bytes
add edi,ecx
jmp reserved_data
zero_bytes:
xor eax,eax
shr ecx,1
jnc bytes_stosb_ok
stos byte [edi]
bytes_stosb_ok:
shr ecx,1
jnc bytes_stosw_ok
stos word [edi]
bytes_stosw_ok:
rep stos dword [edi]
reserved_data:
pop eax
call undefined_data
jmp instruction_assembled
reserve_words:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
mov ecx,eax
mov edx,ecx
shl edx,1
jc out_of_memory
add edx,edi
jc out_of_memory
cmp edx,[tagged_blocks]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_words
lea edi,[edi+ecx*2]
jmp reserved_data
zero_words:
xor eax,eax
shr ecx,1
jnc words_stosw_ok
stos word [edi]
words_stosw_ok:
rep stos dword [edi]
jmp reserved_data
reserve_dwords:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
mov ecx,eax
mov edx,ecx
shl edx,1
jc out_of_memory
shl edx,1
jc out_of_memory
add edx,edi
jc out_of_memory
cmp edx,[tagged_blocks]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_dwords
lea edi,[edi+ecx*4]
jmp reserved_data
zero_dwords:
xor eax,eax
rep stos dword [edi]
jmp reserved_data
reserve_pwords:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
mov ecx,eax
shl ecx,1
jc out_of_memory
add ecx,eax
mov edx,ecx
shl edx,1
jc out_of_memory
add edx,edi
jc out_of_memory
cmp edx,[tagged_blocks]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_words
lea edi,[edi+ecx*2]
jmp reserved_data
reserve_qwords:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
mov ecx,eax
shl ecx,1
jc out_of_memory
mov edx,ecx
shl edx,1
jc out_of_memory
shl edx,1
jc out_of_memory
add edx,edi
jc out_of_memory
cmp edx,[tagged_blocks]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_dwords
lea edi,[edi+ecx*4]
jmp reserved_data
reserve_twords:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
mov ecx,eax
shl ecx,2
jc out_of_memory
add ecx,eax
mov edx,ecx
shl edx,1
jc out_of_memory
add edx,edi
jc out_of_memory
cmp edx,[tagged_blocks]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_words
lea edi,[edi+ecx*2]
jmp reserved_data
align_directive:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
mov edx,eax
dec edx
test eax,edx
jnz invalid_align_value
or eax,eax
jz invalid_align_value
cmp eax,1
je instruction_assembled
mov ecx,edi
mov ebp,[addressing_space]
sub ecx,[ds:ebp]
cmp dword [ds:ebp+10h],0
jne section_not_aligned_enough
cmp byte [ds:ebp+9],0
je make_alignment
cmp [output_format],3
je pe_alignment
mov ebx,[ds:ebp+14h]
cmp byte [ebx],0
jne section_not_aligned_enough
cmp eax,[ebx+10h]
jbe make_alignment
jmp section_not_aligned_enough
pe_alignment:
cmp eax,1000h
ja section_not_aligned_enough
make_alignment:
dec eax
and ecx,eax
jz instruction_assembled
neg ecx
add ecx,eax
inc ecx
mov edx,ecx
add edx,edi
jc out_of_memory
cmp edx,[tagged_blocks]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je nops
add edi,ecx
jmp reserved_data
invalid_align_value:
cmp [error_line],0
jne instruction_assembled
mov eax,[current_line]
mov [error_line],eax
mov [error],invalid_value
jmp instruction_assembled
nops:
mov eax,90909090h
shr ecx,1
jnc nops_stosb_ok
stos byte [edi]
nops_stosb_ok:
shr ecx,1
jnc nops_stosw_ok
stos word [edi]
nops_stosw_ok:
rep stos dword [edi]
jmp reserved_data
err_directive:
mov al,[esi]
cmp al,0Fh
je invoked_error
or al,al
jz invoked_error
jmp extra_characters_on_line
assert_directive:
call calculate_logical_expression
or al,al
jnz instruction_assembled
cmp [error_line],0
jne instruction_assembled
mov eax,[current_line]
mov [error_line],eax
mov [error],assertion_failed
jmp instruction_assembled
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/avx.inc
0,0 → 1,3355
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
avx_single_source_pd_instruction_er_evex:
or [vex_required],8
avx_single_source_pd_instruction_er:
or [operand_flags],2+4+8
jmp avx_pd_instruction
avx_single_source_pd_instruction_sae_evex:
or [vex_required],8
or [operand_flags],2+4
jmp avx_pd_instruction
avx_pd_instruction_imm8:
mov [immediate_size],1
jmp avx_pd_instruction
avx_pd_instruction_er:
or [operand_flags],8
avx_pd_instruction_sae:
or [operand_flags],4
avx_pd_instruction:
mov [opcode_prefix],66h
or [rex_prefix],80h
mov cx,0800h
jmp avx_instruction_with_broadcast
avx_pd_instruction_38_evex:
or [vex_required],8
mov [supplemental_code],al
mov al,38h
jmp avx_pd_instruction
avx_cvtps2dq_instruction:
mov [opcode_prefix],66h
jmp avx_single_source_ps_instruction_er
avx_cvtudq2ps_instruction:
mov [opcode_prefix],0F2h
avx_single_source_ps_instruction_er_evex:
or [vex_required],8
avx_single_source_ps_instruction_er:
or [operand_flags],2+4+8
jmp avx_ps_instruction
avx_single_source_ps_instruction_noevex:
or [operand_flags],2
or [vex_required],2
jmp avx_ps_instruction
avx_ps_instruction_imm8:
mov [immediate_size],1
jmp avx_ps_instruction
avx_ps_instruction_er:
or [operand_flags],8
avx_ps_instruction_sae:
or [operand_flags],4
avx_ps_instruction:
mov cx,0400h
jmp avx_instruction_with_broadcast
avx_ps_instruction_66_38_evex:
or [vex_required],8
mov [opcode_prefix],66h
mov [supplemental_code],al
mov al,38h
jmp avx_ps_instruction
avx_sd_instruction_er:
or [operand_flags],8
avx_sd_instruction_sae:
or [operand_flags],4
avx_sd_instruction:
mov [opcode_prefix],0F2h
or [rex_prefix],80h
mov cl,8
jmp avx_instruction
avx_ss_instruction_er:
or [operand_flags],8
avx_ss_instruction_sae:
or [operand_flags],4
avx_ss_instruction:
mov [opcode_prefix],0F3h
mov cl,4
jmp avx_instruction
avx_ss_instruction_noevex:
or [vex_required],2
jmp avx_ss_instruction
avx_single_source_q_instruction_38_evex:
or [operand_flags],2
avx_q_instruction_38_evex:
or [vex_required],8
avx_q_instruction_38:
mov [supplemental_code],al
mov al,38h
jmp avx_q_instruction
avx_q_instruction_38_w1_evex:
or [vex_required],8
avx_q_instruction_38_w1:
or [rex_prefix],8
jmp avx_q_instruction_38
avx_q_instruction_3a_imm8_evex:
mov [immediate_size],1
or [vex_required],8
mov [supplemental_code],al
mov al,3Ah
jmp avx_q_instruction
avx_q_instruction_evex:
or [vex_required],8
avx_q_instruction:
or [rex_prefix],80h
mov ch,8
jmp avx_pi_instruction
avx_single_source_d_instruction_38_evex:
or [vex_required],8
avx_single_source_d_instruction_38:
or [operand_flags],2
jmp avx_d_instruction_38
avx_d_instruction_38_evex:
or [vex_required],8
avx_d_instruction_38:
mov [supplemental_code],al
mov al,38h
jmp avx_d_instruction
avx_d_instruction_3a_imm8_evex:
mov [immediate_size],1
or [vex_required],8
mov [supplemental_code],al
mov al,3Ah
jmp avx_d_instruction
avx_single_source_d_instruction_imm8:
or [operand_flags],2
mov [immediate_size],1
jmp avx_d_instruction
avx_d_instruction_evex:
or [vex_required],8
avx_d_instruction:
mov ch,4
jmp avx_pi_instruction
avx_single_source_bw_instruction_38:
or [operand_flags],2
avx_bw_instruction_38:
mov [supplemental_code],al
mov al,38h
avx_bw_instruction:
xor ch,ch
avx_pi_instruction:
mov [opcode_prefix],66h
xor cl,cl
jmp avx_instruction_with_broadcast
avx_bw_instruction_38_w1_evex:
or [rex_prefix],8
avx_bw_instruction_38_evex:
or [vex_required],8
jmp avx_bw_instruction_38
avx_pd_instruction_noevex:
xor cl,cl
or [vex_required],2
mov [opcode_prefix],66h
jmp avx_instruction
avx_ps_instruction_noevex:
or [vex_required],2
mov [opcode_prefix],0F2h
xor cl,cl
jmp avx_instruction
avx_instruction:
xor ch,ch
avx_instruction_with_broadcast:
mov [mmx_size],cl
mov [broadcast_size],ch
mov [base_code],0Fh
mov [extended_code],al
avx_xop_common:
or [vex_required],1
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
avx_reg:
lods byte [esi]
call convert_avx_register
mov [postbyte_register],al
call take_avx512_mask
avx_vex_reg:
test [operand_flags],2
jnz avx_vex_reg_ok
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [vex_register],al
avx_vex_reg_ok:
mov al,[mmx_size]
or al,al
jz avx_regs_size_ok
mov ah,[operand_size]
or ah,ah
jz avx_regs_size_ok
cmp al,ah
je avx_regs_size_ok
ja invalid_operand_size
cmp ah,16
jne invalid_operand_size
avx_regs_size_ok:
lods byte [esi]
cmp al,','
jne invalid_operand
avx_regs_rm:
call take_avx_rm
jc avx_regs_reg
mov al,[immediate_size]
cmp al,1
je mmx_imm8
jb instruction_ready
cmp al,-4
je sse_cmp_mem_ok
cmp byte [esi],','
jne invalid_operand
inc esi
call take_avx_register
shl al,4
jc invalid_operand
or byte [value],al
test al,80h
jz avx_regs_mem_reg_store
cmp [code_type],64
jne invalid_operand
avx_regs_mem_reg_store:
call take_imm4_if_needed
call store_instruction_with_imm8
jmp instruction_assembled
avx_regs_reg:
mov bl,al
call take_avx512_rounding
mov al,[immediate_size]
cmp al,1
je mmx_nomem_imm8
jb nomem_instruction_ready
cmp al,-4
je sse_cmp_nomem_ok
lods byte [esi]
cmp al,','
jne invalid_operand
mov al,bl
shl al,4
jc invalid_operand
or byte [value],al
test al,80h
jz avx_regs_reg_
cmp [code_type],64
jne invalid_operand
avx_regs_reg_:
call take_avx_rm
jc avx_regs_reg_reg
cmp [immediate_size],-2
jg invalid_operand
or [rex_prefix],8
call take_imm4_if_needed
call store_instruction_with_imm8
jmp instruction_assembled
avx_regs_reg_reg:
shl al,4
jc invalid_operand
and byte [value],1111b
or byte [value],al
call take_imm4_if_needed
call store_nomem_instruction
mov al,byte [value]
stos byte [edi]
jmp instruction_assembled
take_avx_rm:
xor cl,cl
xchg cl,[operand_size]
lods byte [esi]
call get_size_operator
cmp al,'['
je take_avx_mem
cmp al,10h
jne invalid_operand
mov [operand_size],cl
lods byte [esi]
call convert_avx_register
or cl,cl
jnz avx_reg_ok
or cl,[mmx_size]
jz avx_reg_ok
cmp ah,cl
je avx_reg_ok
jb invalid_operand_size
cmp ah,16
jne invalid_operand_size
avx_reg_ok:
stc
ret
take_avx_mem:
push ecx
call get_address
cmp byte [esi],'{'
jne avx_mem_ok
inc esi
lods byte [esi]
cmp al,1Fh
jne invalid_operand
mov al,[esi]
shr al,4
cmp al,1
jne invalid_operand
mov al,[mmx_size]
or al,al
jnz avx_mem_broadcast_check
mov eax,[esp]
or al,al
jnz avx_mem_broadcast_check
mov al,[broadcast_size]
mov [mmx_size],al
mov ah,cl
lods byte [esi]
and al,1111b
mov cl,al
mov al,[broadcast_size]
shl al,cl
mov [esp],al
mov cl,ah
jmp avx_mem_broadcast_ok
avx_mem_broadcast_check:
bsf eax,eax
xchg al,[broadcast_size]
mov [mmx_size],al
bsf eax,eax
jz invalid_operand
mov ah,[broadcast_size]
sub ah,al
lods byte [esi]
and al,1111b
cmp al,ah
jne invalid_operand_size
avx_mem_broadcast_ok:
or [vex_required],40h
lods byte [esi]
cmp al,'}'
jne invalid_operand
avx_mem_ok:
pop eax
or al,al
jz avx_mem_size_deciding
xchg al,[operand_size]
cmp [mmx_size],0
jne avx_mem_size_enforced
or al,al
jz avx_mem_size_ok
cmp al,[operand_size]
jne operand_sizes_do_not_match
avx_mem_size_ok:
clc
ret
avx_mem_size_deciding:
mov al,[operand_size]
cmp [mmx_size],0
jne avx_mem_size_enforced
cmp al,16
je avx_mem_size_ok
cmp al,32
je avx_mem_size_ok
cmp al,64
je avx_mem_size_ok
or al,al
jnz invalid_operand_size
call recoverable_unknown_size
avx_mem_size_enforced:
or al,al
jz avx_mem_size_ok
cmp al,[mmx_size]
je avx_mem_size_ok
jmp invalid_operand_size
take_imm4_if_needed:
cmp [immediate_size],-3
jne imm4_ok
push ebx ecx edx
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
cmp al,'('
jne invalid_operand
call get_byte_value
test al,11110000b
jnz value_out_of_range
or byte [value],al
pop edx ecx ebx
imm4_ok:
ret
take_avx512_mask:
cmp byte [esi],'{'
jne avx512_masking_ok
test [operand_flags],10h
jnz invalid_operand
inc esi
lods byte [esi]
cmp al,14h
jne invalid_operand
lods byte [esi]
mov ah,al
shr ah,4
cmp ah,5
jne invalid_operand
or al,al
jz invalid_operand
and al,111b
mov [mask_register],al
or [vex_required],20h
lods byte [esi]
cmp al,'}'
jne invalid_operand
cmp byte [esi],'{'
jne avx512_masking_ok
test [operand_flags],20h
jnz invalid_operand
inc esi
lods byte [esi]
cmp al,1Fh
jne invalid_operand
lods byte [esi]
or al,al
jnz invalid_operand
or [mask_register],80h
lods byte [esi]
cmp al,'}'
jne invalid_operand
avx512_masking_ok:
retn
take_avx512_rounding:
test [operand_flags],4+8
jz avx512_rounding_done
cmp [mmx_size],0
jne avx512_rounding_allowed
cmp [operand_size],64
jne avx512_rounding_done
avx512_rounding_allowed:
cmp byte [esi],','
jne avx512_rounding_done
cmp byte [esi+1],'{'
jne avx512_rounding_done
add esi,2
mov [rounding_mode],0
or [vex_required],40h+80h
test [operand_flags],8
jz take_sae
lods byte [esi]
cmp al,1Fh
jne invalid_operand
lods byte [esi]
mov ah,al
shr ah,4
cmp ah,2
jne invalid_operand
and al,11b
mov [rounding_mode],al
lods byte [esi]
cmp al,'-'
jne invalid_operand
take_sae:
lods byte [esi]
cmp al,1Fh
jne invalid_operand
lods byte [esi]
cmp al,30h
jne invalid_operand
lods byte [esi]
cmp al,'}'
jne invalid_operand
avx512_rounding_done:
retn
 
avx_movdqu_instruction:
mov ah,0F3h
jmp avx_movdq_instruction
avx_movdqa_instruction:
mov ah,66h
avx_movdq_instruction:
mov [opcode_prefix],ah
or [vex_required],2
jmp avx_movps_instruction
avx512_movdqu16_instruction:
or [rex_prefix],8
avx512_movdqu8_instruction:
mov ah,0F2h
jmp avx_movdq_instruction_evex
avx512_movdqu64_instruction:
or [rex_prefix],8
avx512_movdqu32_instruction:
mov ah,0F3h
jmp avx_movdq_instruction_evex
avx512_movdqa64_instruction:
or [rex_prefix],8
avx512_movdqa32_instruction:
mov ah,66h
avx_movdq_instruction_evex:
mov [opcode_prefix],ah
or [vex_required],8
jmp avx_movps_instruction
avx_movpd_instruction:
mov [opcode_prefix],66h
or [rex_prefix],80h
avx_movps_instruction:
or [operand_flags],2
mov [base_code],0Fh
mov [extended_code],al
or [vex_required],1
xor al,al
mov [mmx_size],al
mov [broadcast_size],al
lods byte [esi]
call get_size_operator
cmp al,10h
je avx_reg
inc [extended_code]
test [extended_code],1
jnz avx_mem
add [extended_code],-1+10h
avx_mem:
cmp al,'['
jne invalid_operand
call get_address
or [operand_flags],20h
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [postbyte_register],al
jmp instruction_ready
avx_movntpd_instruction:
or [rex_prefix],80h
avx_movntdq_instruction:
mov [opcode_prefix],66h
avx_movntps_instruction:
mov [base_code],0Fh
mov [extended_code],al
or [vex_required],1
or [operand_flags],10h
mov [mmx_size],0
lods byte [esi]
call get_size_operator
jmp avx_mem
avx_compress_q_instruction:
or [rex_prefix],8
avx_compress_d_instruction:
or [vex_required],8
mov [mmx_size],0
call setup_66_0f_38
lods byte [esi]
call get_size_operator
cmp al,10h
jne avx_mem
lods byte [esi]
call convert_avx_register
mov bl,al
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [postbyte_register],al
jmp nomem_instruction_ready
avx_lddqu_instruction:
mov ah,0F2h
or [vex_required],2
avx_load_instruction:
mov [opcode_prefix],ah
mov [base_code],0Fh
mov [extended_code],al
mov [mmx_size],0
or [vex_required],1
call take_avx_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
jmp instruction_ready
avx_movntdqa_instruction:
mov [supplemental_code],al
mov al,38h
mov ah,66h
jmp avx_load_instruction
avx_movq_instruction:
or [rex_prefix],8
mov [mmx_size],8
jmp avx_mov_instruction
avx_movd_instruction:
mov [mmx_size],4
avx_mov_instruction:
or [vex_required],1
mov [opcode_prefix],66h
mov [base_code],0Fh
mov [extended_code],7Eh
lods byte [esi]
call get_size_operator
cmp al,10h
je avx_movd_reg
cmp al,'['
jne invalid_operand
call get_address
mov al,[mmx_size]
not al
and [operand_size],al
jnz invalid_operand_size
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_avx_register
cmp ah,16
jne invalid_operand_size
mov [postbyte_register],al
cmp [mmx_size],8
jne instruction_ready
and [rex_prefix],not 8
or [rex_prefix],80h
mov [extended_code],0D6h
jmp instruction_ready
avx_movd_reg:
lods byte [esi]
cmp al,0C0h
jae avx_movd_xmmreg
call convert_register
cmp ah,[mmx_size]
jne invalid_operand_size
mov [operand_size],0
mov bl,al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_avx_register
cmp ah,16
jne invalid_operand_size
mov [postbyte_register],al
jmp nomem_instruction_ready
avx_movd_xmmreg:
sub [extended_code],10h
call convert_avx_register
cmp ah,16
jne invalid_operand_size
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je avx_movd_xmmreg_reg
cmp al,'['
jne invalid_operand
call get_address
mov al,[mmx_size]
cmp al,8
jne avx_movd_xmmreg_mem_ready
call avx_movq_xmmreg_xmmreg_opcode
avx_movd_xmmreg_mem_ready:
not al
test [operand_size],al
jnz invalid_operand_size
jmp instruction_ready
avx_movd_xmmreg_reg:
lods byte [esi]
cmp al,0C0h
jae avx_movq_xmmreg_xmmreg
call convert_register
cmp ah,[mmx_size]
jne invalid_operand_size
mov bl,al
jmp nomem_instruction_ready
avx_movq_xmmreg_xmmreg:
cmp [mmx_size],8
jne invalid_operand
call avx_movq_xmmreg_xmmreg_opcode
call convert_avx_register
cmp ah,16
jne invalid_operand_size
mov bl,al
jmp nomem_instruction_ready
avx_movq_xmmreg_xmmreg_opcode:
and [rex_prefix],not 8
or [rex_prefix],80h
add [extended_code],10h
mov [opcode_prefix],0F3h
ret
avx_movddup_instruction:
or [vex_required],1
mov [opcode_prefix],0F2h
mov [base_code],0Fh
mov [extended_code],al
or [rex_prefix],80h
xor al,al
mov [mmx_size],al
mov [broadcast_size],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_avx_register
mov [postbyte_register],al
cmp ah,16
ja avx_movddup_size_ok
mov [mmx_size],8
avx_movddup_size_ok:
call take_avx512_mask
jmp avx_vex_reg_ok
avx_movlpd_instruction:
mov [opcode_prefix],66h
or [rex_prefix],80h
avx_movlps_instruction:
mov [base_code],0Fh
mov [extended_code],al
mov [mmx_size],8
mov [broadcast_size],0
or [vex_required],1
lods byte [esi]
call get_size_operator
cmp al,10h
jne avx_movlps_mem
lods byte [esi]
call convert_avx_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [vex_register],al
cmp [operand_size],16
jne invalid_operand
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_rm
jc invalid_operand
jmp instruction_ready
avx_movlps_mem:
cmp al,'['
jne invalid_operand
call get_address
avx_movlps_mem_:
mov al,[operand_size]
or al,al
jz avx_movlps_mem_size_ok
cmp al,[mmx_size]
jne invalid_operand_size
mov [operand_size],0
avx_movlps_mem_size_ok:
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
cmp ah,16
jne invalid_operand
mov [postbyte_register],al
inc [extended_code]
jmp instruction_ready
avx_movhlps_instruction:
mov [base_code],0Fh
mov [extended_code],al
or [vex_required],1
call take_avx_register
cmp ah,16
jne invalid_operand
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [vex_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov bl,al
jmp nomem_instruction_ready
avx_movsd_instruction:
mov al,0F2h
mov cl,8
or [rex_prefix],80h
jmp avx_movs_instruction
avx_movss_instruction:
mov al,0F3h
mov cl,4
avx_movs_instruction:
mov [opcode_prefix],al
mov [mmx_size],cl
or [vex_required],1
mov [base_code],0Fh
mov [extended_code],10h
lods byte [esi]
call get_size_operator
cmp al,10h
jne avx_movs_mem
lods byte [esi]
call convert_avx_register
cmp ah,16
jne invalid_operand
mov [postbyte_register],al
call take_avx512_mask
xor cl,cl
xchg cl,[operand_size]
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne avx_movs_reg_mem
mov [operand_size],cl
lods byte [esi]
call convert_avx_register
mov [vex_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov bl,al
cmp bl,8
jb nomem_instruction_ready
inc [extended_code]
xchg bl,[postbyte_register]
jmp nomem_instruction_ready
avx_movs_reg_mem:
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
or al,al
jz avx_movs_reg_mem_ok
cmp al,[mmx_size]
jne invalid_operand_size
avx_movs_reg_mem_ok:
jmp instruction_ready
avx_movs_mem:
cmp al,'['
jne invalid_operand
call get_address
or [operand_flags],20h
call take_avx512_mask
jmp avx_movlps_mem_
 
avx_comiss_instruction:
or [operand_flags],2+4+10h
mov cl,4
jmp avx_instruction
avx_comisd_instruction:
or [operand_flags],2+4+10h
mov [opcode_prefix],66h
or [rex_prefix],80h
mov cl,8
jmp avx_instruction
avx_movshdup_instruction:
or [operand_flags],2
mov [opcode_prefix],0F3h
xor cl,cl
jmp avx_instruction
avx_cvtqq2pd_instruction:
mov [opcode_prefix],0F3h
or [vex_required],8
or [operand_flags],2+4+8
or [rex_prefix],8
mov cx,0800h
jmp avx_instruction_with_broadcast
avx_pshuf_w_instruction:
mov [opcode_prefix],al
or [operand_flags],2
mov [immediate_size],1
mov al,70h
xor cl,cl
jmp avx_instruction
avx_single_source_128bit_instruction_38_noevex:
or [operand_flags],2
avx_128bit_instruction_38_noevex:
mov cl,16
jmp avx_instruction_38_noevex
avx_single_source_instruction_38_noevex:
or [operand_flags],2
jmp avx_pi_instruction_38_noevex
avx_pi_instruction_38_noevex:
xor cl,cl
avx_instruction_38_noevex:
or [vex_required],2
avx_instruction_38:
mov [opcode_prefix],66h
mov [supplemental_code],al
mov al,38h
jmp avx_instruction
avx_ss_instruction_3a_imm8_noevex:
mov cl,4
jmp avx_instruction_3a_imm8_noevex
avx_sd_instruction_3a_imm8_noevex:
mov cl,8
jmp avx_instruction_3a_imm8_noevex
avx_single_source_128bit_instruction_3a_imm8_noevex:
or [operand_flags],2
avx_128bit_instruction_3a_imm8_noevex:
mov cl,16
jmp avx_instruction_3a_imm8_noevex
avx_triple_source_instruction_3a_noevex:
xor cl,cl
mov [immediate_size],-1
mov byte [value],0
jmp avx_instruction_3a_noevex
avx_single_source_instruction_3a_imm8_noevex:
or [operand_flags],2
avx_pi_instruction_3a_imm8_noevex:
xor cl,cl
avx_instruction_3a_imm8_noevex:
mov [immediate_size],1
avx_instruction_3a_noevex:
or [vex_required],2
avx_instruction_3a:
mov [opcode_prefix],66h
mov [supplemental_code],al
mov al,3Ah
jmp avx_instruction
avx_pi_instruction_3a_imm8:
xor cl,cl
mov [immediate_size],1
jmp avx_instruction_3a
avx_pclmulqdq_instruction:
mov byte [value],al
mov [immediate_size],-4
or [vex_required],2
mov cl,16
mov al,44h
jmp avx_instruction_3a
 
avx512_single_source_pd_instruction_sae_imm8:
or [operand_flags],2
avx512_pd_instruction_sae_imm8:
or [rex_prefix],8
mov cx,0800h
jmp avx512_instruction_sae_imm8
avx512_single_source_ps_instruction_sae_imm8:
or [operand_flags],2
avx512_ps_instruction_sae_imm8:
mov cx,0400h
jmp avx512_instruction_sae_imm8
avx512_sd_instruction_sae_imm8:
or [rex_prefix],8
mov cx,0008h
jmp avx512_instruction_sae_imm8
avx512_ss_instruction_sae_imm8:
mov cx,0004h
avx512_instruction_sae_imm8:
or [operand_flags],4
avx512_instruction_imm8:
or [vex_required],8
mov [opcode_prefix],66h
mov [immediate_size],1
mov [supplemental_code],al
mov al,3Ah
jmp avx_instruction_with_broadcast
avx512_pd_instruction_er:
or [operand_flags],4+8
jmp avx512_pd_instruction
avx512_single_source_pd_instruction_sae:
or [operand_flags],4
avx512_single_source_pd_instruction:
or [operand_flags],2
avx512_pd_instruction:
or [rex_prefix],8
mov cx,0800h
jmp avx512_instruction
avx512_ps_instruction_er:
or [operand_flags],4+8
jmp avx512_ps_instruction
avx512_single_source_ps_instruction_sae:
or [operand_flags],4
avx512_single_source_ps_instruction:
or [operand_flags],2
avx512_ps_instruction:
mov cx,0400h
jmp avx512_instruction
avx512_sd_instruction_er:
or [operand_flags],8
avx512_sd_instruction_sae:
or [operand_flags],4
avx512_sd_instruction:
or [rex_prefix],8
mov cx,0008h
jmp avx512_instruction
avx512_ss_instruction_er:
or [operand_flags],8
avx512_ss_instruction_sae:
or [operand_flags],4
avx512_ss_instruction:
mov cx,0004h
avx512_instruction:
or [vex_required],8
mov [opcode_prefix],66h
mov [supplemental_code],al
mov al,38h
jmp avx_instruction_with_broadcast
avx512_exp2pd_instruction:
or [rex_prefix],8
or [operand_flags],2+4
mov cx,0840h
jmp avx512_instruction
avx512_exp2ps_instruction:
or [operand_flags],2+4
mov cx,0440h
jmp avx512_instruction
 
fma_instruction_pd:
or [rex_prefix],8
mov cx,0800h
jmp fma_instruction
fma_instruction_ps:
mov cx,0400h
jmp fma_instruction
fma_instruction_sd:
or [rex_prefix],8
mov cx,0008h
jmp fma_instruction
fma_instruction_ss:
mov cx,0004h
fma_instruction:
or [operand_flags],4+8
mov [opcode_prefix],66h
mov [supplemental_code],al
mov al,38h
jmp avx_instruction_with_broadcast
 
fma4_instruction_p:
xor cl,cl
jmp fma4_instruction
fma4_instruction_sd:
mov cl,8
jmp fma4_instruction
fma4_instruction_ss:
mov cl,4
fma4_instruction:
mov [immediate_size],-2
mov byte [value],0
jmp avx_instruction_3a_noevex
 
avx_cmp_pd_instruction:
mov [opcode_prefix],66h
or [rex_prefix],80h
mov cx,0800h
jmp avx_cmp_instruction
avx_cmp_ps_instruction:
mov cx,0400h
jmp avx_cmp_instruction
avx_cmp_sd_instruction:
mov [opcode_prefix],0F2h
or [rex_prefix],80h
mov cx,0008h
jmp avx_cmp_instruction
avx_cmp_ss_instruction:
mov [opcode_prefix],0F3h
mov cx,0004h
avx_cmp_instruction:
mov byte [value],al
mov [immediate_size],-4
or [operand_flags],4+20h
mov al,0C2h
jmp avx_cmp_common
avx_cmpeqq_instruction:
or [rex_prefix],80h
mov ch,8
mov [supplemental_code],al
mov al,38h
jmp avx_cmp_pi_instruction
avx_cmpeqd_instruction:
mov ch,4
jmp avx_cmp_pi_instruction
avx_cmpeqb_instruction:
xor ch,ch
jmp avx_cmp_pi_instruction
avx512_cmp_uq_instruction:
or [rex_prefix],8
mov ch,8
mov ah,1Eh
jmp avx_cmp_pi_instruction_evex
avx512_cmp_ud_instruction:
mov ch,4
mov ah,1Eh
jmp avx_cmp_pi_instruction_evex
avx512_cmp_q_instruction:
or [rex_prefix],8
mov ch,8
mov ah,1Fh
jmp avx_cmp_pi_instruction_evex
avx512_cmp_d_instruction:
mov ch,4
mov ah,1Fh
jmp avx_cmp_pi_instruction_evex
avx512_cmp_uw_instruction:
or [rex_prefix],8
avx512_cmp_ub_instruction:
xor ch,ch
mov ah,3Eh
jmp avx_cmp_pi_instruction_evex
avx512_cmp_w_instruction:
or [rex_prefix],8
avx512_cmp_b_instruction:
xor ch,ch
mov ah,3Fh
avx_cmp_pi_instruction_evex:
mov byte [value],al
mov [immediate_size],-4
mov [supplemental_code],ah
mov al,3Ah
or [vex_required],8
avx_cmp_pi_instruction:
xor cl,cl
or [operand_flags],20h
mov [opcode_prefix],66h
avx_cmp_common:
mov [mmx_size],cl
mov [broadcast_size],ch
mov [extended_code],al
mov [base_code],0Fh
lods byte [esi]
call get_size_operator
cmp al,14h
je avx_maskreg
cmp al,10h
jne invalid_operand
or [vex_required],2
jmp avx_reg
avx_maskreg:
cmp [operand_size],0
jne invalid_operand_size
or [vex_required],8
lods byte [esi]
call convert_mask_register
mov [postbyte_register],al
call take_avx512_mask
jmp avx_vex_reg
avx512_fpclasspd_instruction:
or [rex_prefix],8
mov cx,0800h
jmp avx_fpclass_instruction
avx512_fpclassps_instruction:
mov cx,0400h
jmp avx_fpclass_instruction
avx512_fpclasssd_instruction:
or [rex_prefix],8
mov cx,0008h
jmp avx_fpclass_instruction
avx512_fpclassss_instruction:
mov cx,0004h
avx_fpclass_instruction:
mov [broadcast_size],ch
mov [mmx_size],cl
or [operand_flags],2
call setup_66_0f_3a
mov [immediate_size],1
lods byte [esi]
cmp al,14h
je avx_maskreg
jmp invalid_operand
avx512_ptestnmd_instruction:
mov ch,4
jmp avx512_ptestnm_instruction
avx512_ptestnmq_instruction:
or [rex_prefix],8
mov ch,8
jmp avx512_ptestnm_instruction
avx512_ptestnmw_instruction:
or [rex_prefix],8
avx512_ptestnmb_instruction:
xor ch,ch
avx512_ptestnm_instruction:
mov ah,0F3h
jmp avx512_ptest_instruction
avx512_ptestmd_instruction:
mov ch,4
jmp avx512_ptestm_instruction
avx512_ptestmq_instruction:
or [rex_prefix],8
mov ch,8
jmp avx512_ptestm_instruction
avx512_ptestmw_instruction:
or [rex_prefix],8
avx512_ptestmb_instruction:
xor ch,ch
avx512_ptestm_instruction:
mov ah,66h
avx512_ptest_instruction:
xor cl,cl
mov [opcode_prefix],ah
mov [supplemental_code],al
mov al,38h
or [vex_required],8
jmp avx_cmp_common
 
mask_shift_instruction_q:
or [rex_prefix],8
mask_shift_instruction_d:
or [operand_flags],2
or [immediate_size],1
mov [opcode_prefix],66h
mov [supplemental_code],al
mov al,3Ah
jmp mask_instruction
mask_instruction_single_source_b:
mov [opcode_prefix],66h
jmp mask_instruction_single_source_w
mask_instruction_single_source_d:
mov [opcode_prefix],66h
mask_instruction_single_source_q:
or [rex_prefix],8
mask_instruction_single_source_w:
or [operand_flags],2
jmp mask_instruction
mask_instruction_b:
mov [opcode_prefix],66h
jmp mask_instruction_w
mask_instruction_d:
mov [opcode_prefix],66h
mask_instruction_q:
or [rex_prefix],8
mask_instruction_w:
mov [operand_size],32
mask_instruction:
or [vex_required],1
mov [base_code],0Fh
mov [extended_code],al
call take_mask_register
mov [postbyte_register],al
test [operand_flags],2
jnz mask_instruction_nds_ok
lods byte [esi]
cmp al,','
jne invalid_operand
call take_mask_register
mov [vex_register],al
mask_instruction_nds_ok:
lods byte [esi]
cmp al,','
jne invalid_operand
call take_mask_register
mov bl,al
cmp [immediate_size],0
jne mmx_nomem_imm8
jmp nomem_instruction_ready
take_mask_register:
lods byte [esi]
cmp al,14h
jne invalid_operand
lods byte [esi]
convert_mask_register:
mov ah,al
shr ah,4
cmp ah,5
jne invalid_operand
and al,1111b
ret
kmov_instruction:
mov [mmx_size],al
or [vex_required],1
mov [base_code],0Fh
mov [extended_code],90h
lods byte [esi]
cmp al,14h
je kmov_maskreg
cmp al,10h
je kmov_reg
call get_size_operator
inc [extended_code]
cmp al,'['
jne invalid_argument
call get_address
lods byte [esi]
cmp al,','
jne invalid_operand
call take_mask_register
mov [postbyte_register],al
kmov_with_mem:
mov ah,[mmx_size]
mov al,[operand_size]
or al,al
jz kmov_mem_size_ok
cmp al,ah
jne invalid_operand_size
kmov_mem_size_ok:
call setup_kmov_prefix
jmp instruction_ready
setup_kmov_prefix:
cmp ah,4
jb kmov_w_ok
or [rex_prefix],8
kmov_w_ok:
test ah,1 or 4
jz kmov_prefix_ok
mov [opcode_prefix],66h
kmov_prefix_ok:
ret
kmov_maskreg:
lods byte [esi]
call convert_mask_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
cmp al,14h
je kmov_maskreg_maskreg
cmp al,10h
je kmov_maskreg_reg
call get_size_operator
cmp al,'['
jne invalid_argument
call get_address
jmp kmov_with_mem
kmov_maskreg_maskreg:
lods byte [esi]
call convert_mask_register
mov bl,al
mov ah,[mmx_size]
call setup_kmov_prefix
jmp nomem_instruction_ready
kmov_maskreg_reg:
add [extended_code],2
lods byte [esi]
call convert_register
kmov_with_reg:
mov bl,al
mov al,[mmx_size]
mov ah,4
cmp al,ah
jbe kmov_reg_size_check
mov ah,al
kmov_reg_size_check:
cmp ah,[operand_size]
jne invalid_operand_size
cmp al,8
je kmov_f2_w1
cmp al,2
ja kmov_f2
je nomem_instruction_ready
mov [opcode_prefix],66h
jmp nomem_instruction_ready
kmov_f2_w1:
or [rex_prefix],8
kmov_f2:
mov [opcode_prefix],0F2h
jmp nomem_instruction_ready
kmov_reg:
add [extended_code],3
lods byte [esi]
call convert_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_mask_register
jmp kmov_with_reg
avx512_pmov_m2_instruction_w1:
or [rex_prefix],8
avx512_pmov_m2_instruction:
or [vex_required],8
call setup_f3_0f_38
call take_avx_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_mask_register
mov bl,al
jmp nomem_instruction_ready
avx512_pmov_2m_instruction_w1:
or [rex_prefix],8
avx512_pmov_2m_instruction:
or [vex_required],8
call setup_f3_0f_38
call take_mask_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov bl,al
jmp nomem_instruction_ready
setup_f3_0f_38:
mov [extended_code],38h
mov [supplemental_code],al
mov [base_code],0Fh
mov [opcode_prefix],0F3h
ret
 
vzeroall_instruction:
mov [operand_size],32
vzeroupper_instruction:
mov [base_code],0Fh
mov [extended_code],al
and [displacement_compression],0
call store_vex_instruction_code
jmp instruction_assembled
vldmxcsr_instruction:
or [vex_required],2
jmp fxsave_instruction
 
avx_perm2f128_instruction:
or [vex_required],2
xor ch,ch
avx_instruction_imm8_without_128bit:
mov [immediate_size],1
mov ah,3Ah
jmp avx_instruction_without_128bit
avx512_shuf_q_instruction:
or [rex_prefix],8
or [vex_required],8
mov ch,8
jmp avx_instruction_imm8_without_128bit
avx512_shuf_d_instruction:
or [vex_required],8
mov ch,4
jmp avx_instruction_imm8_without_128bit
avx_permd_instruction:
mov ah,38h
mov ch,4
avx_instruction_without_128bit:
xor cl,cl
call setup_avx_66_supplemental
call take_avx_register
cmp ah,32
jb invalid_operand_size
mov [postbyte_register],al
call take_avx512_mask
jmp avx_vex_reg
setup_avx_66_supplemental:
mov [opcode_prefix],66h
mov [broadcast_size],ch
mov [mmx_size],cl
mov [base_code],0Fh
mov [extended_code],ah
mov [supplemental_code],al
or [vex_required],1
ret
avx_permq_instruction:
or [rex_prefix],8
mov ch,8
jmp avx_permil_instruction
avx_permilpd_instruction:
or [rex_prefix],80h
mov ch,8
jmp avx_permil_instruction
avx_permilps_instruction:
mov ch,4
avx_permil_instruction:
or [operand_flags],2
xor cl,cl
mov ah,3Ah
call setup_avx_66_supplemental
call take_avx_register
cmp [supplemental_code],4
jae avx_permil_size_ok
cmp ah,32
jb invalid_operand_size
avx_permil_size_ok:
mov [postbyte_register],al
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_rm
jnc mmx_imm8
mov bl,al
cmp byte [esi],','
jne invalid_operand
mov al,[esi+1]
cmp al,11h
jne avx_permil_rm_or_imm8
mov al,[esi+3]
avx_permil_rm_or_imm8:
cmp al,'('
je mmx_nomem_imm8
mov [vex_register],bl
inc esi
mov [extended_code],38h
mov al,[supplemental_code]
cmp al,4
jb avx_permq_rm
add [supplemental_code],8
jmp avx_regs_rm
avx_permq_rm:
or [vex_required],8
shl al,5
neg al
add al,36h
mov [supplemental_code],al
jmp avx_regs_rm
vpermil_2pd_instruction:
mov [immediate_size],-2
mov byte [value],al
mov al,49h
jmp vpermil2_instruction_setup
vpermil_2ps_instruction:
mov [immediate_size],-2
mov byte [value],al
mov al,48h
jmp vpermil2_instruction_setup
vpermil2_instruction:
mov [immediate_size],-3
mov byte [value],0
vpermil2_instruction_setup:
or [vex_required],2
mov [base_code],0Fh
mov [supplemental_code],al
mov al,3Ah
xor cl,cl
jmp avx_instruction
 
avx_shift_q_instruction_evex:
or [vex_required],8
avx_shift_q_instruction:
or [rex_prefix],80h
mov cl,8
jmp avx_shift_instruction
avx_shift_d_instruction:
mov cl,4
jmp avx_shift_instruction
avx_shift_bw_instruction:
xor cl,cl
avx_shift_instruction:
mov [broadcast_size],cl
mov [mmx_size],0
mov [opcode_prefix],66h
mov [base_code],0Fh
mov [extended_code],al
or [vex_required],1
call take_avx_register
mov [postbyte_register],al
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
xor cl,cl
xchg cl,[operand_size]
lods byte [esi]
call get_size_operator
cmp al,'['
je avx_shift_reg_mem
mov [operand_size],cl
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_avx_register
mov [vex_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
push esi
xor cl,cl
xchg cl,[operand_size]
lods byte [esi]
call get_size_operator
cmp al,10h
je avx_shift_reg_reg_reg
pop esi
cmp al,'['
je avx_shift_reg_reg_mem
xchg cl,[operand_size]
test cl,not 1
jnz invalid_operand_size
dec esi
call convert_avx_shift_opcode
mov bl,al
jmp mmx_nomem_imm8
convert_avx_shift_opcode:
mov al,[extended_code]
mov ah,al
and ah,1111b
add ah,70h
mov [extended_code],ah
shr al,4
sub al,0Ch
shl al,1
xchg al,[postbyte_register]
xchg al,[vex_register]
ret
avx_shift_reg_reg_reg:
pop eax
lods byte [esi]
call convert_xmm_register
xchg cl,[operand_size]
mov bl,al
jmp nomem_instruction_ready
avx_shift_reg_reg_mem:
mov [mmx_size],16
push ecx
lods byte [esi]
call get_size_operator
call get_address
pop eax
xchg al,[operand_size]
test al,al
jz instruction_ready
cmp al,16
jne invalid_operand_size
jmp instruction_ready
avx_shift_reg_mem:
or [vex_required],8
call take_avx_mem
call convert_avx_shift_opcode
jmp mmx_imm8
avx_shift_dq_instruction:
mov [postbyte_register],al
mov [opcode_prefix],66h
mov [base_code],0Fh
mov [extended_code],73h
or [vex_required],1
mov [mmx_size],0
call take_avx_register
mov [vex_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
je avx_shift_dq_reg_mem
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_avx_register
mov bl,al
jmp mmx_nomem_imm8
avx_shift_dq_reg_mem:
or [vex_required],8
call get_address
jmp mmx_imm8
avx512_rotate_q_instruction:
mov cl,8
or [rex_prefix],cl
jmp avx512_rotate_instruction
avx512_rotate_d_instruction:
mov cl,4
avx512_rotate_instruction:
mov [broadcast_size],cl
mov [postbyte_register],al
mov [opcode_prefix],66h
mov [base_code],0Fh
mov [extended_code],72h
or [vex_required],8
mov [mmx_size],0
mov [immediate_size],1
call take_avx_register
mov [vex_register],al
call take_avx512_mask
jmp avx_vex_reg_ok
 
avx_pmovsxbq_instruction:
mov cl,2
jmp avx_pmovsx_instruction
avx_pmovsxbd_instruction:
mov cl,4
jmp avx_pmovsx_instruction
avx_pmovsxbw_instruction:
mov cl,8
avx_pmovsx_instruction:
mov [mmx_size],cl
or [vex_required],1
call setup_66_0f_38
call take_avx_register
mov [postbyte_register],al
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
xor al,al
xchg al,[operand_size]
bsf ecx,eax
sub cl,4
shl [mmx_size],cl
push eax
lods byte [esi]
call get_size_operator
cmp al,10h
je avx_pmovsx_reg_reg
cmp al,'['
jne invalid_operand
call get_address
pop eax
xchg al,[operand_size]
or al,al
jz instruction_ready
cmp al,[mmx_size]
jne invalid_operand_size
jmp instruction_ready
avx_pmovsx_reg_reg:
lods byte [esi]
call convert_avx_register
mov bl,al
cmp ah,[mmx_size]
je avx_pmovsx_xmmreg_reg_size_ok
jb invalid_operand_size
cmp ah,16
jne invalid_operand_size
avx_pmovsx_xmmreg_reg_size_ok:
pop eax
mov [operand_size],al
jmp nomem_instruction_ready
avx512_pmovqb_instruction:
mov cl,2
jmp avx512_pmov_instruction
avx512_pmovdb_instruction:
mov cl,4
jmp avx512_pmov_instruction
avx512_pmovwb_instruction:
mov cl,8
avx512_pmov_instruction:
mov [mmx_size],cl
or [vex_required],8
mov [extended_code],38h
mov [supplemental_code],al
mov [base_code],0Fh
mov [opcode_prefix],0F3h
lods byte [esi]
call get_size_operator
cmp al,10h
je avx512_pmov_reg
cmp al,'['
jne invalid_operand
call get_address
or [operand_flags],20h
call avx512_pmov_common
or al,al
jz instruction_ready
cmp al,[mmx_size]
jne invalid_operand_size
jmp instruction_ready
avx512_pmov_common:
call take_avx512_mask
xor al,al
xchg al,[operand_size]
push eax
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [postbyte_register],al
mov al,ah
mov ah,cl
bsf ecx,eax
sub cl,4
shl [mmx_size],cl
mov cl,ah
pop eax
ret
avx512_pmov_reg:
lods byte [esi]
call convert_avx_register
mov bl,al
call avx512_pmov_common
cmp al,[mmx_size]
je nomem_instruction_ready
jb invalid_operand_size
cmp al,16
jne invalid_operand_size
jmp nomem_instruction_ready
 
avx_broadcast_128_instruction_noevex:
or [vex_required],2
mov cl,10h
jmp avx_broadcast_instruction
avx512_broadcast_32x2_instruction:
mov cl,08h
jmp avx_broadcast_instruction_evex
avx512_broadcast_32x4_instruction:
mov cl,10h
jmp avx_broadcast_instruction_evex
avx512_broadcast_32x8_instruction:
mov cl,20h
jmp avx_broadcast_instruction_evex
avx512_broadcast_64x2_instruction:
mov cl,10h
jmp avx_broadcast_instruction_w1_evex
avx512_broadcast_64x4_instruction:
mov cl,20h
avx_broadcast_instruction_w1_evex:
or [rex_prefix],8
avx_broadcast_instruction_evex:
or [vex_required],8
jmp avx_broadcast_instruction
avx_broadcastss_instruction:
mov cl,4
jmp avx_broadcast_instruction
avx_broadcastsd_instruction:
or [rex_prefix],80h
mov cl,8
jmp avx_broadcast_instruction
avx_pbroadcastb_instruction:
mov cl,1
jmp avx_broadcast_pi_instruction
avx_pbroadcastw_instruction:
mov cl,2
jmp avx_broadcast_pi_instruction
avx_pbroadcastd_instruction:
mov cl,4
jmp avx_broadcast_pi_instruction
avx_pbroadcastq_instruction:
mov cl,8
or [rex_prefix],80h
avx_broadcast_pi_instruction:
or [operand_flags],40h
avx_broadcast_instruction:
mov [opcode_prefix],66h
mov [supplemental_code],al
mov al,38h
mov [mmx_size],cl
mov [base_code],0Fh
mov [extended_code],al
or [vex_required],1
call take_avx_register
cmp ah,[mmx_size]
je invalid_operand_size
test [operand_flags],40h
jnz avx_broadcast_destination_size_ok
cmp [mmx_size],4
je avx_broadcast_destination_size_ok
cmp [supplemental_code],59h
je avx_broadcast_destination_size_ok
cmp ah,16
je invalid_operand_size
avx_broadcast_destination_size_ok:
xor ah,ah
xchg ah,[operand_size]
push eax
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je avx_broadcast_reg_reg
cmp al,'['
jne invalid_operand
call get_address
pop eax
xchg ah,[operand_size]
mov [postbyte_register],al
mov al,[broadcast_size]
mov al,[mmx_size]
cmp al,ah
je instruction_ready
or al,al
jz instruction_ready
or ah,ah
jz instruction_ready
jmp invalid_operand_size
avx_broadcast_reg_reg:
lods byte [esi]
test [operand_flags],40h
jz avx_broadcast_reg_avx_reg
cmp al,60h
jb avx_broadcast_reg_general_reg
cmp al,80h
jb avx_broadcast_reg_avx_reg
cmp al,0C0h
jb avx_broadcast_reg_general_reg
avx_broadcast_reg_avx_reg:
call convert_avx_register
mov bl,al
mov al,[mmx_size]
or al,al
jz avx_broadcast_reg_avx_reg_size_ok
cmp ah,16
jne invalid_operand_size
cmp al,ah
jae invalid_operand
avx_broadcast_reg_avx_reg_size_ok:
pop eax
xchg ah,[operand_size]
mov [postbyte_register],al
test [vex_required],2
jnz invalid_operand
jmp nomem_instruction_ready
avx_broadcast_reg_general_reg:
call convert_register
mov bl,al
mov al,[mmx_size]
or al,al
jz avx_broadcast_reg_general_reg_size_ok
cmp al,ah
jne invalid_operand_size
avx_broadcast_reg_general_reg_size_ok:
cmp al,4
jb avx_broadcast_reg_general_reg_ready
cmp al,8
mov al,3
jne avx_broadcast_reg_general_reg_ready
or [rex_prefix],8
avx_broadcast_reg_general_reg_ready:
add al,7Ah-1
mov [supplemental_code],al
or [vex_required],8
pop eax
xchg ah,[operand_size]
mov [postbyte_register],al
jmp nomem_instruction_ready
 
avx512_extract_64x4_instruction:
or [rex_prefix],8
avx512_extract_32x8_instruction:
or [vex_required],8
mov cl,32
jmp avx_extractf_instruction
avx512_extract_64x2_instruction:
or [rex_prefix],8
avx512_extract_32x4_instruction:
or [vex_required],8
mov cl,16
jmp avx_extractf_instruction
avx_extractf128_instruction:
or [vex_required],2
mov cl,16
avx_extractf_instruction:
mov [mmx_size],cl
call setup_66_0f_3a
lods byte [esi]
call get_size_operator
cmp al,10h
je avx_extractf_reg
cmp al,'['
jne invalid_operand
call get_address
xor al,al
xchg al,[operand_size]
or al,al
jz avx_extractf_mem_size_ok
cmp al,[mmx_size]
jne invalid_operand_size
avx_extractf_mem_size_ok:
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
cmp ah,[mmx_size]
jbe invalid_operand_size
mov [postbyte_register],al
jmp mmx_imm8
avx_extractf_reg:
lods byte [esi]
call convert_avx_register
cmp ah,[mmx_size]
jne invalid_operand_size
push eax
call take_avx512_mask
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
cmp ah,[mmx_size]
jbe invalid_operand_size
mov [postbyte_register],al
pop ebx
jmp mmx_nomem_imm8
avx512_insert_64x4_instruction:
or [rex_prefix],8
avx512_insert_32x8_instruction:
or [vex_required],8
mov cl,32
jmp avx_insertf_instruction
avx512_insert_64x2_instruction:
or [rex_prefix],8
avx512_insert_32x4_instruction:
or [vex_required],8
mov cl,16
jmp avx_insertf_instruction
avx_insertf128_instruction:
or [vex_required],2
mov cl,16
avx_insertf_instruction:
mov [mmx_size],cl
mov [broadcast_size],0
call setup_66_0f_3a
call take_avx_register
cmp ah,[mmx_size]
jbe invalid_operand
mov [postbyte_register],al
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [vex_register],al
mov al,[mmx_size]
xchg al,[operand_size]
push eax
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je avx_insertf_reg_reg_reg
cmp al,'['
jne invalid_operand
call get_address
pop eax
mov [operand_size],al
jmp mmx_imm8
avx_insertf_reg_reg_reg:
lods byte [esi]
call convert_avx_register
mov bl,al
pop eax
mov [operand_size],al
jmp mmx_nomem_imm8
avx_extract_b_instruction:
mov cl,1
jmp avx_extract_instruction
avx_extract_w_instruction:
mov cl,2
jmp avx_extract_instruction
avx_extract_q_instruction:
or [rex_prefix],8
mov cl,8
jmp avx_extract_instruction
avx_extract_d_instruction:
mov cl,4
avx_extract_instruction:
mov [mmx_size],cl
call setup_66_0f_3a
or [vex_required],1
lods byte [esi]
call get_size_operator
cmp al,10h
je avx_extractps_reg
cmp al,'['
jne invalid_operand
call get_address
mov al,[mmx_size]
not al
and [operand_size],al
jnz invalid_operand_size
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_avx_register
cmp ah,16
jne invalid_operand_size
mov [postbyte_register],al
jmp mmx_imm8
avx_extractps_reg:
lods byte [esi]
call convert_register
mov bl,al
mov al,[mmx_size]
cmp ah,al
jb invalid_operand_size
cmp ah,4
je avx_extractps_reg_size_ok
cmp ah,8
jne invalid_operand_size
cmp [code_type],64
jne invalid_operand
cmp al,4
jae avx_extractps_reg_size_ok
or [rex_prefix],8
avx_extractps_reg_size_ok:
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_avx_register
cmp ah,16
jne invalid_operand_size
mov [postbyte_register],al
cmp [supplemental_code],15h
jne mmx_nomem_imm8
mov [extended_code],0C5h
xchg bl,[postbyte_register]
jmp mmx_nomem_imm8
avx_insertps_instruction:
mov [immediate_size],1
or [operand_flags],10h
mov [opcode_prefix],66h
mov [supplemental_code],al
mov al,3Ah
mov cl,4
jmp avx_instruction
avx_pinsrb_instruction:
mov cl,1
jmp avx_pinsr_instruction_3a
avx_pinsrw_instruction:
mov cl,2
jmp avx_pinsr_instruction
avx_pinsrd_instruction:
mov cl,4
jmp avx_pinsr_instruction_3a
avx_pinsrq_instruction:
mov cl,8
or [rex_prefix],8
avx_pinsr_instruction_3a:
mov [supplemental_code],al
mov al,3Ah
avx_pinsr_instruction:
mov [opcode_prefix],66h
mov [base_code],0Fh
mov [extended_code],al
mov [mmx_size],cl
or [vex_required],1
call take_avx_register
cmp ah,16
jne invalid_operand_size
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [vex_register],al
jmp pinsr_xmmreg
 
avx_cvtudq2pd_instruction:
or [vex_required],8
avx_cvtdq2pd_instruction:
mov [opcode_prefix],0F3h
mov cl,4
jmp avx_cvt_d_instruction
avx_cvtps2qq_instruction:
or [operand_flags],8
avx_cvttps2qq_instruction:
or [operand_flags],4
or [vex_required],8
mov [opcode_prefix],66h
mov cl,4
jmp avx_cvt_d_instruction
avx_cvtps2pd_instruction:
or [operand_flags],4
mov cl,4
avx_cvt_d_instruction:
mov [base_code],0Fh
mov [extended_code],al
or [vex_required],1
mov [broadcast_size],cl
call take_avx_register
mov [postbyte_register],al
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
xor ecx,ecx
xchg cl,[operand_size]
mov al,cl
shr al,1
mov [mmx_size],al
lods byte [esi]
call get_size_operator
cmp al,'['
je avx_cvt_d_reg_mem
cmp al,10h
jne invalid_operand
mov [operand_size],0
lods byte [esi]
call convert_avx_register
cmp ah,[mmx_size]
je avx_cvt_d_reg_reg_size_ok
jb invalid_operand_size
cmp ah,16
jne invalid_operand_size
avx_cvt_d_reg_reg_size_ok:
mov bl,al
mov [operand_size],cl
call take_avx512_rounding
jmp nomem_instruction_ready
avx_cvt_d_reg_mem:
call take_avx_mem
jmp instruction_ready
avx_cvtpd2dq_instruction:
or [operand_flags],4+8
mov [opcode_prefix],0F2h
jmp avx_cvt_q_instruction
avx_cvtuqq2ps_instruction:
mov [opcode_prefix],0F2h
avx_cvtpd2udq_instruction:
or [operand_flags],8
avx_cvttpd2udq_instruction:
or [operand_flags],4
or [vex_required],8
jmp avx_cvt_q_instruction
avx_cvtpd2ps_instruction:
or [operand_flags],8
avx_cvttpd2dq_instruction:
or [operand_flags],4
mov [opcode_prefix],66h
avx_cvt_q_instruction:
mov [broadcast_size],8
mov [base_code],0Fh
mov [extended_code],al
or [vex_required],1
or [rex_prefix],80h
call take_avx_register
mov [postbyte_register],al
push eax
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
xor al,al
mov [operand_size],al
mov [mmx_size],al
call take_avx_rm
jnc avx_cvt_q_reg_mem
mov bl,al
pop eax
call avx_cvt_q_check_size
call take_avx512_rounding
jmp nomem_instruction_ready
avx_cvt_q_reg_mem:
pop eax
call avx_cvt_q_check_size
jmp instruction_ready
avx_cvt_q_check_size:
mov al,[operand_size]
or al,al
jz avx_cvt_q_size_not_specified
shr al,1
cmp al,ah
je avx_cvt_q_size_ok
ja invalid_operand_size
cmp ah,16
jne invalid_operand_size
avx_cvt_q_size_ok:
ret
avx_cvt_q_size_not_specified:
cmp ah,64 shr 1
jne recoverable_unknown_size
mov [operand_size],64
ret
avx_cvttps2udq_instruction:
or [vex_required],8
or [operand_flags],2+4
mov cx,0400h
jmp avx_instruction_with_broadcast
avx_cvttps2dq_instruction:
mov [opcode_prefix],0F3h
or [operand_flags],2+4
mov cx,0400h
jmp avx_instruction_with_broadcast
avx_cvtph2ps_instruction:
mov [opcode_prefix],66h
mov [supplemental_code],al
or [operand_flags],4
mov al,38h
xor cl,cl
jmp avx_cvt_d_instruction
avx_cvtps2ph_instruction:
call setup_66_0f_3a
or [vex_required],1
or [operand_flags],4
lods byte [esi]
call get_size_operator
cmp al,10h
je vcvtps2ph_reg
cmp al,'['
jne invalid_operand
call get_address
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
shl [operand_size],1
call take_avx_register
mov [postbyte_register],al
shr ah,1
mov [mmx_size],ah
jmp mmx_imm8
vcvtps2ph_reg:
lods byte [esi]
call convert_avx_register
mov bl,al
call take_avx512_mask
xor cl,cl
xchg cl,[operand_size]
shl cl,1
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [postbyte_register],al
or cl,cl
jz vcvtps2ph_reg_size_ok
cmp cl,ah
je vcvtps2ph_reg_size_ok
jb invalid_operand_size
cmp ah,16
jne invalid_operand_size
vcvtps2ph_reg_size_ok:
call take_avx512_rounding
jmp mmx_nomem_imm8
 
avx_cvtsd2usi_instruction:
or [operand_flags],8
avx_cvttsd2usi_instruction:
or [vex_required],8
jmp avx_cvttsd2si_instruction
avx_cvtsd2si_instruction:
or [operand_flags],8
avx_cvttsd2si_instruction:
mov ah,0F2h
mov cl,8
jmp avx_cvt_2si_instruction
avx_cvtss2usi_instruction:
or [operand_flags],8
avx_cvttss2usi_instruction:
or [vex_required],8
jmp avx_cvttss2si_instruction
avx_cvtss2si_instruction:
or [operand_flags],8
avx_cvttss2si_instruction:
mov ah,0F3h
mov cl,4
avx_cvt_2si_instruction:
or [operand_flags],2+4
mov [mmx_size],cl
mov [broadcast_size],0
mov [opcode_prefix],ah
mov [base_code],0Fh
mov [extended_code],al
or [vex_required],1
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_register
mov [postbyte_register],al
mov [operand_size],0
cmp ah,4
je avx_cvt_2si_reg
cmp ah,8
jne invalid_operand_size
call operand_64bit
avx_cvt_2si_reg:
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_rm
jnc instruction_ready
mov bl,al
call take_avx512_rounding
jmp nomem_instruction_ready
avx_cvtusi2sd_instruction:
or [vex_required],8
avx_cvtsi2sd_instruction:
mov ah,0F2h
mov cl,8
jmp avx_cvtsi_instruction
avx_cvtusi2ss_instruction:
or [vex_required],8
avx_cvtsi2ss_instruction:
mov ah,0F3h
mov cl,4
avx_cvtsi_instruction:
or [operand_flags],2+4+8
mov [mmx_size],cl
mov [opcode_prefix],ah
mov [base_code],0Fh
mov [extended_code],al
or [vex_required],1
call take_avx_register
cmp ah,16
jne invalid_operand_size
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [vex_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,'['
je avx_cvtsi_reg_reg_mem
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_register
mov bl,al
cmp ah,4
je avx_cvtsi_reg_reg_reg32
cmp ah,8
jne invalid_operand_size
call operand_64bit
avx_cvtsi_rounding:
call take_avx512_rounding
jmp nomem_instruction_ready
avx_cvtsi_reg_reg_reg32:
cmp [mmx_size],8
jne avx_cvtsi_rounding
jmp nomem_instruction_ready
avx_cvtsi_reg_reg_mem:
call get_address
mov al,[operand_size]
mov [mmx_size],al
or al,al
jz single_mem_nosize
cmp al,4
je instruction_ready
cmp al,8
jne invalid_operand_size
call operand_64bit
jmp instruction_ready
 
avx_maskmov_w1_instruction:
or [rex_prefix],8
avx_maskmov_instruction:
call setup_66_0f_38
mov [mmx_size],0
or [vex_required],2
lods byte [esi]
call get_size_operator
cmp al,10h
jne avx_maskmov_mem
lods byte [esi]
call convert_avx_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [vex_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
cmp al,'['
jne invalid_operand
call get_address
jmp instruction_ready
avx_maskmov_mem:
cmp al,'['
jne invalid_operand
call get_address
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [vex_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov [postbyte_register],al
add [supplemental_code],2
jmp instruction_ready
avx_movmskpd_instruction:
mov [opcode_prefix],66h
avx_movmskps_instruction:
mov [base_code],0Fh
mov [extended_code],50h
or [vex_required],2
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_register
mov [postbyte_register],al
cmp ah,4
je avx_movmskps_reg_ok
cmp ah,8
jne invalid_operand_size
cmp [code_type],64
jne invalid_operand
avx_movmskps_reg_ok:
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov bl,al
jmp nomem_instruction_ready
avx_maskmovdqu_instruction:
or [vex_required],2
jmp maskmovdqu_instruction
avx_pmovmskb_instruction:
or [vex_required],2
mov [opcode_prefix],66h
mov [base_code],0Fh
mov [extended_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_register
cmp ah,4
je avx_pmovmskb_reg_size_ok
cmp [code_type],64
jne invalid_operand_size
cmp ah,8
jnz invalid_operand_size
avx_pmovmskb_reg_size_ok:
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
call take_avx_register
mov bl,al
jmp nomem_instruction_ready
 
gather_pd_instruction:
or [rex_prefix],8
gather_ps_instruction:
call setup_66_0f_38
or [vex_required],4
or [operand_flags],20h
call take_avx_register
mov [postbyte_register],al
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
xor cl,cl
xchg cl,[operand_size]
push ecx
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_argument
call get_address
pop eax
xchg al,[operand_size]
gather_mem_size_check:
mov ah,4
test [rex_prefix],8
jz gather_elements_size_ok
add ah,ah
gather_elements_size_ok:
mov [mmx_size],ah
test al,al
jz gather_mem_size_ok
cmp al,ah
jne invalid_operand_size
gather_mem_size_ok:
cmp byte [esi],','
je gather_reg_mem_reg
test [vex_required],20h
jz invalid_operand
mov ah,[operand_size]
mov al,80h
jmp gather_arguments_ok
gather_reg_mem_reg:
or [vex_required],2
inc esi
call take_avx_register
gather_arguments_ok:
mov [vex_register],al
cmp al,[postbyte_register]
je disallowed_combination_of_registers
mov al,bl
and al,11111b
cmp al,[postbyte_register]
je disallowed_combination_of_registers
cmp al,[vex_register]
je disallowed_combination_of_registers
mov al,bl
shr al,5
cmp al,0Ch shr 1
je gather_vr128
mov ah,32
cmp al,6 shr 1
jne gather_regular
add ah,ah
gather_regular:
mov al,[rex_prefix]
shr al,3
xor al,[supplemental_code]
test al,1
jz gather_uniform
test [supplemental_code],1
jz gather_double
mov al,ah
xchg al,[operand_size]
add al,al
cmp al,ah
jne invalid_operand_size
jmp instruction_ready
gather_double:
add ah,ah
gather_uniform:
cmp ah,[operand_size]
jne invalid_operand_size
jmp instruction_ready
gather_vr128:
cmp ah,16
je instruction_ready
cmp ah,32
jne invalid_operand_size
test [supplemental_code],1
jnz invalid_operand_size
test [rex_prefix],8
jz invalid_operand_size
jmp instruction_ready
scatter_pd_instruction:
or [rex_prefix],8
scatter_ps_instruction:
call setup_66_0f_38
or [vex_required],4+8
or [operand_flags],20h
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_argument
call get_address
call take_avx512_mask
lods byte [esi]
cmp al,','
jne invalid_operand
xor al,al
xchg al,[operand_size]
push eax
call take_avx_register
mov [postbyte_register],al
pop eax
jmp gather_mem_size_check
gatherpf_qpd_instruction:
mov ah,0C7h
jmp gatherpf_pd_instruction
gatherpf_dpd_instruction:
mov ah,0C6h
gatherpf_pd_instruction:
or [rex_prefix],8
mov cl,8
jmp gatherpf_instruction
gatherpf_qps_instruction:
mov ah,0C7h
jmp gatherpf_ps_instruction
gatherpf_dps_instruction:
mov ah,0C6h
gatherpf_ps_instruction:
mov cl,4
gatherpf_instruction:
mov [mmx_size],cl
mov [postbyte_register],al
mov al,ah
call setup_66_0f_38
or [vex_required],4+8
or [operand_flags],20h
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_argument
call get_address
call take_avx512_mask
mov ah,[mmx_size]
mov al,[operand_size]
or al,al
jz gatherpf_mem_size_ok
cmp al,ah
jne invalid_operand_size
gatherpf_mem_size_ok:
mov [operand_size],64
mov al,6 shr 1
cmp ah,4
je gatherpf_check_vsib
cmp [supplemental_code],0C6h
jne gatherpf_check_vsib
mov al,0Eh shr 1
gatherpf_check_vsib:
mov ah,bl
shr ah,5
cmp al,ah
jne invalid_operand
jmp instruction_ready
 
bmi_instruction:
mov [base_code],0Fh
mov [extended_code],38h
mov [supplemental_code],0F3h
mov [postbyte_register],al
bmi_reg:
or [vex_required],2
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_register
mov [vex_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je bmi_reg_reg
cmp al,'['
jne invalid_argument
call get_address
call operand_32or64
jmp instruction_ready
bmi_reg_reg:
lods byte [esi]
call convert_register
mov bl,al
call operand_32or64
jmp nomem_instruction_ready
operand_32or64:
mov al,[operand_size]
cmp al,4
je operand_32or64_ok
cmp al,8
jne invalid_operand_size
cmp [code_type],64
jne invalid_operand
or [rex_prefix],8
operand_32or64_ok:
ret
pdep_instruction:
mov [opcode_prefix],0F2h
jmp andn_instruction
pext_instruction:
mov [opcode_prefix],0F3h
andn_instruction:
mov [base_code],0Fh
mov [extended_code],38h
mov [supplemental_code],al
or [vex_required],2
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
jmp bmi_reg
sarx_instruction:
mov [opcode_prefix],0F3h
jmp bzhi_instruction
shrx_instruction:
mov [opcode_prefix],0F2h
jmp bzhi_instruction
shlx_instruction:
mov [opcode_prefix],66h
bzhi_instruction:
mov [base_code],0Fh
mov [extended_code],38h
mov [supplemental_code],al
or [vex_required],2
call get_reg_mem
jc bzhi_reg_reg
call get_vex_source_register
jc invalid_operand
call operand_32or64
jmp instruction_ready
bzhi_reg_reg:
call get_vex_source_register
jc invalid_operand
call operand_32or64
jmp nomem_instruction_ready
get_vex_source_register:
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne no_vex_source_register
lods byte [esi]
call convert_register
mov [vex_register],al
clc
ret
no_vex_source_register:
stc
ret
bextr_instruction:
mov [base_code],0Fh
mov [extended_code],38h
mov [supplemental_code],al
or [vex_required],2
call get_reg_mem
jc bextr_reg_reg
call get_vex_source_register
jc bextr_reg_mem_imm32
call operand_32or64
jmp instruction_ready
bextr_reg_reg:
call get_vex_source_register
jc bextr_reg_reg_imm32
call operand_32or64
jmp nomem_instruction_ready
setup_bextr_imm_opcode:
mov [xop_opcode_map],0Ah
mov [base_code],10h
call operand_32or64
ret
bextr_reg_mem_imm32:
call get_imm32
call setup_bextr_imm_opcode
jmp store_instruction_with_imm32
bextr_reg_reg_imm32:
call get_imm32
call setup_bextr_imm_opcode
store_nomem_instruction_with_imm32:
call store_nomem_instruction
mov eax,dword [value]
call mark_relocation
stos dword [edi]
jmp instruction_assembled
get_imm32:
cmp al,'('
jne invalid_operand
push edx ebx ecx
call get_dword_value
mov dword [value],eax
pop ecx ebx edx
ret
rorx_instruction:
mov [opcode_prefix],0F2h
mov [base_code],0Fh
mov [extended_code],3Ah
mov [supplemental_code],al
or [vex_required],2
call get_reg_mem
jc rorx_reg_reg
call operand_32or64
jmp mmx_imm8
rorx_reg_reg:
call operand_32or64
jmp mmx_nomem_imm8
 
tbm_instruction:
mov [xop_opcode_map],9
mov ah,al
shr ah,4
and al,111b
mov [base_code],ah
mov [postbyte_register],al
jmp bmi_reg
 
llwpcb_instruction:
or [vex_required],2
mov [xop_opcode_map],9
mov [base_code],12h
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_register
mov bl,al
call operand_32or64
jmp nomem_instruction_ready
lwpins_instruction:
or [vex_required],2
mov [xop_opcode_map],0Ah
mov [base_code],12h
mov [vex_register],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
xor cl,cl
xchg cl,[operand_size]
lods byte [esi]
call get_size_operator
cmp al,10h
je lwpins_reg_reg
cmp al,'['
jne invalid_argument
push ecx
call get_address
pop eax
xchg al,[operand_size]
test al,al
jz lwpins_reg_mem_size_ok
cmp al,4
jne invalid_operand_size
lwpins_reg_mem_size_ok:
call prepare_lwpins
jmp store_instruction_with_imm32
lwpins_reg_reg:
lods byte [esi]
call convert_register
cmp ah,4
jne invalid_operand_size
mov [operand_size],cl
mov bl,al
call prepare_lwpins
jmp store_nomem_instruction_with_imm32
prepare_lwpins:
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_imm32
call operand_32or64
mov al,[vex_register]
xchg al,[postbyte_register]
mov [vex_register],al
ret
 
xop_single_source_sd_instruction:
or [operand_flags],2
mov [mmx_size],8
jmp xop_instruction_9
xop_single_source_ss_instruction:
or [operand_flags],2
mov [mmx_size],4
jmp xop_instruction_9
xop_single_source_instruction:
or [operand_flags],2
mov [mmx_size],0
xop_instruction_9:
mov [base_code],al
mov [xop_opcode_map],9
jmp avx_xop_common
xop_single_source_128bit_instruction:
or [operand_flags],2
mov [mmx_size],16
jmp xop_instruction_9
xop_triple_source_128bit_instruction:
mov [immediate_size],-1
mov byte [value],0
mov [mmx_size],16
jmp xop_instruction_8
xop_128bit_instruction:
mov [immediate_size],-2
mov byte [value],0
mov [mmx_size],16
xop_instruction_8:
mov [base_code],al
mov [xop_opcode_map],8
jmp avx_xop_common
xop_pcom_b_instruction:
mov ah,0CCh
jmp xop_pcom_instruction
xop_pcom_d_instruction:
mov ah,0CEh
jmp xop_pcom_instruction
xop_pcom_q_instruction:
mov ah,0CFh
jmp xop_pcom_instruction
xop_pcom_w_instruction:
mov ah,0CDh
jmp xop_pcom_instruction
xop_pcom_ub_instruction:
mov ah,0ECh
jmp xop_pcom_instruction
xop_pcom_ud_instruction:
mov ah,0EEh
jmp xop_pcom_instruction
xop_pcom_uq_instruction:
mov ah,0EFh
jmp xop_pcom_instruction
xop_pcom_uw_instruction:
mov ah,0EDh
xop_pcom_instruction:
mov byte [value],al
mov [immediate_size],-4
mov [mmx_size],16
mov [base_code],ah
mov [xop_opcode_map],8
jmp avx_xop_common
vpcmov_instruction:
or [vex_required],2
mov [immediate_size],-2
mov byte [value],0
mov [mmx_size],0
mov [base_code],al
mov [xop_opcode_map],8
jmp avx_xop_common
xop_shift_instruction:
mov [base_code],al
or [vex_required],2
mov [xop_opcode_map],9
call take_avx_register
cmp ah,16
jne invalid_operand
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
je xop_shift_reg_mem
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [vex_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
push esi
xor cl,cl
xchg cl,[operand_size]
lods byte [esi]
call get_size_operator
pop esi
xchg cl,[operand_size]
cmp al,'['
je xop_shift_reg_reg_mem
cmp al,10h
jne xop_shift_reg_reg_imm
call take_avx_register
mov bl,al
xchg bl,[vex_register]
jmp nomem_instruction_ready
xop_shift_reg_reg_mem:
or [rex_prefix],8
lods byte [esi]
call get_size_operator
call get_address
jmp instruction_ready
xop_shift_reg_reg_imm:
xor bl,bl
xchg bl,[vex_register]
cmp [base_code],94h
jae invalid_operand
add [base_code],30h
mov [xop_opcode_map],8
dec esi
jmp mmx_nomem_imm8
xop_shift_reg_mem:
call get_address
lods byte [esi]
cmp al,','
jne invalid_operand
push esi
xor cl,cl
xchg cl,[operand_size]
lods byte [esi]
call get_size_operator
pop esi
xchg cl,[operand_size]
cmp al,10h
jne xop_shift_reg_mem_imm
call take_avx_register
mov [vex_register],al
jmp instruction_ready
xop_shift_reg_mem_imm:
cmp [base_code],94h
jae invalid_operand
add [base_code],30h
mov [xop_opcode_map],8
dec esi
jmp mmx_imm8
 
set_evex_mode:
mov [evex_mode],al
jmp instruction_assembled
 
take_avx_register:
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
convert_avx_register:
mov ah,al
and al,1Fh
and ah,0E0h
sub ah,60h
jb invalid_operand
jz avx512_register_size
sub ah,60h
jb invalid_operand
jnz avx_register_size_ok
mov ah,16
jmp avx_register_size_ok
avx512_register_size:
mov ah,64
avx_register_size_ok:
cmp al,8
jb match_register_size
cmp [code_type],64
jne invalid_operand
jmp match_register_size
store_vex_instruction_code:
test [rex_prefix],10h
jnz invalid_operand
test [vex_required],0F8h
jnz store_evex_instruction_code
test [vex_register],10000b
jnz store_evex_instruction_code
cmp [operand_size],64
je store_evex_instruction_code
mov al,[base_code]
cmp al,0Fh
jne store_xop_instruction_code
test [vex_required],2
jnz prepare_vex
cmp [evex_mode],0
je prepare_vex
cmp [displacement_compression],1
jne prepare_vex
cmp edx,80h
jb prepare_vex
cmp edx,-80h
jae prepare_vex
mov al,bl
or al,bh
shr al,4
cmp al,2
je prepare_vex
call compress_displacement
cmp [displacement_compression],2
ja prepare_evex
jb prepare_vex
dec [displacement_compression]
mov edx,[uncompressed_displacement]
prepare_vex:
mov ah,[extended_code]
cmp ah,38h
je store_vex_0f38_instruction_code
cmp ah,3Ah
je store_vex_0f3a_instruction_code
test [rex_prefix],1011b
jnz store_vex_0f_instruction_code
mov [edi+2],ah
mov byte [edi],0C5h
mov al,[vex_register]
not al
shl al,3
mov ah,[rex_prefix]
shl ah,5
and ah,80h
xor al,ah
call get_vex_lpp_bits
mov [edi+1],al
call check_vex
add edi,3
ret
get_vex_lpp_bits:
cmp [operand_size],32
jne get_vex_pp_bits
or al,100b
get_vex_pp_bits:
mov ah,[opcode_prefix]
cmp ah,66h
je vex_66
cmp ah,0F3h
je vex_f3
cmp ah,0F2h
je vex_f2
test ah,ah
jnz disallowed_combination_of_registers
ret
vex_f2:
or al,11b
ret
vex_f3:
or al,10b
ret
vex_66:
or al,1
ret
store_vex_0f38_instruction_code:
mov al,11100010b
mov ah,[supplemental_code]
jmp make_c4_vex
store_vex_0f3a_instruction_code:
mov al,11100011b
mov ah,[supplemental_code]
jmp make_c4_vex
store_vex_0f_instruction_code:
mov al,11100001b
make_c4_vex:
mov [edi+3],ah
mov byte [edi],0C4h
mov ah,[rex_prefix]
shl ah,5
xor al,ah
mov [edi+1],al
call check_vex
mov al,[vex_register]
xor al,1111b
shl al,3
mov ah,[rex_prefix]
shl ah,4
and ah,80h
or al,ah
call get_vex_lpp_bits
mov [edi+2],al
add edi,4
ret
check_vex:
cmp [code_type],64
je vex_ok
not al
test al,11000000b
jnz invalid_operand
test [rex_prefix],40h
jnz invalid_operand
vex_ok:
ret
store_xop_instruction_code:
mov [edi+3],al
mov byte [edi],8Fh
mov al,[xop_opcode_map]
mov ah,[rex_prefix]
test ah,40h
jz xop_ok
cmp [code_type],64
jne invalid_operand
xop_ok:
not ah
shl ah,5
xor al,ah
mov [edi+1],al
mov al,[vex_register]
xor al,1111b
shl al,3
mov ah,[rex_prefix]
shl ah,4
and ah,80h
or al,ah
call get_vex_lpp_bits
mov [edi+2],al
add edi,4
ret
store_evex_instruction_code:
test [vex_required],2
jnz invalid_operand
cmp [base_code],0Fh
jne invalid_operand
cmp [displacement_compression],1
jne prepare_evex
call compress_displacement
prepare_evex:
mov ah,[extended_code]
cmp ah,38h
je store_evex_0f38_instruction_code
cmp ah,3Ah
je store_evex_0f3a_instruction_code
mov al,11110001b
make_evex:
mov [edi+4],ah
mov byte [edi],62h
mov ah,[rex_prefix]
shl ah,5
xor al,ah
mov ah,[vex_required]
and ah,10h
xor al,ah
mov [edi+1],al
call check_vex
mov al,[vex_register]
not al
and al,1111b
shl al,3
mov ah,[rex_prefix]
shl ah,4
or ah,[rex_prefix]
and ah,80h
or al,ah
or al,100b
call get_vex_pp_bits
mov [edi+2],al
mov al,[vex_register]
not al
shr al,1
and al,1000b
test [vex_required],80h
jne evex_rounding
mov ah,[operand_size]
cmp ah,16
jbe evex_l_ok
or al,ah
jmp evex_l_ok
evex_rounding:
mov ah,[rounding_mode]
shl ah,5
or al,ah
evex_l_ok:
test [vex_required],20h
jz evex_zaaa_ok
or al,[mask_register]
evex_zaaa_ok:
test [vex_required],40h
jz evex_b_ok
or al,10h
evex_b_ok:
mov [edi+3],al
add edi,5
ret
store_evex_0f38_instruction_code:
mov al,11110010b
mov ah,[supplemental_code]
jmp make_evex
store_evex_0f3a_instruction_code:
mov al,11110011b
mov ah,[supplemental_code]
jmp make_evex
compress_displacement:
mov ebp,ecx
mov [uncompressed_displacement],edx
or edx,edx
jz displacement_compressed
xor ecx,ecx
mov cl,[mmx_size]
test cl,cl
jnz calculate_displacement_scale
mov cl,[operand_size]
calculate_displacement_scale:
bsf ecx,ecx
jz displacement_compression_ok
xor eax,eax
shrd eax,edx,cl
jnz displacement_not_compressed
sar edx,cl
cmp edx,80h
jb displacement_compressed
cmp edx,-80h
jnb displacement_compressed
shl edx,cl
displacement_not_compressed:
inc [displacement_compression]
jmp displacement_compression_ok
displacement_compressed:
add [displacement_compression],2
displacement_compression_ok:
mov ecx,ebp
ret
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/errors.inc
0,0 → 1,194
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
out_of_memory:
push _out_of_memory
jmp fatal_error
stack_overflow:
push _stack_overflow
jmp fatal_error
main_file_not_found:
push _main_file_not_found
jmp fatal_error
write_failed:
push _write_failed
jmp fatal_error
 
unexpected_end_of_file:
push _unexpected_end_of_file
jmp general_error
code_cannot_be_generated:
push _code_cannot_be_generated
jmp general_error
format_limitations_exceeded:
push _format_limitations_exceeded
jmp general_error
invalid_definition:
push _invalid_definition
general_error:
cmp [symbols_file],0
je fatal_error
call dump_preprocessed_source
jmp fatal_error
 
file_not_found:
push _file_not_found
jmp error_with_source
error_reading_file:
push _error_reading_file
jmp error_with_source
invalid_file_format:
push _invalid_file_format
jmp error_with_source
invalid_macro_arguments:
push _invalid_macro_arguments
jmp error_with_source
incomplete_macro:
push _incomplete_macro
jmp error_with_source
unexpected_characters:
push _unexpected_characters
jmp error_with_source
invalid_argument:
push _invalid_argument
jmp error_with_source
illegal_instruction:
push _illegal_instruction
jmp error_with_source
invalid_operand:
push _invalid_operand
jmp error_with_source
invalid_operand_size:
push _invalid_operand_size
jmp error_with_source
operand_size_not_specified:
push _operand_size_not_specified
jmp error_with_source
operand_sizes_do_not_match:
push _operand_sizes_do_not_match
jmp error_with_source
invalid_address_size:
push _invalid_address_size
jmp error_with_source
address_sizes_do_not_agree:
push _address_sizes_do_not_agree
jmp error_with_source
disallowed_combination_of_registers:
push _disallowed_combination_of_registers
jmp error_with_source
long_immediate_not_encodable:
push _long_immediate_not_encodable
jmp error_with_source
relative_jump_out_of_range:
push _relative_jump_out_of_range
jmp error_with_source
invalid_expression:
push _invalid_expression
jmp error_with_source
invalid_address:
push _invalid_address
jmp error_with_source
invalid_value:
push _invalid_value
jmp error_with_source
value_out_of_range:
push _value_out_of_range
jmp error_with_source
undefined_symbol:
mov edi,message
mov esi,_undefined_symbol
call copy_asciiz
push message
cmp [error_info],0
je error_with_source
mov esi,[error_info]
mov esi,[esi+24]
or esi,esi
jz error_with_source
mov byte [edi-1],20h
call write_quoted_symbol_name
jmp error_with_source
copy_asciiz:
lods byte [esi]
stos byte [edi]
test al,al
jnz copy_asciiz
ret
write_quoted_symbol_name:
mov al,27h
stosb
movzx ecx,byte [esi-1]
rep movs byte [edi],[esi]
mov ax,27h
stosw
ret
symbol_out_of_scope:
mov edi,message
mov esi,_symbol_out_of_scope_1
call copy_asciiz
cmp [error_info],0
je finish_symbol_out_of_scope_message
mov esi,[error_info]
mov esi,[esi+24]
or esi,esi
jz finish_symbol_out_of_scope_message
mov byte [edi-1],20h
call write_quoted_symbol_name
finish_symbol_out_of_scope_message:
mov byte [edi-1],20h
mov esi,_symbol_out_of_scope_2
call copy_asciiz
push message
jmp error_with_source
invalid_use_of_symbol:
push _invalid_use_of_symbol
jmp error_with_source
name_too_long:
push _name_too_long
jmp error_with_source
invalid_name:
push _invalid_name
jmp error_with_source
reserved_word_used_as_symbol:
push _reserved_word_used_as_symbol
jmp error_with_source
symbol_already_defined:
push _symbol_already_defined
jmp error_with_source
missing_end_quote:
push _missing_end_quote
jmp error_with_source
missing_end_directive:
push _missing_end_directive
jmp error_with_source
unexpected_instruction:
push _unexpected_instruction
jmp error_with_source
extra_characters_on_line:
push _extra_characters_on_line
jmp error_with_source
section_not_aligned_enough:
push _section_not_aligned_enough
jmp error_with_source
setting_already_specified:
push _setting_already_specified
jmp error_with_source
data_already_defined:
push _data_already_defined
jmp error_with_source
too_many_repeats:
push _too_many_repeats
jmp error_with_source
assertion_failed:
push _assertion_failed
jmp error_with_source
invoked_error:
push _invoked_error
error_with_source:
cmp [symbols_file],0
je assembler_error
call dump_preprocessed_source
call restore_preprocessed_source
jmp assembler_error
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/exprcalc.inc
0,0 → 1,2219
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
calculate_expression:
mov [current_offset],edi
mov [value_undefined],0
cmp byte [esi],0
je get_string_value
cmp byte [esi],'.'
je convert_fp
calculation_loop:
mov eax,[tagged_blocks]
sub eax,0Ch
cmp eax,edi
jbe out_of_memory
lods byte [esi]
cmp al,1
je get_byte_number
cmp al,2
je get_word_number
cmp al,4
je get_dword_number
cmp al,8
je get_qword_number
cmp al,0Fh
je value_out_of_range
cmp al,10h
je get_register
cmp al,11h
je get_label
cmp al,')'
je expression_calculated
cmp al,']'
je expression_calculated
cmp al,'!'
je invalid_expression
sub edi,14h
mov ebx,edi
sub ebx,14h
cmp al,0F0h
je calculate_rva
cmp al,0F1h
je calculate_plt
cmp al,0D0h
je calculate_not
cmp al,0E0h
je calculate_bsf
cmp al,0E1h
je calculate_bsr
cmp al,083h
je calculate_neg
mov dx,[ebx+8]
or dx,[edi+8]
cmp al,80h
je calculate_add
cmp al,81h
je calculate_sub
mov ah,[ebx+12]
or ah,[edi+12]
jz absolute_values_calculation
call recoverable_misuse
absolute_values_calculation:
cmp al,90h
je calculate_mul
cmp al,91h
je calculate_div
or dx,dx
jnz invalid_expression
cmp al,0A0h
je calculate_mod
cmp al,0B0h
je calculate_and
cmp al,0B1h
je calculate_or
cmp al,0B2h
je calculate_xor
cmp al,0C0h
je calculate_shl
cmp al,0C1h
je calculate_shr
jmp invalid_expression
expression_calculated:
sub edi,14h
cmp [value_undefined],0
je expression_value_ok
xor eax,eax
mov [edi],eax
mov [edi+4],eax
mov [edi+12],eax
expression_value_ok:
ret
get_byte_number:
xor eax,eax
lods byte [esi]
stos dword [edi]
xor al,al
stos dword [edi]
got_number:
and word [edi-8+8],0
and word [edi-8+12],0
and dword [edi-8+16],0
add edi,0Ch
jmp calculation_loop
get_word_number:
xor eax,eax
lods word [esi]
stos dword [edi]
xor ax,ax
stos dword [edi]
jmp got_number
get_dword_number:
movs dword [edi],[esi]
xor eax,eax
stos dword [edi]
jmp got_number
get_qword_number:
movs dword [edi],[esi]
movs dword [edi],[esi]
jmp got_number
get_register:
mov byte [edi+9],0
and word [edi+12],0
lods byte [esi]
mov [edi+8],al
mov byte [edi+10],1
xor eax,eax
mov [edi+16],eax
stos dword [edi]
stos dword [edi]
add edi,0Ch
jmp calculation_loop
get_label:
xor eax,eax
mov [edi+8],eax
mov [edi+12],eax
mov [edi+20],eax
lods dword [esi]
cmp eax,0Fh
jb predefined_label
je reserved_word_used_as_symbol
mov ebx,eax
mov ax,[current_pass]
mov [ebx+18],ax
mov cl,[ebx+9]
shr cl,1
and cl,1
neg cl
or byte [ebx+8],8
test byte [ebx+8],1
jz label_undefined
cmp ax,[ebx+16]
je unadjusted_label
test byte [ebx+8],4
jnz label_out_of_scope
test byte [ebx+9],1
jz unadjusted_label
mov eax,[ebx]
sub eax,dword [adjustment]
stos dword [edi]
mov eax,[ebx+4]
sbb eax,dword [adjustment+4]
stos dword [edi]
sbb cl,[adjustment_sign]
mov [edi-8+13],cl
mov eax,dword [adjustment]
or al,[adjustment_sign]
or eax,dword [adjustment+4]
jz got_label
or [next_pass_needed],-1
jmp got_label
unadjusted_label:
mov eax,[ebx]
stos dword [edi]
mov eax,[ebx+4]
stos dword [edi]
mov [edi-8+13],cl
got_label:
test byte [ebx+9],4
jnz invalid_use_of_symbol
cmp [symbols_file],0
je label_reference_ok
cmp [next_pass_needed],0
jne label_reference_ok
call store_label_reference
label_reference_ok:
mov al,[ebx+11]
mov [edi-8+12],al
mov eax,[ebx+12]
mov [edi-8+8],eax
cmp al,ah
jne labeled_registers_ok
shr eax,16
add al,ah
jo labeled_registers_ok
xor ah,ah
mov [edi-8+10],ax
mov [edi-8+9],ah
labeled_registers_ok:
mov eax,[ebx+20]
mov [edi-8+16],eax
add edi,0Ch
mov al,[ebx+10]
or al,al
jz calculation_loop
test [operand_flags],1
jnz calculation_loop
check_size:
xchg [operand_size],al
or al,al
jz calculation_loop
cmp al,[operand_size]
jne operand_sizes_do_not_match
jmp calculation_loop
current_offset_label:
mov eax,[current_offset]
make_current_offset_label:
xor edx,edx
xor ch,ch
mov ebp,[addressing_space]
sub eax,[ds:ebp]
sbb edx,[ds:ebp+4]
sbb ch,[ds:ebp+8]
jp current_offset_label_ok
call recoverable_overflow
current_offset_label_ok:
stos dword [edi]
mov eax,edx
stos dword [edi]
mov eax,[ds:ebp+10h]
stos dword [edi]
mov cl,[ds:ebp+9]
mov [edi-12+12],cx
mov eax,[ds:ebp+14h]
mov [edi-12+16],eax
add edi,8
jmp calculation_loop
org_origin_label:
mov eax,[addressing_space]
mov eax,[eax+18h]
jmp make_current_offset_label
counter_label:
mov eax,[counter]
make_dword_label_value:
stos dword [edi]
xor eax,eax
stos dword [edi]
add edi,0Ch
jmp calculation_loop
timestamp_label:
call make_timestamp
make_qword_label_value:
stos dword [edi]
mov eax,edx
stos dword [edi]
add edi,0Ch
jmp calculation_loop
predefined_label:
or eax,eax
jz current_offset_label
cmp eax,1
je counter_label
cmp eax,2
je timestamp_label
cmp eax,3
je org_origin_label
mov edx,invalid_value
jmp error_undefined
label_out_of_scope:
mov edx,symbol_out_of_scope
jmp error_undefined
label_undefined:
mov edx,undefined_symbol
error_undefined:
cmp [current_pass],1
ja undefined_value
force_next_pass:
or [next_pass_needed],-1
undefined_value:
or [value_undefined],-1
and word [edi+12],0
xor eax,eax
stos dword [edi]
stos dword [edi]
add edi,0Ch
cmp [error_line],0
jne calculation_loop
mov eax,[current_line]
mov [error_line],eax
mov [error],edx
mov [error_info],ebx
jmp calculation_loop
calculate_add:
xor ah,ah
mov ah,[ebx+12]
mov al,[edi+12]
or al,al
jz add_values
or ah,ah
jz add_relocatable
add ah,al
jnz invalid_add
mov ecx,[edi+16]
cmp ecx,[ebx+16]
je add_values
invalid_add:
call recoverable_misuse
jmp add_values
add_relocatable:
mov ah,al
mov ecx,[edi+16]
mov [ebx+16],ecx
add_values:
mov [ebx+12],ah
mov eax,[edi]
add [ebx],eax
mov eax,[edi+4]
adc [ebx+4],eax
mov al,[edi+13]
adc [ebx+13],al
jp add_sign_ok
call recoverable_overflow
add_sign_ok:
or dx,dx
jz calculation_loop
push esi
mov esi,ebx
mov cl,[edi+10]
mov al,[edi+8]
call add_register
mov cl,[edi+11]
mov al,[edi+9]
call add_register
pop esi
jmp calculation_loop
add_register:
or al,al
jz add_register_done
add_register_start:
cmp [esi+8],al
jne add_in_second_slot
add [esi+10],cl
jo value_out_of_range
jnz add_register_done
mov byte [esi+8],0
ret
add_in_second_slot:
cmp [esi+9],al
jne create_in_first_slot
add [esi+11],cl
jo value_out_of_range
jnz add_register_done
mov byte [esi+9],0
ret
create_in_first_slot:
cmp byte [esi+8],0
jne create_in_second_slot
mov [esi+8],al
mov [esi+10],cl
ret
create_in_second_slot:
cmp byte [esi+9],0
jne invalid_expression
mov [esi+9],al
mov [esi+11],cl
add_register_done:
ret
out_of_range:
jmp calculation_loop
calculate_sub:
xor ah,ah
mov ah,[ebx+12]
mov al,[edi+12]
or al,al
jz sub_values
or ah,ah
jz negate_relocatable
cmp al,ah
jne invalid_sub
xor ah,ah
mov ecx,[edi+16]
cmp ecx,[ebx+16]
je sub_values
invalid_sub:
call recoverable_misuse
jmp sub_values
negate_relocatable:
neg al
mov ah,al
mov ecx,[edi+16]
mov [ebx+16],ecx
sub_values:
mov [ebx+12],ah
mov eax,[edi]
sub [ebx],eax
mov eax,[edi+4]
sbb [ebx+4],eax
mov al,[edi+13]
sbb [ebx+13],al
jp sub_sign_ok
cmp [error_line],0
jne sub_sign_ok
call recoverable_overflow
sub_sign_ok:
or dx,dx
jz calculation_loop
push esi
mov esi,ebx
mov cl,[edi+10]
mov al,[edi+8]
call sub_register
mov cl,[edi+11]
mov al,[edi+9]
call sub_register
pop esi
jmp calculation_loop
sub_register:
or al,al
jz add_register_done
neg cl
jo value_out_of_range
jmp add_register_start
calculate_mul:
or dx,dx
jz mul_start
cmp word [ebx+8],0
jne mul_start
xor ecx,ecx
swap_values:
mov eax,[ebx+ecx]
xchg eax,[edi+ecx]
mov [ebx+ecx],eax
add ecx,4
cmp ecx,16
jb swap_values
mul_start:
push esi edx
mov esi,ebx
xor bl,bl
cmp byte [esi+13],0
je mul_first_sign_ok
xor bl,-1
mov eax,[esi]
mov edx,[esi+4]
not eax
not edx
add eax,1
adc edx,0
mov [esi],eax
mov [esi+4],edx
or eax,edx
jz mul_overflow
mul_first_sign_ok:
cmp byte [edi+13],0
je mul_second_sign_ok
xor bl,-1
cmp byte [esi+8],0
je mul_first_register_sign_ok
neg byte [esi+10]
jo invalid_expression
mul_first_register_sign_ok:
cmp byte [esi+9],0
je mul_second_register_sign_ok
neg byte [esi+11]
jo invalid_expression
mul_second_register_sign_ok:
mov eax,[edi]
mov edx,[edi+4]
not eax
not edx
add eax,1
adc edx,0
mov [edi],eax
mov [edi+4],edx
or eax,edx
jz mul_overflow
mul_second_sign_ok:
cmp dword [esi+4],0
jz mul_numbers
cmp dword [edi+4],0
jz mul_numbers
jnz mul_overflow
mul_numbers:
mov eax,[esi+4]
mul dword [edi]
or edx,edx
jnz mul_overflow
mov ecx,eax
mov eax,[esi]
mul dword [edi+4]
or edx,edx
jnz mul_overflow
add ecx,eax
jc mul_overflow
mov eax,[esi]
mul dword [edi]
add edx,ecx
jc mul_overflow
mov [esi],eax
mov [esi+4],edx
or bl,bl
jz mul_ok
not eax
not edx
add eax,1
adc edx,0
mov [esi],eax
mov [esi+4],edx
or eax,edx
jnz mul_ok
not bl
mul_ok:
mov [esi+13],bl
pop edx
or dx,dx
jz mul_calculated
cmp word [edi+8],0
jne invalid_value
cmp byte [esi+8],0
je mul_first_register_ok
call get_byte_scale
imul byte [esi+10]
mov dl,ah
cbw
cmp ah,dl
jne value_out_of_range
mov [esi+10],al
or al,al
jnz mul_first_register_ok
mov [esi+8],al
mul_first_register_ok:
cmp byte [esi+9],0
je mul_calculated
call get_byte_scale
imul byte [esi+11]
mov dl,ah
cbw
cmp ah,dl
jne value_out_of_range
mov [esi+11],al
or al,al
jnz mul_calculated
mov [esi+9],al
mul_calculated:
pop esi
jmp calculation_loop
mul_overflow:
pop edx esi
call recoverable_overflow
jmp calculation_loop
get_byte_scale:
mov al,[edi]
cbw
cwde
cdq
cmp edx,[edi+4]
jne value_out_of_range
cmp eax,[edi]
jne value_out_of_range
ret
calculate_div:
push esi edx
mov esi,ebx
call div_64
pop edx
or dx,dx
jz div_calculated
cmp byte [esi+8],0
je div_first_register_ok
call get_byte_scale
or al,al
jz value_out_of_range
mov al,[esi+10]
cbw
idiv byte [edi]
or ah,ah
jnz invalid_use_of_symbol
mov [esi+10],al
div_first_register_ok:
cmp byte [esi+9],0
je div_calculated
call get_byte_scale
or al,al
jz value_out_of_range
mov al,[esi+11]
cbw
idiv byte [edi]
or ah,ah
jnz invalid_use_of_symbol
mov [esi+11],al
div_calculated:
pop esi
jmp calculation_loop
calculate_mod:
push esi
mov esi,ebx
call div_64
mov [esi],eax
mov [esi+4],edx
mov [esi+13],bh
pop esi
jmp calculation_loop
calculate_and:
mov eax,[edi]
mov edx,[edi+4]
mov cl,[edi+13]
and [ebx],eax
and [ebx+4],edx
and [ebx+13],cl
jmp calculation_loop
calculate_or:
mov eax,[edi]
mov edx,[edi+4]
mov cl,[edi+13]
or [ebx],eax
or [ebx+4],edx
or [ebx+13],cl
jmp calculation_loop
calculate_xor:
mov eax,[edi]
mov edx,[edi+4]
mov cl,[edi+13]
xor [ebx],eax
xor [ebx+4],edx
xor [ebx+13],cl
jmp calculation_loop
shr_negative:
mov byte [edi+13],0
not dword [edi]
not dword [edi+4]
add dword [edi],1
adc dword [edi+4],0
jc shl_over
calculate_shl:
cmp byte [edi+13],0
jne shl_negative
mov edx,[ebx+4]
mov eax,[ebx]
cmp dword [edi+4],0
jne shl_over
movsx ecx,byte [ebx+13]
xchg ecx,[edi]
cmp ecx,64
je shl_max
ja shl_over
cmp ecx,32
jae shl_high
shld [edi],edx,cl
shld edx,eax,cl
shl eax,cl
mov [ebx],eax
mov [ebx+4],edx
jmp shl_done
shl_over:
cmp byte [ebx+13],0
jne shl_overflow
shl_max:
movsx ecx,byte [ebx+13]
cmp eax,ecx
jne shl_overflow
cmp edx,ecx
jne shl_overflow
xor eax,eax
mov [ebx],eax
mov [ebx+4],eax
jmp calculation_loop
shl_high:
sub cl,32
shld [edi],edx,cl
shld edx,eax,cl
shl eax,cl
mov [ebx+4],eax
and dword [ebx],0
cmp edx,[edi]
jne shl_overflow
shl_done:
movsx eax,byte [ebx+13]
cmp eax,[edi]
je calculation_loop
shl_overflow:
call recoverable_overflow
jmp calculation_loop
shl_negative:
mov byte [edi+13],0
not dword [edi]
not dword [edi+4]
add dword [edi],1
adc dword [edi+4],0
jnc calculate_shr
dec dword [edi+4]
calculate_shr:
cmp byte [edi+13],0
jne shr_negative
mov edx,[ebx+4]
mov eax,[ebx]
cmp dword [edi+4],0
jne shr_over
mov ecx,[edi]
cmp ecx,64
jae shr_over
push esi
movsx esi,byte [ebx+13]
cmp ecx,32
jae shr_high
shrd eax,edx,cl
shrd edx,esi,cl
mov [ebx],eax
mov [ebx+4],edx
pop esi
jmp calculation_loop
shr_high:
sub cl,32
shrd edx,esi,cl
mov [ebx],edx
mov [ebx+4],esi
pop esi
jmp calculation_loop
shr_over:
movsx eax,byte [ebx+13]
mov dword [ebx],eax
mov dword [ebx+4],eax
jmp calculation_loop
calculate_not:
cmp word [edi+8],0
jne invalid_expression
cmp byte [edi+12],0
je not_ok
call recoverable_misuse
not_ok:
not dword [edi]
not dword [edi+4]
not byte [edi+13]
add edi,14h
jmp calculation_loop
calculate_bsf:
cmp word [edi+8],0
jne invalid_expression
cmp byte [edi+12],0
je bsf_ok
call recoverable_misuse
bsf_ok:
xor ecx,ecx
bsf eax,[edi]
jnz finish_bs
mov ecx,32
bsf eax,[edi+4]
jnz finish_bs
cmp byte [edi+13],0
jne finish_bs
bs_overflow:
call recoverable_overflow
add edi,14h
jmp calculation_loop
calculate_bsr:
cmp word [edi+8],0
jne invalid_expression
cmp byte [edi+12],0
je bsr_ok
call recoverable_misuse
bsr_ok:
cmp byte [edi+13],0
jne bs_overflow
mov ecx,32
bsr eax,[edi+4]
jnz finish_bs
xor ecx,ecx
bsr eax,[edi]
jz bs_overflow
finish_bs:
add eax,ecx
xor edx,edx
mov [edi],eax
mov [edi+4],edx
mov [edi+13],dl
add edi,14h
jmp calculation_loop
calculate_neg:
cmp byte [edi+8],0
je neg_first_register_ok
neg byte [edi+10]
jo invalid_expression
neg_first_register_ok:
cmp byte [edi+9],0
je neg_second_register_ok
neg byte [edi+11]
jo invalid_expression
neg_second_register_ok:
neg byte [edi+12]
xor eax,eax
xor edx,edx
xor cl,cl
xchg eax,[edi]
xchg edx,[edi+4]
xchg cl,[edi+13]
sub [edi],eax
sbb [edi+4],edx
sbb [edi+13],cl
jp neg_sign_ok
call recoverable_overflow
neg_sign_ok:
add edi,14h
jmp calculation_loop
calculate_rva:
cmp word [edi+8],0
jne invalid_expression
mov al,[output_format]
cmp al,5
je calculate_gotoff
cmp al,4
je calculate_coff_rva
cmp al,3
jne invalid_expression
test [format_flags],8
jnz pe64_rva
mov al,2
bt [resolver_flags],0
jc rva_type_ok
xor al,al
rva_type_ok:
cmp byte [edi+12],al
je rva_ok
call recoverable_misuse
rva_ok:
mov byte [edi+12],0
mov eax,[code_start]
mov eax,[eax+34h]
xor edx,edx
finish_rva:
sub [edi],eax
sbb [edi+4],edx
sbb byte [edi+13],0
jp rva_finished
call recoverable_overflow
rva_finished:
add edi,14h
jmp calculation_loop
pe64_rva:
mov al,4
bt [resolver_flags],0
jc pe64_rva_type_ok
xor al,al
pe64_rva_type_ok:
cmp byte [edi+12],al
je pe64_rva_ok
call recoverable_misuse
pe64_rva_ok:
mov byte [edi+12],0
mov eax,[code_start]
mov edx,[eax+34h]
mov eax,[eax+30h]
jmp finish_rva
calculate_gotoff:
test [format_flags],8+1
jnz invalid_expression
calculate_coff_rva:
mov dl,5
cmp byte [edi+12],2
je change_value_type
incorrect_change_of_value_type:
call recoverable_misuse
change_value_type:
mov byte [edi+12],dl
add edi,14h
jmp calculation_loop
calculate_plt:
cmp word [edi+8],0
jne invalid_expression
cmp [output_format],5
jne invalid_expression
test [format_flags],1
jnz invalid_expression
mov dl,6
mov dh,2
test [format_flags],8
jz check_value_for_plt
mov dh,4
check_value_for_plt:
mov eax,[edi]
or eax,[edi+4]
jnz incorrect_change_of_value_type
cmp byte [edi+12],dh
jne incorrect_change_of_value_type
mov eax,[edi+16]
cmp byte [eax],80h
jne incorrect_change_of_value_type
jmp change_value_type
div_64:
xor ebx,ebx
cmp dword [edi],0
jne divider_ok
cmp dword [edi+4],0
jne divider_ok
cmp [next_pass_needed],0
je value_out_of_range
jmp div_done
divider_ok:
cmp byte [esi+13],0
je div_first_sign_ok
mov eax,[esi]
mov edx,[esi+4]
not eax
not edx
add eax,1
adc edx,0
mov [esi],eax
mov [esi+4],edx
or eax,edx
jz value_out_of_range
xor bx,-1
div_first_sign_ok:
cmp byte [edi+13],0
je div_second_sign_ok
mov eax,[edi]
mov edx,[edi+4]
not eax
not edx
add eax,1
adc edx,0
mov [edi],eax
mov [edi+4],edx
or eax,edx
jz value_out_of_range
xor bl,-1
div_second_sign_ok:
cmp dword [edi+4],0
jne div_high
mov ecx,[edi]
mov eax,[esi+4]
xor edx,edx
div ecx
mov [esi+4],eax
mov eax,[esi]
div ecx
mov [esi],eax
mov eax,edx
xor edx,edx
jmp div_done
div_high:
push ebx
mov eax,[esi+4]
xor edx,edx
div dword [edi+4]
mov ebx,[esi]
mov [esi],eax
and dword [esi+4],0
mov ecx,edx
mul dword [edi]
div_high_loop:
cmp ecx,edx
ja div_high_done
jb div_high_large_correction
cmp ebx,eax
jae div_high_done
div_high_correction:
dec dword [esi]
sub eax,[edi]
sbb edx,[edi+4]
jnc div_high_loop
div_high_done:
sub ebx,eax
sbb ecx,edx
mov edx,ecx
mov eax,ebx
pop ebx
jmp div_done
div_high_large_correction:
push eax edx
mov eax,edx
sub eax,ecx
xor edx,edx
div dword [edi+4]
shr eax,1
jz div_high_small_correction
sub [esi],eax
push eax
mul dword [edi+4]
sub dword [esp+4],eax
pop eax
mul dword [edi]
sub dword [esp+4],eax
sbb dword [esp],edx
pop edx eax
jmp div_high_loop
div_high_small_correction:
pop edx eax
jmp div_high_correction
div_done:
or bh,bh
jz remainder_ok
not eax
not edx
add eax,1
adc edx,0
mov ecx,eax
or ecx,edx
jnz remainder_ok
not bh
remainder_ok:
or bl,bl
jz div_ok
not dword [esi]
not dword [esi+4]
add dword [esi],1
adc dword [esi+4],0
mov ecx,[esi]
or ecx,[esi+4]
jnz div_ok
not bl
div_ok:
mov [esi+13],bl
ret
store_label_reference:
mov eax,[tagged_blocks]
mov dword [eax-4],2
mov dword [eax-8],4
sub eax,8+4
cmp eax,edi
jbe out_of_memory
mov [tagged_blocks],eax
mov [eax],ebx
ret
convert_fp:
inc esi
and word [edi+8],0
and word [edi+12],0
mov al,[value_size]
cmp al,2
je convert_fp_word
cmp al,4
je convert_fp_dword
test al,not 8
jz convert_fp_qword
call recoverable_misuse
convert_fp_qword:
xor eax,eax
xor edx,edx
cmp word [esi+8],8000h
je fp_qword_store
mov bx,[esi+8]
mov eax,[esi]
mov edx,[esi+4]
add eax,eax
adc edx,edx
mov ecx,edx
shr edx,12
shrd eax,ecx,12
jnc fp_qword_ok
add eax,1
adc edx,0
bt edx,20
jnc fp_qword_ok
and edx,1 shl 20 - 1
inc bx
shr edx,1
rcr eax,1
fp_qword_ok:
add bx,3FFh
cmp bx,7FFh
jge value_out_of_range
cmp bx,0
jg fp_qword_exp_ok
or edx,1 shl 20
mov cx,bx
neg cx
inc cx
cmp cx,52
ja value_out_of_range
cmp cx,32
jb fp_qword_small_shift
sub cx,32
mov eax,edx
xor edx,edx
shr eax,cl
jmp fp_qword_shift_done
fp_qword_small_shift:
mov ebx,edx
shr edx,cl
shrd eax,ebx,cl
fp_qword_shift_done:
mov bx,0
jnc fp_qword_exp_ok
add eax,1
adc edx,0
test edx,1 shl 20
jz fp_qword_exp_ok
and edx,1 shl 20 - 1
inc bx
fp_qword_exp_ok:
shl ebx,20
or edx,ebx
fp_qword_store:
mov bl,[esi+11]
shl ebx,31
or edx,ebx
mov [edi],eax
mov [edi+4],edx
add esi,13
ret
convert_fp_word:
xor eax,eax
cmp word [esi+8],8000h
je fp_word_store
mov bx,[esi+8]
mov ax,[esi+6]
shl ax,1
shr ax,6
jnc fp_word_ok
inc ax
bt ax,10
jnc fp_word_ok
and ax,1 shl 10 - 1
inc bx
shr ax,1
fp_word_ok:
add bx,0Fh
cmp bx,01Fh
jge value_out_of_range
cmp bx,0
jg fp_word_exp_ok
or ax,1 shl 10
mov cx,bx
neg cx
inc cx
cmp cx,10
ja value_out_of_range
xor bx,bx
shr ax,cl
jnc fp_word_exp_ok
inc ax
test ax,1 shl 10
jz fp_word_exp_ok
and ax,1 shl 10 - 1
inc bx
fp_word_exp_ok:
shl bx,10
or ax,bx
fp_word_store:
mov bl,[esi+11]
shl bx,15
or ax,bx
mov [edi],eax
xor eax,eax
mov [edi+4],eax
add esi,13
ret
convert_fp_dword:
xor eax,eax
cmp word [esi+8],8000h
je fp_dword_store
mov bx,[esi+8]
mov eax,[esi+4]
shl eax,1
shr eax,9
jnc fp_dword_ok
inc eax
bt eax,23
jnc fp_dword_ok
and eax,1 shl 23 - 1
inc bx
shr eax,1
fp_dword_ok:
add bx,7Fh
cmp bx,0FFh
jge value_out_of_range
cmp bx,0
jg fp_dword_exp_ok
or eax,1 shl 23
mov cx,bx
neg cx
inc cx
cmp cx,23
ja value_out_of_range
xor bx,bx
shr eax,cl
jnc fp_dword_exp_ok
inc eax
test eax,1 shl 23
jz fp_dword_exp_ok
and eax,1 shl 23 - 1
inc bx
fp_dword_exp_ok:
shl ebx,23
or eax,ebx
fp_dword_store:
mov bl,[esi+11]
shl ebx,31
or eax,ebx
mov [edi],eax
xor eax,eax
mov [edi+4],eax
add esi,13
ret
get_string_value:
inc esi
lods dword [esi]
mov ecx,eax
cmp ecx,8
ja value_out_of_range
mov edx,edi
xor eax,eax
stos dword [edi]
stos dword [edi]
mov edi,edx
rep movs byte [edi],[esi]
mov edi,edx
inc esi
and word [edi+8],0
and word [edi+12],0
ret
 
get_byte_value:
mov [value_size],1
or [operand_flags],1
call calculate_value
or al,al
jz check_byte_value
call recoverable_misuse
check_byte_value:
mov eax,[edi]
mov edx,[edi+4]
cmp byte [edi+13],0
je byte_positive
cmp edx,-1
jne range_exceeded
cmp eax,-100h
jb range_exceeded
ret
byte_positive:
test edx,edx
jnz range_exceeded
cmp eax,100h
jae range_exceeded
return_byte_value:
ret
range_exceeded:
xor eax,eax
xor edx,edx
recoverable_overflow:
cmp [error_line],0
jne ignore_overflow
push [current_line]
pop [error_line]
mov [error],value_out_of_range
or [value_undefined],-1
ignore_overflow:
ret
recoverable_misuse:
cmp [error_line],0
jne ignore_misuse
push [current_line]
pop [error_line]
mov [error],invalid_use_of_symbol
ignore_misuse:
ret
get_word_value:
mov [value_size],2
or [operand_flags],1
call calculate_value
cmp al,2
jb check_word_value
call recoverable_misuse
check_word_value:
mov eax,[edi]
mov edx,[edi+4]
cmp byte [edi+13],0
je word_positive
cmp edx,-1
jne range_exceeded
cmp eax,-10000h
jb range_exceeded
ret
word_positive:
test edx,edx
jnz range_exceeded
cmp eax,10000h
jae range_exceeded
ret
get_dword_value:
mov [value_size],4
or [operand_flags],1
call calculate_value
cmp al,4
jne check_dword_value
mov [value_type],2
mov eax,[edi]
cdq
cmp edx,[edi+4]
jne range_exceeded
mov ecx,edx
shr ecx,31
cmp cl,[value_sign]
jne range_exceeded
ret
check_dword_value:
mov eax,[edi]
mov edx,[edi+4]
cmp byte [edi+13],0
je dword_positive
cmp edx,-1
jne range_exceeded
ret
dword_positive:
test edx,edx
jne range_exceeded
ret
get_pword_value:
mov [value_size],6
or [operand_flags],1
call calculate_value
cmp al,4
jne check_pword_value
call recoverable_misuse
check_pword_value:
mov eax,[edi]
mov edx,[edi+4]
cmp byte [edi+13],0
je pword_positive
cmp edx,-10000h
jb range_exceeded
ret
pword_positive:
cmp edx,10000h
jae range_exceeded
ret
get_qword_value:
mov [value_size],8
or [operand_flags],1
call calculate_value
check_qword_value:
mov eax,[edi]
mov edx,[edi+4]
ret
get_count_value:
mov [value_size],8
or [operand_flags],1
call calculate_expression
cmp word [edi+8],0
jne invalid_value
mov [value_sign],0
mov al,[edi+12]
or al,al
jz check_count_value
call recoverable_misuse
check_count_value:
cmp byte [edi+13],0
jne invalid_count_value
mov eax,[edi]
mov edx,[edi+4]
or edx,edx
jnz invalid_count_value
ret
invalid_count_value:
cmp [error_line],0
jne zero_count
mov eax,[current_line]
mov [error_line],eax
mov [error],invalid_value
zero_count:
xor eax,eax
ret
get_value:
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,'('
jne invalid_value
mov al,[operand_size]
cmp al,1
je value_byte
cmp al,2
je value_word
cmp al,4
je value_dword
cmp al,6
je value_pword
cmp al,8
je value_qword
or al,al
jnz invalid_value
mov [value_size],al
call calculate_value
mov eax,[edi]
mov edx,[edi+4]
ret
calculate_value:
call calculate_expression
cmp word [edi+8],0
jne invalid_value
mov eax,[edi+16]
mov [symbol_identifier],eax
mov al,[edi+13]
mov [value_sign],al
mov al,[edi+12]
mov [value_type],al
ret
value_qword:
call get_qword_value
truncated_value:
mov [value_sign],0
ret
value_pword:
call get_pword_value
movzx edx,dx
jmp truncated_value
value_dword:
call get_dword_value
xor edx,edx
jmp truncated_value
value_word:
call get_word_value
xor edx,edx
movzx eax,ax
jmp truncated_value
value_byte:
call get_byte_value
xor edx,edx
movzx eax,al
jmp truncated_value
get_address_word_value:
mov [address_size],2
mov [value_size],2
mov [free_address_range],0
jmp calculate_address
get_address_dword_value:
mov [address_size],4
mov [value_size],4
mov [free_address_range],0
jmp calculate_address
get_address_qword_value:
mov [address_size],8
mov [value_size],8
mov [free_address_range],0
jmp calculate_address
get_address_value:
mov [address_size],0
mov [value_size],8
or [free_address_range],-1
calculate_address:
cmp byte [esi],'.'
je invalid_address
call calculate_expression
mov eax,[edi+16]
mov [address_symbol],eax
mov al,[edi+13]
mov [address_sign],al
mov al,[edi+12]
mov [value_type],al
cmp al,0
je address_size_ok
jg get_address_symbol_size
neg al
get_address_symbol_size:
cmp al,6
je special_address_type_32bit
cmp al,5
je special_address_type_32bit
ja invalid_address_type
test al,1
jnz invalid_address_type
shl al,5
jmp address_symbol_ok
invalid_address_type:
call recoverable_misuse
special_address_type_32bit:
mov al,40h
address_symbol_ok:
mov ah,[address_size]
or [address_size],al
shr al,4
or ah,ah
jz address_size_ok
cmp al,ah
je address_size_ok
cmp ax,0408h
je address_sizes_mixed
cmp ax,0804h
jne address_sizes_do_not_agree
address_sizes_mixed:
mov [value_type],2
mov eax,[edi]
cdq
cmp edx,[edi+4]
je address_size_ok
cmp [error_line],0
jne address_size_ok
call recoverable_overflow
address_size_ok:
xor ebx,ebx
xor ecx,ecx
mov cl,[value_type]
shl ecx,16
mov ch,[address_size]
cmp word [edi+8],0
je check_immediate_address
mov al,[edi+8]
mov dl,[edi+10]
call get_address_register
mov al,[edi+9]
mov dl,[edi+11]
call get_address_register
mov ax,bx
shr ah,4
shr al,4
or bh,bh
jz check_address_registers
or bl,bl
jz check_address_registers
cmp al,ah
jne check_vsib
check_address_registers:
or al,ah
cmp al,0Ch
jae check_vsib
cmp al,6
je check_vsib
cmp al,7
je check_vsib
mov ah,[address_size]
and ah,0Fh
jz address_registers_sizes_ok
cmp al,ah
jne invalid_address
address_registers_sizes_ok:
cmp al,4
je sib_allowed
cmp al,8
je sib_allowed
cmp al,9
je check_ip_relative_address
cmp cl,1
ja invalid_address
cmp [free_address_range],0
jne check_qword_value
jmp check_word_value
address_sizes_do_not_match:
cmp al,0Fh
jne invalid_address
mov al,bh
and al,0Fh
cmp al,ah
jne invalid_address
check_ip_relative_address:
or bl,bl
jnz invalid_address
cmp bh,98h
je check_rip_relative_address
cmp bh,94h
jne invalid_address
cmp [free_address_range],0
je check_dword_value
mov eax,[edi]
mov edx,[edi+4]
ret
check_rip_relative_address:
mov eax,[edi]
cdq
cmp edx,[edi+4]
jne range_exceeded
cmp dl,[edi+13]
jne range_exceeded
ret
get_address_register:
or al,al
jz address_register_ok
cmp dl,1
jne scaled_register
or bh,bh
jnz scaled_register
mov bh,al
address_register_ok:
ret
scaled_register:
or bl,bl
jnz invalid_address
mov bl,al
mov cl,dl
jmp address_register_ok
sib_allowed:
or bh,bh
jnz check_index_with_base
cmp cl,3
je special_index_scale
cmp cl,5
je special_index_scale
cmp cl,9
je special_index_scale
cmp cl,2
jne check_index_scale
cmp bl,45h
jne special_index_scale
cmp [code_type],64
je special_index_scale
cmp [segment_register],4
jne special_index_scale
cmp [value_type],0
jne check_index_scale
mov al,[edi]
cbw
cwde
cmp eax,[edi]
jne check_index_scale
cdq
cmp edx,[edi+4]
jne check_immediate_address
special_index_scale:
mov bh,bl
dec cl
check_immediate_address:
cmp [free_address_range],0
jne check_qword_value
mov al,[address_size]
and al,0Fh
cmp al,2
je check_word_value
cmp al,4
je check_dword_value
cmp al,8
je check_qword_value
or al,al
jnz invalid_value
cmp [code_type],64
jne check_dword_value
jmp check_qword_value
check_index_with_base:
cmp cl,1
jne check_index_scale
cmp bl,44h
je swap_base_with_index
cmp bl,84h
je swap_base_with_index
cmp [code_type],64
je check_for_rbp_base
cmp bl,45h
jne check_for_ebp_base
cmp [segment_register],3
je swap_base_with_index
jmp check_immediate_address
check_for_ebp_base:
cmp bh,45h
jne check_immediate_address
cmp [segment_register],4
jne check_immediate_address
swap_base_with_index:
xchg bl,bh
jmp check_immediate_address
check_for_rbp_base:
cmp bh,45h
je swap_base_with_index
cmp bh,85h
je swap_base_with_index
jmp check_immediate_address
check_index_scale:
test cl,not 1111b
jnz invalid_address
mov al,cl
dec al
and al,cl
jz check_immediate_address
jmp invalid_address
check_vsib:
xor ah,ah
check_vsib_base:
test bh,bh
jz check_vsib_index
mov al,bh
shr al,4
cmp al,4
je check_vsib_base_size
cmp [code_type],64
jne swap_vsib_registers
cmp al,8
jne swap_vsib_registers
check_vsib_base_size:
mov ah,[address_size]
and ah,0Fh
jz check_vsib_index
cmp al,ah
jne invalid_address
check_vsib_index:
mov al,bl
and al,0E0h
cmp al,0C0h
jae check_index_scale
cmp al,60h
je check_index_scale
jmp invalid_address
swap_vsib_registers:
xor ah,-1
jz invalid_address
cmp cl,1
ja invalid_address
xchg bl,bh
mov cl,1
jmp check_vsib_base
 
calculate_relative_offset:
cmp [value_undefined],0
jne relative_offset_ok
test bh,bh
setne ch
cmp bx,[ds:ebp+10h]
je origin_registers_ok
xchg bh,bl
xchg ch,cl
cmp bx,[ds:ebp+10h]
jne invalid_value
origin_registers_ok:
cmp cx,[ds:ebp+10h+2]
jne invalid_value
mov bl,[address_sign]
add eax,[ds:ebp]
adc edx,[ds:ebp+4]
adc bl,[ds:ebp+8]
sub eax,edi
sbb edx,0
sbb bl,0
mov [value_sign],bl
mov bl,[value_type]
mov ecx,[address_symbol]
mov [symbol_identifier],ecx
test bl,1
jnz relative_offset_unallowed
cmp bl,6
je plt_relative_offset
mov bh,[ds:ebp+9]
cmp bl,bh
je set_relative_offset_type
cmp bx,0402h
je set_relative_offset_type
relative_offset_unallowed:
call recoverable_misuse
set_relative_offset_type:
cmp [value_type],0
je relative_offset_ok
mov [value_type],0
cmp ecx,[ds:ebp+14h]
je relative_offset_ok
mov [value_type],3
relative_offset_ok:
ret
plt_relative_offset:
mov [value_type],7
cmp byte [ds:ebp+9],2
je relative_offset_ok
cmp byte [ds:ebp+9],4
jne recoverable_misuse
ret
 
calculate_logical_expression:
xor al,al
calculate_embedded_logical_expression:
mov [logical_value_wrapping],al
call get_logical_value
logical_loop:
cmp byte [esi],'|'
je logical_or
cmp byte [esi],'&'
je logical_and
ret
logical_or:
inc esi
or al,al
jnz logical_value_already_determined
push eax
call get_logical_value
pop ebx
or al,bl
jmp logical_loop
logical_and:
inc esi
or al,al
jz logical_value_already_determined
push eax
call get_logical_value
pop ebx
and al,bl
jmp logical_loop
logical_value_already_determined:
push eax
call skip_logical_value
jc invalid_expression
pop eax
jmp logical_loop
get_value_for_comparison:
mov [value_size],8
or [operand_flags],1
lods byte [esi]
call calculate_expression
cmp byte [edi+8],0
jne first_register_size_ok
mov byte [edi+10],0
first_register_size_ok:
cmp byte [edi+9],0
jne second_register_size_ok
mov byte [edi+11],0
second_register_size_ok:
mov eax,[edi+16]
mov [symbol_identifier],eax
mov al,[edi+13]
mov [value_sign],al
mov bl,[edi+12]
mov eax,[edi]
mov edx,[edi+4]
mov ecx,[edi+8]
ret
get_logical_value:
xor al,al
check_for_negation:
cmp byte [esi],'~'
jne negation_ok
inc esi
xor al,-1
jmp check_for_negation
negation_ok:
push eax
mov al,[esi]
cmp al,91h
je logical_expression
cmp al,0FFh
je invalid_expression
cmp al,88h
je check_for_defined
cmp al,89h
je check_for_used
cmp al,'0'
je given_false
cmp al,'1'
je given_true
cmp al,'('
jne invalid_value
call get_value_for_comparison
mov bh,[value_sign]
push eax edx [symbol_identifier] ebx ecx
mov al,[esi]
or al,al
jz logical_number
cmp al,0Fh
je logical_number
cmp al,92h
je logical_number
cmp al,'&'
je logical_number
cmp al,'|'
je logical_number
inc esi
mov [compare_type],al
cmp byte [esi],'('
jne invalid_value
call get_value_for_comparison
cmp bl,[esp+4]
jne values_not_relative
or bl,bl
jz check_values_registers
mov ebx,[symbol_identifier]
cmp ebx,[esp+8]
jne values_not_relative
check_values_registers:
cmp ecx,[esp]
je values_relative
ror ecx,16
xchg ch,cl
ror ecx,16
xchg ch,cl
cmp ecx,[esp]
je values_relative
values_not_relative:
cmp [compare_type],0F8h
jne invalid_comparison
add esp,12+8
jmp return_false
invalid_comparison:
call recoverable_misuse
values_relative:
pop ebx
shl ebx,16
mov bx,[esp]
add esp,8
pop ecx ebp
cmp [compare_type],'='
je check_equal
cmp [compare_type],0F1h
je check_not_equal
cmp [compare_type],0F8h
je return_true
test ebx,0FFFF0000h
jz check_less_or_greater
call recoverable_misuse
check_less_or_greater:
cmp [compare_type],'>'
je check_greater
cmp [compare_type],'<'
je check_less
cmp [compare_type],0F2h
je check_not_less
cmp [compare_type],0F3h
je check_not_greater
jmp invalid_expression
check_equal:
cmp bh,[value_sign]
jne return_false
cmp eax,ebp
jne return_false
cmp edx,ecx
jne return_false
jmp return_true
check_greater:
cmp bh,[value_sign]
jg return_true
jl return_false
cmp edx,ecx
jb return_true
ja return_false
cmp eax,ebp
jb return_true
jae return_false
check_less:
cmp bh,[value_sign]
jg return_false
jl return_true
cmp edx,ecx
jb return_false
ja return_true
cmp eax,ebp
jbe return_false
ja return_true
check_not_less:
cmp bh,[value_sign]
jg return_true
jl return_false
cmp edx,ecx
jb return_true
ja return_false
cmp eax,ebp
jbe return_true
ja return_false
check_not_greater:
cmp bh,[value_sign]
jg return_false
jl return_true
cmp edx,ecx
jb return_false
ja return_true
cmp eax,ebp
jb return_false
jae return_true
check_not_equal:
cmp bh,[value_sign]
jne return_true
cmp eax,ebp
jne return_true
cmp edx,ecx
jne return_true
jmp return_false
logical_number:
pop ecx ebx eax edx eax
or bl,bl
jnz invalid_logical_number
or cx,cx
jz logical_number_ok
invalid_logical_number:
call recoverable_misuse
logical_number_ok:
test bh,bh
jnz return_true
or eax,edx
jnz return_true
jmp return_false
check_for_defined:
or bl,-1
lods word [esi]
cmp ah,'('
jne invalid_expression
check_expression:
lods byte [esi]
or al,al
jz defined_string
cmp al,'.'
je defined_fp_value
cmp al,')'
je expression_checked
cmp al,'!'
je invalid_expression
cmp al,0Fh
je check_expression
cmp al,10h
je defined_register
cmp al,11h
je check_if_symbol_defined
cmp al,80h
jae check_expression
movzx eax,al
add esi,eax
jmp check_expression
defined_register:
inc esi
jmp check_expression
defined_fp_value:
add esi,12+1
jmp expression_checked
defined_string:
lods dword [esi]
add esi,eax
inc esi
jmp expression_checked
check_if_symbol_defined:
lods dword [esi]
cmp eax,-1
je invalid_expression
cmp eax,0Fh
jb check_expression
je reserved_word_used_as_symbol
test byte [eax+8],4
jnz no_prediction
test byte [eax+8],1
jz symbol_predicted_undefined
mov cx,[current_pass]
sub cx,[eax+16]
jz check_expression
cmp cx,1
ja symbol_predicted_undefined
or byte [eax+8],40h+80h
jmp check_expression
no_prediction:
test byte [eax+8],1
jz symbol_undefined
mov cx,[current_pass]
sub cx,[eax+16]
jz check_expression
jmp symbol_undefined
symbol_predicted_undefined:
or byte [eax+8],40h
and byte [eax+8],not 80h
symbol_undefined:
xor bl,bl
jmp check_expression
expression_checked:
mov al,bl
jmp logical_value_ok
check_for_used:
lods word [esi]
cmp ah,2
jne invalid_expression
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
inc esi
test byte [eax+8],8
jz not_used
mov cx,[current_pass]
sub cx,[eax+18]
jz return_true
cmp cx,1
ja not_used
or byte [eax+8],10h+20h
jmp return_true
not_used:
or byte [eax+8],10h
and byte [eax+8],not 20h
jmp return_false
given_false:
inc esi
return_false:
xor al,al
jmp logical_value_ok
given_true:
inc esi
return_true:
or al,-1
jmp logical_value_ok
logical_expression:
lods byte [esi]
mov dl,[logical_value_wrapping]
push edx
call calculate_embedded_logical_expression
pop edx
mov [logical_value_wrapping],dl
push eax
lods byte [esi]
cmp al,92h
jne invalid_expression
pop eax
logical_value_ok:
pop ebx
xor al,bl
ret
 
skip_symbol:
lods byte [esi]
or al,al
jz nothing_to_skip
cmp al,0Fh
je nothing_to_skip
cmp al,1
je skip_instruction
cmp al,2
je skip_label
cmp al,3
je skip_label
cmp al,4
je skip_special_label
cmp al,20h
jb skip_assembler_symbol
cmp al,'('
je skip_expression
cmp al,'['
je skip_address
skip_done:
clc
ret
skip_label:
add esi,2
skip_instruction:
add esi,2
skip_assembler_symbol:
inc esi
jmp skip_done
skip_special_label:
add esi,4
jmp skip_done
skip_address:
mov al,[esi]
and al,11110000b
cmp al,60h
jb skip_expression
cmp al,70h
ja skip_expression
inc esi
jmp skip_address
skip_expression:
lods byte [esi]
or al,al
jz skip_string
cmp al,'.'
je skip_fp_value
cmp al,')'
je skip_done
cmp al,']'
je skip_done
cmp al,'!'
je skip_expression
cmp al,0Fh
je skip_expression
cmp al,10h
je skip_register
cmp al,11h
je skip_label_value
cmp al,80h
jae skip_expression
movzx eax,al
add esi,eax
jmp skip_expression
skip_label_value:
add esi,3
skip_register:
inc esi
jmp skip_expression
skip_fp_value:
add esi,12
jmp skip_done
skip_string:
lods dword [esi]
add esi,eax
inc esi
jmp skip_done
nothing_to_skip:
dec esi
stc
ret
 
expand_path:
lods byte [esi]
cmp al,'%'
je environment_variable
stos byte [edi]
or al,al
jnz expand_path
cmp edi,[memory_end]
ja out_of_memory
ret
environment_variable:
mov ebx,esi
find_variable_end:
lods byte [esi]
or al,al
jz not_environment_variable
cmp al,'%'
jne find_variable_end
mov byte [esi-1],0
push esi
mov esi,ebx
call get_environment_variable
pop esi
mov byte [esi-1],'%'
jmp expand_path
not_environment_variable:
mov al,'%'
stos byte [edi]
mov esi,ebx
jmp expand_path
get_include_directory:
lods byte [esi]
cmp al,';'
je include_directory_ok
stos byte [edi]
or al,al
jnz get_include_directory
dec esi
dec edi
include_directory_ok:
cmp byte [edi-1],'/'
je path_separator_ok
cmp byte [edi-1],'\'
je path_separator_ok
mov al,'/'
stos byte [edi]
path_separator_ok:
ret
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/exprpars.inc
0,0 → 1,1267
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
convert_expression:
push ebp
call get_fp_value
jnc fp_expression
mov [current_offset],esp
expression_loop:
push edi
mov edi,single_operand_operators
call get_operator
pop edi
or al,al
jz expression_element
cmp al,82h
je expression_loop
push eax
jmp expression_loop
expression_element:
mov al,[esi]
cmp al,1Ah
je expression_number
cmp al,22h
je expression_number
cmp al,'('
je expression_number
mov al,'!'
stos byte [edi]
jmp expression_operator
expression_number:
call convert_number
expression_operator:
push edi
mov edi,operators
call get_operator
pop edi
or al,al
jz expression_end
operators_loop:
cmp esp,[current_offset]
je push_operator
mov bl,al
and bl,0F0h
mov bh,byte [esp]
and bh,0F0h
cmp bl,bh
ja push_operator
pop ebx
mov byte [edi],bl
inc edi
jmp operators_loop
push_operator:
push eax
jmp expression_loop
expression_end:
cmp esp,[current_offset]
je expression_converted
pop eax
stos byte [edi]
jmp expression_end
expression_converted:
pop ebp
ret
fp_expression:
mov al,'.'
stos byte [edi]
mov eax,[fp_value]
stos dword [edi]
mov eax,[fp_value+4]
stos dword [edi]
mov eax,[fp_value+8]
stos dword [edi]
pop ebp
ret
 
convert_number:
lea eax,[edi+20h]
mov edx,[memory_end]
cmp [source_start],0
je check_memory_for_number
mov edx,[labels_list]
check_memory_for_number:
cmp eax,edx
jae out_of_memory
mov eax,esp
sub eax,100h
jc stack_overflow
cmp eax,[stack_limit]
jb stack_overflow
cmp byte [esi],'('
je expression_value
inc edi
call get_number
jc symbol_value
or ebp,ebp
jz valid_number
mov byte [edi-1],0Fh
ret
valid_number:
cmp dword [edi+4],0
jne qword_number
cmp word [edi+2],0
jne dword_number
cmp byte [edi+1],0
jne word_number
byte_number:
mov byte [edi-1],1
inc edi
ret
qword_number:
mov byte [edi-1],8
add edi,8
ret
dword_number:
mov byte [edi-1],4
scas dword [edi]
ret
word_number:
mov byte [edi-1],2
scas word [edi]
ret
expression_value:
inc esi
push [current_offset]
call convert_expression
pop [current_offset]
lods byte [esi]
cmp al,')'
je subexpression_closed
dec esi
mov al,'!'
stosb
subexpression_closed:
ret
symbol_value:
cmp [source_start],0
je preprocessor_value
push edi esi
lods word [esi]
cmp al,1Ah
jne no_address_register
movzx ecx,ah
call get_symbol
jc no_address_register
cmp al,10h
jne no_address_register
mov al,ah
shr ah,4
cmp ah,4
je register_value
and ah,not 1
cmp ah,8
je register_value
cmp ah,0Ch
jae register_value
cmp ah,6
je register_value
cmp al,23h
je register_value
cmp al,25h
je register_value
cmp al,26h
je register_value
cmp al,27h
je register_value
no_address_register:
pop esi
mov edi,directive_operators
call get_operator
pop edi
or al,al
jnz broken_value
lods byte [esi]
cmp al,1Ah
jne invalid_value
lods byte [esi]
movzx ecx,al
call get_label_id
store_label_value:
mov byte [edi-1],11h
stos dword [edi]
ret
broken_value:
mov eax,0Fh
jmp store_label_value
register_value:
pop edx edi
mov byte [edi-1],10h
stos byte [edi]
ret
preprocessor_value:
dec edi
cmp [hash_tree],0
je invalid_value
lods byte [esi]
cmp al,1Ah
jne invalid_value
lods byte [esi]
mov cl,al
mov ch,10b
call get_preprocessor_symbol
jc invalid_value
push esi
mov esi,[edx+8]
push [current_offset]
call convert_expression
pop [current_offset]
pop esi
ret
 
get_number:
xor ebp,ebp
lods byte [esi]
cmp al,22h
je get_text_number
cmp al,1Ah
jne not_number
lods byte [esi]
movzx ecx,al
mov [number_start],esi
mov al,[esi]
cmp al,'$'
je number_begin
sub al,30h
cmp al,9
ja invalid_number
number_begin:
mov ebx,esi
add esi,ecx
push esi
dec esi
mov dword [edi],0
mov dword [edi+4],0
cmp byte [ebx],'$'
je pascal_hex_number
cmp word [ebx],'0x'
je get_hex_number
mov al,[esi]
dec esi
cmp al,'h'
je get_hex_number
cmp al,'b'
je get_bin_number
cmp al,'d'
je get_dec_number
cmp al,'o'
je get_oct_number
cmp al,'H'
je get_hex_number
cmp al,'B'
je get_bin_number
cmp al,'D'
je get_dec_number
cmp al,'O'
je get_oct_number
inc esi
get_dec_number:
mov ebx,esi
mov esi,[number_start]
get_dec_digit:
cmp esi,ebx
ja number_ok
cmp byte [esi],27h
je next_dec_digit
xor edx,edx
mov eax,[edi]
shld edx,eax,2
shl eax,2
add eax,[edi]
adc edx,0
add eax,eax
adc edx,edx
mov [edi],eax
mov eax,[edi+4]
add eax,eax
jc dec_out_of_range
add eax,eax
jc dec_out_of_range
add eax,[edi+4]
jc dec_out_of_range
add eax,eax
jc dec_out_of_range
add eax,edx
jc dec_out_of_range
mov [edi+4],eax
movzx eax,byte [esi]
sub al,30h
jc bad_number
cmp al,9
ja bad_number
add [edi],eax
adc dword [edi+4],0
jc dec_out_of_range
next_dec_digit:
inc esi
jmp get_dec_digit
dec_out_of_range:
cmp esi,ebx
ja dec_out_of_range_finished
lods byte [esi]
cmp al,27h
je bad_number
sub al,30h
jc bad_number
cmp al,9
ja bad_number
jmp dec_out_of_range
dec_out_of_range_finished:
or ebp,-1
jmp number_ok
bad_number:
pop eax
invalid_number:
mov esi,[number_start]
dec esi
not_number:
dec esi
stc
ret
get_bin_number:
xor bl,bl
get_bin_digit:
cmp esi,[number_start]
jb number_ok
movzx eax,byte [esi]
cmp al,27h
je bin_digit_skip
sub al,30h
cmp al,1
ja bad_number
xor edx,edx
mov cl,bl
dec esi
cmp bl,64
je bin_out_of_range
inc bl
cmp cl,32
jae bin_digit_high
shl eax,cl
or dword [edi],eax
jmp get_bin_digit
bin_digit_high:
sub cl,32
shl eax,cl
or dword [edi+4],eax
jmp get_bin_digit
bin_out_of_range:
or al,al
jz get_bin_digit
or ebp,-1
jmp get_bin_digit
bin_digit_skip:
dec esi
jmp get_bin_digit
pascal_hex_number:
cmp cl,1
je bad_number
get_hex_number:
xor bl,bl
get_hex_digit:
cmp esi,[number_start]
jb number_ok
movzx eax,byte [esi]
cmp al,27h
je hex_digit_skip
cmp al,'x'
je hex_number_ok
cmp al,'$'
je pascal_hex_ok
sub al,30h
cmp al,9
jbe hex_digit_ok
sub al,7
cmp al,15
jbe hex_letter_digit_ok
sub al,20h
cmp al,15
ja bad_number
hex_letter_digit_ok:
cmp al,10
jb bad_number
hex_digit_ok:
xor edx,edx
mov cl,bl
dec esi
cmp bl,64
je hex_out_of_range
add bl,4
cmp cl,32
jae hex_digit_high
shl eax,cl
or dword [edi],eax
jmp get_hex_digit
hex_digit_high:
sub cl,32
shl eax,cl
or dword [edi+4],eax
jmp get_hex_digit
hex_out_of_range:
or al,al
jz get_hex_digit
or ebp,-1
jmp get_hex_digit
hex_digit_skip:
dec esi
jmp get_hex_digit
get_oct_number:
xor bl,bl
get_oct_digit:
cmp esi,[number_start]
jb number_ok
movzx eax,byte [esi]
cmp al,27h
je oct_digit_skip
sub al,30h
cmp al,7
ja bad_number
oct_digit_ok:
xor edx,edx
mov cl,bl
dec esi
cmp bl,63
ja oct_out_of_range
jne oct_range_ok
cmp al,1
ja oct_out_of_range
oct_range_ok:
add bl,3
cmp cl,30
je oct_digit_wrap
ja oct_digit_high
shl eax,cl
or dword [edi],eax
jmp get_oct_digit
oct_digit_wrap:
shl eax,cl
adc dword [edi+4],0
or dword [edi],eax
jmp get_oct_digit
oct_digit_high:
sub cl,32
shl eax,cl
or dword [edi+4],eax
jmp get_oct_digit
oct_digit_skip:
dec esi
jmp get_oct_digit
oct_out_of_range:
or al,al
jz get_oct_digit
or ebp,-1
jmp get_oct_digit
hex_number_ok:
dec esi
pascal_hex_ok:
cmp esi,[number_start]
jne bad_number
number_ok:
pop esi
number_done:
clc
ret
get_text_number:
lods dword [esi]
mov edx,eax
xor bl,bl
mov dword [edi],0
mov dword [edi+4],0
get_text_character:
sub edx,1
jc number_done
movzx eax,byte [esi]
inc esi
mov cl,bl
cmp bl,64
je text_out_of_range
add bl,8
cmp cl,32
jae text_character_high
shl eax,cl
or dword [edi],eax
jmp get_text_character
text_character_high:
sub cl,32
shl eax,cl
or dword [edi+4],eax
jmp get_text_character
text_out_of_range:
or ebp,-1
jmp get_text_character
 
get_fp_value:
push edi esi
lods byte [esi]
cmp al,1Ah
je fp_value_start
cmp al,'-'
je fp_sign_ok
cmp al,'+'
jne not_fp_value
fp_sign_ok:
lods byte [esi]
cmp al,1Ah
jne not_fp_value
fp_value_start:
lods byte [esi]
movzx ecx,al
cmp cl,1
jbe not_fp_value
lea edx,[esi+1]
xor ah,ah
check_fp_value:
lods byte [esi]
cmp al,'.'
je fp_character_dot
cmp al,'E'
je fp_character_exp
cmp al,'e'
je fp_character_exp
cmp al,'F'
je fp_last_character
cmp al,'f'
je fp_last_character
digit_expected:
cmp al,'0'
jb not_fp_value
cmp al,'9'
ja not_fp_value
jmp fp_character_ok
fp_character_dot:
cmp esi,edx
je not_fp_value
or ah,ah
jnz not_fp_value
or ah,1
lods byte [esi]
loop digit_expected
not_fp_value:
pop esi edi
stc
ret
fp_last_character:
cmp cl,1
jne not_fp_value
or ah,4
jmp fp_character_ok
fp_character_exp:
cmp esi,edx
je not_fp_value
cmp ah,1
ja not_fp_value
or ah,2
cmp ecx,1
jne fp_character_ok
cmp byte [esi],'+'
je fp_exp_sign
cmp byte [esi],'-'
jne fp_character_ok
fp_exp_sign:
inc esi
cmp byte [esi],1Ah
jne not_fp_value
inc esi
lods byte [esi]
movzx ecx,al
inc ecx
fp_character_ok:
dec ecx
jnz check_fp_value
or ah,ah
jz not_fp_value
pop esi
lods byte [esi]
mov [fp_sign],0
cmp al,1Ah
je fp_get
inc esi
cmp al,'+'
je fp_get
mov [fp_sign],1
fp_get:
lods byte [esi]
movzx ecx,al
xor edx,edx
mov edi,fp_value
mov [edi],edx
mov [edi+4],edx
mov [edi+12],edx
call fp_optimize
mov [fp_format],0
mov al,[esi]
fp_before_dot:
lods byte [esi]
cmp al,'.'
je fp_dot
cmp al,'E'
je fp_exponent
cmp al,'e'
je fp_exponent
cmp al,'F'
je fp_done
cmp al,'f'
je fp_done
sub al,30h
mov edi,fp_value+16
xor edx,edx
mov dword [edi+12],edx
mov dword [edi],edx
mov dword [edi+4],edx
mov [edi+7],al
mov dl,7
mov dword [edi+8],edx
call fp_optimize
mov edi,fp_value
push ecx
mov ecx,10
call fp_mul
pop ecx
mov ebx,fp_value+16
call fp_add
loop fp_before_dot
fp_dot:
mov edi,fp_value+16
xor edx,edx
mov [edi],edx
mov [edi+4],edx
mov byte [edi+7],80h
mov [edi+8],edx
mov dword [edi+12],edx
dec ecx
jz fp_done
fp_after_dot:
lods byte [esi]
cmp al,'E'
je fp_exponent
cmp al,'e'
je fp_exponent
cmp al,'F'
je fp_done
cmp al,'f'
je fp_done
inc [fp_format]
cmp [fp_format],80h
jne fp_counter_ok
mov [fp_format],7Fh
fp_counter_ok:
dec esi
mov edi,fp_value+16
push ecx
mov ecx,10
call fp_div
push dword [edi]
push dword [edi+4]
push dword [edi+8]
push dword [edi+12]
lods byte [esi]
sub al,30h
movzx ecx,al
call fp_mul
mov ebx,edi
mov edi,fp_value
call fp_add
mov edi,fp_value+16
pop dword [edi+12]
pop dword [edi+8]
pop dword [edi+4]
pop dword [edi]
pop ecx
dec ecx
jnz fp_after_dot
jmp fp_done
fp_exponent:
or [fp_format],80h
xor edx,edx
xor ebp,ebp
dec ecx
jnz get_exponent
cmp byte [esi],'+'
je fp_exponent_sign
cmp byte [esi],'-'
jne fp_done
not ebp
fp_exponent_sign:
add esi,2
lods byte [esi]
movzx ecx,al
get_exponent:
movzx eax,byte [esi]
inc esi
sub al,30h
cmp al,10
jae exponent_ok
imul edx,10
cmp edx,8000h
jae value_out_of_range
add edx,eax
loop get_exponent
exponent_ok:
mov edi,fp_value
or edx,edx
jz fp_done
mov ecx,edx
or ebp,ebp
jnz fp_negative_power
fp_power:
push ecx
mov ecx,10
call fp_mul
pop ecx
loop fp_power
jmp fp_done
fp_negative_power:
push ecx
mov ecx,10
call fp_div
pop ecx
loop fp_negative_power
fp_done:
mov edi,fp_value
mov al,[fp_format]
mov [edi+10],al
mov al,[fp_sign]
mov [edi+11],al
test byte [edi+15],80h
jz fp_ok
add dword [edi],1
adc dword [edi+4],0
jnc fp_ok
mov eax,[edi+4]
shrd [edi],eax,1
shr eax,1
or eax,80000000h
mov [edi+4],eax
inc word [edi+8]
fp_ok:
pop edi
clc
ret
fp_mul:
or ecx,ecx
jz fp_zero
mov eax,[edi+12]
mul ecx
mov [edi+12],eax
mov ebx,edx
mov eax,[edi]
mul ecx
add eax,ebx
adc edx,0
mov [edi],eax
mov ebx,edx
mov eax,[edi+4]
mul ecx
add eax,ebx
adc edx,0
mov [edi+4],eax
.loop:
or edx,edx
jz .done
mov eax,[edi]
shrd [edi+12],eax,1
mov eax,[edi+4]
shrd [edi],eax,1
shrd eax,edx,1
mov [edi+4],eax
shr edx,1
inc dword [edi+8]
cmp dword [edi+8],8000h
jge value_out_of_range
jmp .loop
.done:
ret
fp_div:
mov eax,[edi+4]
xor edx,edx
div ecx
mov [edi+4],eax
mov eax,[edi]
div ecx
mov [edi],eax
mov eax,[edi+12]
div ecx
mov [edi+12],eax
mov ebx,eax
or ebx,[edi]
or ebx,[edi+4]
jz fp_zero
.loop:
test byte [edi+7],80h
jnz .exp_ok
mov eax,[edi]
shld [edi+4],eax,1
mov eax,[edi+12]
shld [edi],eax,1
add eax,eax
mov [edi+12],eax
dec dword [edi+8]
add edx,edx
jmp .loop
.exp_ok:
mov eax,edx
xor edx,edx
div ecx
add [edi+12],eax
adc dword [edi],0
adc dword [edi+4],0
jnc .done
mov eax,[edi+4]
mov ebx,[edi]
shrd [edi],eax,1
shrd [edi+12],ebx,1
shr eax,1
or eax,80000000h
mov [edi+4],eax
inc dword [edi+8]
.done:
ret
fp_add:
cmp dword [ebx+8],8000h
je .done
cmp dword [edi+8],8000h
je .copy
mov eax,[ebx+8]
cmp eax,[edi+8]
jge .exp_ok
mov eax,[edi+8]
.exp_ok:
call .change_exp
xchg ebx,edi
call .change_exp
xchg ebx,edi
mov edx,[ebx+12]
mov eax,[ebx]
mov ebx,[ebx+4]
add [edi+12],edx
adc [edi],eax
adc [edi+4],ebx
jnc .done
mov eax,[edi]
shrd [edi+12],eax,1
mov eax,[edi+4]
shrd [edi],eax,1
shr eax,1
or eax,80000000h
mov [edi+4],eax
inc dword [edi+8]
.done:
ret
.copy:
mov eax,[ebx]
mov [edi],eax
mov eax,[ebx+4]
mov [edi+4],eax
mov eax,[ebx+8]
mov [edi+8],eax
mov eax,[ebx+12]
mov [edi+12],eax
ret
.change_exp:
push ecx
mov ecx,eax
sub ecx,[ebx+8]
mov edx,[ebx+4]
jecxz .exp_done
.exp_loop:
mov ebp,[ebx]
shrd [ebx+12],ebp,1
shrd [ebx],edx,1
shr edx,1
inc dword [ebx+8]
loop .exp_loop
.exp_done:
mov [ebx+4],edx
pop ecx
ret
fp_optimize:
mov eax,[edi]
mov ebp,[edi+4]
or ebp,[edi]
or ebp,[edi+12]
jz fp_zero
.loop:
test byte [edi+7],80h
jnz .done
shld [edi+4],eax,1
mov ebp,[edi+12]
shld eax,ebp,1
mov [edi],eax
shl dword [edi+12],1
dec dword [edi+8]
jmp .loop
.done:
ret
fp_zero:
mov dword [edi+8],8000h
ret
 
preevaluate_logical_expression:
xor al,al
preevaluate_embedded_logical_expression:
mov [logical_value_wrapping],al
push edi
call preevaluate_logical_value
preevaluation_loop:
cmp al,0FFh
je invalid_logical_expression
mov dl,[esi]
inc esi
cmp dl,'|'
je preevaluate_or
cmp dl,'&'
je preevaluate_and
cmp dl,92h
je preevaluation_done
or dl,dl
jnz invalid_logical_expression
preevaluation_done:
pop edx
dec esi
ret
preevaluate_or:
cmp al,'1'
je quick_true
cmp al,'0'
je leave_only_following
push edi
mov al,dl
stos byte [edi]
call preevaluate_logical_value
pop ebx
cmp al,'0'
je leave_only_preceding
cmp al,'1'
jne preevaluation_loop
stos byte [edi]
xor al,al
jmp preevaluation_loop
preevaluate_and:
cmp al,'0'
je quick_false
cmp al,'1'
je leave_only_following
push edi
mov al,dl
stos byte [edi]
call preevaluate_logical_value
pop ebx
cmp al,'1'
je leave_only_preceding
cmp al,'0'
jne preevaluation_loop
stos byte [edi]
xor al,al
jmp preevaluation_loop
leave_only_following:
mov edi,[esp]
call preevaluate_logical_value
jmp preevaluation_loop
leave_only_preceding:
mov edi,ebx
xor al,al
jmp preevaluation_loop
quick_true:
call skip_logical_value
jc invalid_logical_expression
mov edi,[esp]
mov al,'1'
jmp preevaluation_loop
quick_false:
call skip_logical_value
jc invalid_logical_expression
mov edi,[esp]
mov al,'0'
jmp preevaluation_loop
invalid_logical_expression:
pop edi
mov esi,edi
mov al,0FFh
stos byte [edi]
ret
skip_logical_value:
cmp byte [esi],'~'
jne negation_skipped
inc esi
jmp skip_logical_value
negation_skipped:
mov al,[esi]
cmp al,91h
jne skip_simple_logical_value
inc esi
xchg al,[logical_value_wrapping]
push eax
skip_logical_expression:
call skip_logical_value
lods byte [esi]
or al,al
jz wrongly_structured_logical_expression
cmp al,0Fh
je wrongly_structured_logical_expression
cmp al,'|'
je skip_logical_expression
cmp al,'&'
je skip_logical_expression
cmp al,92h
jne wrongly_structured_logical_expression
pop eax
mov [logical_value_wrapping],al
logical_value_skipped:
clc
ret
wrongly_structured_logical_expression:
pop eax
stc
ret
skip_simple_logical_value:
mov [logical_value_parentheses],0
find_simple_logical_value_end:
mov al,[esi]
or al,al
jz logical_value_skipped
cmp al,0Fh
je logical_value_skipped
cmp al,'|'
je logical_value_skipped
cmp al,'&'
je logical_value_skipped
cmp al,91h
je skip_logical_value_internal_parenthesis
cmp al,92h
jne skip_logical_value_symbol
sub [logical_value_parentheses],1
jnc skip_logical_value_symbol
cmp [logical_value_wrapping],91h
jne skip_logical_value_symbol
jmp logical_value_skipped
skip_logical_value_internal_parenthesis:
inc [logical_value_parentheses]
skip_logical_value_symbol:
call skip_symbol
jmp find_simple_logical_value_end
preevaluate_logical_value:
mov ebp,edi
preevaluate_negation:
cmp byte [esi],'~'
jne preevaluate_negation_ok
movs byte [edi],[esi]
jmp preevaluate_negation
preevaluate_negation_ok:
mov ebx,esi
cmp byte [esi],91h
jne preevaluate_simple_logical_value
lods byte [esi]
stos byte [edi]
push ebp
mov dl,[logical_value_wrapping]
push edx
call preevaluate_embedded_logical_expression
pop edx
mov [logical_value_wrapping],dl
pop ebp
cmp al,0FFh
je invalid_logical_value
cmp byte [esi],92h
jne invalid_logical_value
or al,al
jnz preevaluated_expression_value
movs byte [edi],[esi]
ret
preevaluated_expression_value:
inc esi
lea edx,[edi-1]
sub edx,ebp
test edx,1
jz expression_negation_ok
xor al,1
expression_negation_ok:
mov edi,ebp
ret
invalid_logical_value:
mov edi,ebp
mov al,0FFh
ret
preevaluate_simple_logical_value:
xor edx,edx
mov [logical_value_parentheses],edx
find_logical_value_boundaries:
mov al,[esi]
or al,al
jz logical_value_boundaries_found
cmp al,91h
je logical_value_internal_parentheses
cmp al,92h
je logical_value_boundaries_parenthesis_close
cmp al,'|'
je logical_value_boundaries_found
cmp al,'&'
je logical_value_boundaries_found
or edx,edx
jnz next_symbol_in_logical_value
cmp al,0F0h
je preevaluable_logical_operator
cmp al,0F7h
je preevaluable_logical_operator
cmp al,0F6h
jne next_symbol_in_logical_value
preevaluable_logical_operator:
mov edx,esi
next_symbol_in_logical_value:
call skip_symbol
jmp find_logical_value_boundaries
logical_value_internal_parentheses:
inc [logical_value_parentheses]
jmp next_symbol_in_logical_value
logical_value_boundaries_parenthesis_close:
sub [logical_value_parentheses],1
jnc next_symbol_in_logical_value
cmp [logical_value_wrapping],91h
jne next_symbol_in_logical_value
logical_value_boundaries_found:
or edx,edx
jz non_preevaluable_logical_value
mov al,[edx]
cmp al,0F0h
je compare_symbols
cmp al,0F7h
je compare_symbol_types
cmp al,0F6h
je scan_symbols_list
non_preevaluable_logical_value:
mov ecx,esi
mov esi,ebx
sub ecx,esi
jz invalid_logical_value
cmp esi,edi
je leave_logical_value_intact
rep movs byte [edi],[esi]
xor al,al
ret
leave_logical_value_intact:
add edi,ecx
add esi,ecx
xor al,al
ret
compare_symbols:
lea ecx,[esi-1]
sub ecx,edx
mov eax,edx
sub eax,ebx
cmp ecx,eax
jne preevaluated_false
push esi edi
mov esi,ebx
lea edi,[edx+1]
repe cmps byte [esi],[edi]
pop edi esi
je preevaluated_true
preevaluated_false:
mov eax,edi
sub eax,ebp
test eax,1
jnz store_true
store_false:
mov edi,ebp
mov al,'0'
ret
preevaluated_true:
mov eax,edi
sub eax,ebp
test eax,1
jnz store_false
store_true:
mov edi,ebp
mov al,'1'
ret
compare_symbol_types:
push esi
lea esi,[edx+1]
type_comparison:
cmp esi,[esp]
je types_compared
mov al,[esi]
cmp al,[ebx]
jne different_type
cmp al,'('
jne equal_type
mov al,[esi+1]
mov ah,[ebx+1]
cmp al,ah
je equal_type
or al,al
jz different_type
or ah,ah
jz different_type
cmp al,'.'
je different_type
cmp ah,'.'
je different_type
equal_type:
call skip_symbol
xchg esi,ebx
call skip_symbol
xchg esi,ebx
jmp type_comparison
types_compared:
pop esi
cmp byte [ebx],0F7h
jne preevaluated_false
jmp preevaluated_true
different_type:
pop esi
jmp preevaluated_false
scan_symbols_list:
push edi esi
lea esi,[edx+1]
sub edx,ebx
lods byte [esi]
cmp al,'<'
jne invalid_symbols_list
get_next_from_list:
mov edi,esi
get_from_list:
cmp byte [esi],','
je compare_in_list
cmp byte [esi],'>'
je compare_in_list
cmp esi,[esp]
jae invalid_symbols_list
call skip_symbol
jmp get_from_list
compare_in_list:
mov ecx,esi
sub ecx,edi
cmp ecx,edx
jne not_equal_length_in_list
mov esi,ebx
repe cmps byte [esi],[edi]
mov esi,edi
jne not_equal_in_list
skip_rest_of_list:
cmp byte [esi],'>'
je check_list_end
cmp esi,[esp]
jae invalid_symbols_list
call skip_symbol
jmp skip_rest_of_list
check_list_end:
inc esi
cmp esi,[esp]
jne invalid_symbols_list
pop esi edi
jmp preevaluated_true
not_equal_in_list:
add esi,ecx
not_equal_length_in_list:
lods byte [esi]
cmp al,','
je get_next_from_list
cmp esi,[esp]
jne invalid_symbols_list
pop esi edi
jmp preevaluated_false
invalid_symbols_list:
pop esi edi
jmp invalid_logical_value
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/formats.inc
0,0 → 1,4130
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
formatter:
mov [current_offset],edi
cmp [output_file],0
jne output_path_ok
mov esi,[input_file]
mov edi,[free_additional_memory]
copy_output_path:
lods byte [esi]
cmp edi,[structures_buffer]
jae out_of_memory
stos byte [edi]
or al,al
jnz copy_output_path
dec edi
mov eax,edi
find_extension:
dec eax
cmp eax,[free_additional_memory]
jb extension_found
cmp byte [eax],'\'
je extension_found
cmp byte [eax],'/'
je extension_found
cmp byte [eax],'.'
jne find_extension
mov edi,eax
extension_found:
lea eax,[edi+9]
cmp eax,[structures_buffer]
jae out_of_memory
cmp [file_extension],0
jne extension_specified
mov al,[output_format]
cmp al,2
je exe_extension
jb bin_extension
cmp al,4
je obj_extension
cmp al,5
je o_extension
cmp al,3
jne no_extension
cmp [subsystem],1
je sys_extension
cmp [subsystem],10
jae efi_extension
bt [format_flags],8
jnc exe_extension
mov eax,'.dll'
jmp make_extension
sys_extension:
mov eax,'.sys'
jmp make_extension
efi_extension:
mov eax,'.efi'
jmp make_extension
bin_extension:
mov eax,'.bin'
bt [format_flags],0
jnc make_extension
mov eax,'.com'
jmp make_extension
obj_extension:
mov eax,'.obj'
jmp make_extension
o_extension:
mov eax,'.o'
bt [format_flags],0
jnc make_extension
no_extension:
xor eax,eax
jmp make_extension
exe_extension:
mov eax,'.exe'
make_extension:
xchg eax,[edi]
scas dword [edi]
mov byte [edi],0
scas byte [edi]
mov esi,edi
stos dword [edi]
sub edi,9
xor eax,eax
mov ebx,characters
adapt_case:
mov al,[esi]
or al,al
jz adapt_next
xlat byte [ebx]
cmp al,[esi]
je adapt_ok
sub byte [edi],20h
adapt_ok:
inc esi
adapt_next:
inc edi
cmp byte [edi],0
jne adapt_case
jmp extension_ok
extension_specified:
mov al,'.'
stos byte [edi]
mov esi,[file_extension]
copy_extension:
lods byte [esi]
stos byte [edi]
test al,al
jnz copy_extension
dec edi
extension_ok:
mov esi,edi
lea ecx,[esi+1]
sub ecx,[free_additional_memory]
mov edi,[structures_buffer]
dec edi
std
rep movs byte [edi],[esi]
cld
inc edi
mov [structures_buffer],edi
mov [output_file],edi
output_path_ok:
cmp [symbols_file],0
je labels_table_ok
mov ecx,[memory_end]
sub ecx,[labels_list]
mov edi,[tagged_blocks]
sub edi,8
mov [edi],ecx
or dword [edi+4],-1
sub edi,ecx
cmp edi,[current_offset]
jbe out_of_memory
mov [tagged_blocks],edi
mov esi,[memory_end]
copy_labels:
sub esi,32
cmp esi,[labels_list]
jb labels_table_ok
mov ecx,32 shr 2
rep movs dword [edi],[esi]
sub esi,32
jmp copy_labels
labels_table_ok:
mov edi,[current_offset]
cmp [output_format],4
je coff_formatter
cmp [output_format],5
jne common_formatter
bt [format_flags],0
jnc elf_formatter
common_formatter:
mov eax,edi
sub eax,[code_start]
mov [real_code_size],eax
cmp edi,[undefined_data_end]
jne calculate_code_size
mov edi,[undefined_data_start]
calculate_code_size:
mov [current_offset],edi
sub edi,[code_start]
mov [code_size],edi
and [written_size],0
mov edx,[output_file]
call create
jc write_failed
cmp [output_format],3
jne stub_written
mov edx,[code_start]
mov ecx,[stub_size]
sub edx,ecx
add [written_size],ecx
call write
stub_written:
cmp [output_format],2
jne write_output
call write_mz_header
write_output:
call write_code
output_written:
call close
cmp [symbols_file],0
jne dump_symbols
ret
write_code:
mov eax,[written_size]
mov [headers_size],eax
mov edx,[code_start]
mov ecx,[code_size]
add [written_size],ecx
lea eax,[edx+ecx]
call write
jc write_failed
ret
format_directive:
cmp edi,[code_start]
jne unexpected_instruction
mov ebp,[addressing_space]
test byte [ds:ebp+0Ah],1
jnz unexpected_instruction
cmp [output_format],0
jne unexpected_instruction
lods byte [esi]
cmp al,1Ch
je format_prefix
cmp al,18h
jne invalid_argument
lods byte [esi]
select_format:
mov dl,al
shr al,4
mov [output_format],al
and edx,0Fh
or [format_flags],edx
cmp al,2
je format_mz
cmp al,3
je format_pe
cmp al,4
je format_coff
cmp al,5
je format_elf
format_defined:
cmp byte [esi],86h
jne instruction_assembled
cmp word [esi+1],'('
jne invalid_argument
mov eax,[esi+3]
add esi,3+4
mov [file_extension],esi
lea esi,[esi+eax+1]
jmp instruction_assembled
format_prefix:
lods byte [esi]
mov ah,al
lods byte [esi]
cmp al,18h
jne invalid_argument
lods byte [esi]
mov edx,eax
shr dl,4
shr dh,4
cmp dl,dh
jne invalid_argument
or al,ah
jmp select_format
entry_directive:
bts [format_flags],10h
jc setting_already_specified
mov al,[output_format]
cmp al,2
je mz_entry
cmp al,3
je pe_entry
cmp al,5
jne illegal_instruction
bt [format_flags],0
jc elf_entry
jmp illegal_instruction
stack_directive:
bts [format_flags],11h
jc setting_already_specified
mov al,[output_format]
cmp al,2
je mz_stack
cmp al,3
je pe_stack
jmp illegal_instruction
heap_directive:
bts [format_flags],12h
jc setting_already_specified
mov al,[output_format]
cmp al,2
je mz_heap
cmp al,3
je pe_heap
jmp illegal_instruction
segment_directive:
mov al,[output_format]
cmp al,2
je mz_segment
cmp al,5
je elf_segment
jmp illegal_instruction
section_directive:
mov al,[output_format]
cmp al,3
je pe_section
cmp al,4
je coff_section
cmp al,5
je elf_section
jmp illegal_instruction
public_directive:
mov al,[output_format]
cmp al,4
je public_allowed
cmp al,5
jne illegal_instruction
bt [format_flags],0
jc illegal_instruction
public_allowed:
mov [base_code],0C0h
lods byte [esi]
cmp al,2
je public_label
cmp al,1Dh
jne invalid_argument
lods byte [esi]
and al,7
add [base_code],al
lods byte [esi]
cmp al,2
jne invalid_argument
public_label:
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
inc esi
mov dx,[current_pass]
mov [eax+18],dx
or byte [eax+8],8
cmp [symbols_file],0
je public_reference_ok
cmp [next_pass_needed],0
jne public_reference_ok
mov ebx,eax
call store_label_reference
mov eax,ebx
public_reference_ok:
mov ebx,[free_additional_memory]
lea edx,[ebx+10h]
cmp edx,[structures_buffer]
jae out_of_memory
mov [free_additional_memory],edx
mov [ebx+8],eax
mov eax,[current_line]
mov [ebx+0Ch],eax
lods byte [esi]
cmp al,86h
jne invalid_argument
lods word [esi]
cmp ax,'('
jne invalid_argument
mov [ebx+4],esi
lods dword [esi]
lea esi,[esi+eax+1]
mov al,[base_code]
mov [ebx],al
jmp instruction_assembled
extrn_directive:
mov al,[output_format]
cmp al,4
je extrn_allowed
cmp al,5
jne illegal_instruction
bt [format_flags],0
jc illegal_instruction
extrn_allowed:
lods word [esi]
cmp ax,'('
jne invalid_argument
mov ebx,esi
lods dword [esi]
lea esi,[esi+eax+1]
mov edx,[free_additional_memory]
lea eax,[edx+0Ch]
cmp eax,[structures_buffer]
jae out_of_memory
mov [free_additional_memory],eax
mov byte [edx],80h
mov [edx+4],ebx
lods byte [esi]
cmp al,86h
jne invalid_argument
lods byte [esi]
cmp al,2
jne invalid_argument
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
inc esi
mov ebx,eax
xor ah,ah
lods byte [esi]
cmp al,':'
je get_extrn_size
dec esi
cmp al,11h
jne extrn_size_ok
get_extrn_size:
lods word [esi]
cmp al,11h
jne invalid_argument
extrn_size_ok:
mov [address_symbol],edx
mov [label_size],ah
movzx ecx,ah
mov [edx+8],ecx
xor eax,eax
xor edx,edx
xor ebp,ebp
mov [address_sign],0
mov ch,2
test [format_flags],8
jz make_free_label
mov ch,4
jmp make_free_label
mark_relocation:
cmp [value_type],0
je relocation_ok
mov ebp,[addressing_space]
test byte [ds:ebp+0Ah],1
jnz relocation_ok
cmp [output_format],2
je mark_mz_relocation
cmp [output_format],3
je mark_pe_relocation
cmp [output_format],4
je mark_coff_relocation
cmp [output_format],5
je mark_elf_relocation
relocation_ok:
ret
close_pass:
mov al,[output_format]
cmp al,3
je close_pe
cmp al,4
je close_coff
cmp al,5
je close_elf
ret
 
format_mz:
mov edx,[additional_memory]
push edi
mov edi,edx
mov ecx,1Ch shr 2
xor eax,eax
rep stos dword [edi]
mov [free_additional_memory],edi
pop edi
mov word [edx+0Ch],0FFFFh
mov word [edx+10h],1000h
mov [code_type],16
jmp format_defined
mark_mz_relocation:
push eax ebx
inc word [number_of_relocations]
jz format_limitations_exceeded
mov ebx,[free_additional_memory]
mov eax,edi
sub eax,[code_start]
mov [ebx],ax
shr eax,16
shl ax,12
mov [ebx+2],ax
cmp word [ebx],0FFFFh
jne mz_relocation_ok
inc word [ebx+2]
sub word [ebx],10h
mz_relocation_ok:
add ebx,4
cmp ebx,[structures_buffer]
jae out_of_memory
mov [free_additional_memory],ebx
pop ebx eax
ret
mz_segment:
lods byte [esi]
cmp al,2
jne invalid_argument
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
inc esi
mov ebx,eax
mov eax,edi
sub eax,[code_start]
mov ecx,0Fh
add eax,0Fh
and eax,1111b
sub ecx,eax
mov edx,edi
xor eax,eax
rep stos byte [edi]
mov eax,edx
call undefined_data
push ebx
call create_addressing_space
pop ebx
mov eax,edi
sub eax,[code_start]
shr eax,4
cmp eax,10000h
jae value_out_of_range
mov edx,eax
mov al,16
cmp byte [esi],13h
jne segment_type_ok
inc esi
lods byte [esi]
segment_type_ok:
mov [code_type],al
mov eax,edx
mov ch,1
mov [address_sign],0
xor edx,edx
xor ebp,ebp
mov [label_size],0
mov [address_symbol],edx
jmp make_free_label
mz_entry:
lods byte [esi]
cmp al,'('
jne invalid_argument
call get_word_value
cmp [value_type],1
je initial_cs_ok
call recoverable_invalid_address
initial_cs_ok:
mov edx,[additional_memory]
mov [edx+16h],ax
lods byte [esi]
cmp al,':'
jne invalid_argument
lods byte [esi]
cmp al,'('
jne invalid_argument
ja invalid_address
call get_word_value
cmp [value_type],0
jne invalid_use_of_symbol
mov edx,[additional_memory]
mov [edx+14h],ax
jmp instruction_assembled
recoverable_invalid_address:
cmp [error_line],0
jne ignore_invalid_address
push [current_line]
pop [error_line]
mov [error],invalid_address
ignore_invalid_address:
ret
mz_stack:
lods byte [esi]
cmp al,'('
jne invalid_argument
call get_word_value
cmp byte [esi],':'
je stack_pointer
cmp ax,10h
jb invalid_value
cmp [value_type],0
jne invalid_use_of_symbol
mov edx,[additional_memory]
mov [edx+10h],ax
jmp instruction_assembled
stack_pointer:
cmp [value_type],1
je initial_ss_ok
call recoverable_invalid_address
initial_ss_ok:
mov edx,[additional_memory]
mov [edx+0Eh],ax
lods byte [esi]
cmp al,':'
jne invalid_argument
lods byte [esi]
cmp al,'('
jne invalid_argument
call get_word_value
cmp [value_type],0
jne invalid_use_of_symbol
mov edx,[additional_memory]
mov [edx+10h],ax
bts [format_flags],4
jmp instruction_assembled
mz_heap:
cmp [output_format],2
jne illegal_instruction
lods byte [esi]
call get_size_operator
cmp ah,1
je invalid_value
cmp ah,2
ja invalid_value
cmp al,'('
jne invalid_argument
call get_word_value
cmp [value_type],0
jne invalid_use_of_symbol
mov edx,[additional_memory]
mov [edx+0Ch],ax
jmp instruction_assembled
write_mz_header:
mov edx,[additional_memory]
bt [format_flags],4
jc mz_stack_ok
mov eax,[real_code_size]
dec eax
shr eax,4
inc eax
mov [edx+0Eh],ax
shl eax,4
movzx ecx,word [edx+10h]
add eax,ecx
mov [real_code_size],eax
mz_stack_ok:
mov edi,[free_additional_memory]
mov eax,[number_of_relocations]
shl eax,2
add eax,1Ch
sub edi,eax
xchg edi,[free_additional_memory]
mov ecx,0Fh
add eax,0Fh
and eax,1111b
sub ecx,eax
xor al,al
rep stos byte [edi]
sub edi,[free_additional_memory]
mov ecx,edi
shr edi,4
mov word [edx],'MZ' ; signature
mov [edx+8],di ; header size in paragraphs
mov eax,[number_of_relocations]
mov [edx+6],ax ; number of relocation entries
mov eax,[code_size]
add eax,ecx
mov esi,eax
shr esi,9
and eax,1FFh
inc si
or ax,ax
jnz mz_size_ok
dec si
mz_size_ok:
mov [edx+2],ax ; number of bytes in last page
mov [edx+4],si ; number of pages
mov eax,[real_code_size]
dec eax
shr eax,4
inc eax
mov esi,[code_size]
dec esi
shr esi,4
inc esi
sub eax,esi
mov [edx+0Ah],ax ; minimum memory in addition to code
add [edx+0Ch],ax ; maximum memory in addition to code
salc
mov ah,al
or [edx+0Ch],ax
mov word [edx+18h],1Ch ; offset of relocation table
add [written_size],ecx
call write
jc write_failed
ret
 
make_stub:
mov [stub_file],edx
or edx,edx
jnz stub_from_file
push esi
mov edx,edi
xor eax,eax
mov ecx,20h
rep stos dword [edi]
mov eax,40h+default_stub_end-default_stub
mov cx,100h+default_stub_end-default_stub
mov word [edx],'MZ'
mov byte [edx+4],1
mov word [edx+2],ax
mov byte [edx+8],4
mov byte [edx+0Ah],10h
mov word [edx+0Ch],0FFFFh
mov word [edx+10h],cx
mov word [edx+3Ch],ax
mov byte [edx+18h],40h
lea edi,[edx+40h]
mov esi,default_stub
mov ecx,default_stub_end-default_stub
rep movs byte [edi],[esi]
pop esi
jmp stub_ok
default_stub:
use16
push cs
pop ds
mov dx,stub_message-default_stub
mov ah,9
int 21h
mov ax,4C01h
int 21h
stub_message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h
rq 1
default_stub_end:
use32
stub_from_file:
push esi
mov esi,edx
call open_binary_file
mov edx,edi
mov ecx,1Ch
mov esi,edx
call read
jc binary_stub
cmp word [esi],'MZ'
jne binary_stub
add edi,1Ch
movzx ecx,word [esi+6]
add ecx,11b
and ecx,not 11b
add ecx,(40h-1Ch) shr 2
lea eax,[edi+ecx*4]
cmp edi,[tagged_blocks]
jae out_of_memory
xor eax,eax
rep stos dword [edi]
mov edx,40h
xchg dx,[esi+18h]
xor al,al
call lseek
movzx ecx,word [esi+6]
shl ecx,2
lea edx,[esi+40h]
call read
mov edx,edi
sub edx,esi
shr edx,4
xchg dx,[esi+8]
shl edx,4
xor al,al
call lseek
movzx ecx,word [esi+4]
dec ecx
shl ecx,9
movzx edx,word [esi+2]
test edx,edx
jnz stub_header_size_ok
mov dx,200h
stub_header_size_ok:
add ecx,edx
mov edx,edi
sub ecx,eax
je read_stub_code
jb stub_code_ok
push ecx
dec ecx
shr ecx,3
inc ecx
shl ecx,1
lea eax,[edi+ecx*4]
cmp eax,[tagged_blocks]
jae out_of_memory
xor eax,eax
rep stos dword [edi]
pop ecx
read_stub_code:
call read
stub_code_ok:
call close
mov edx,edi
sub edx,esi
mov ax,dx
and ax,1FFh
mov [esi+2],ax
dec edx
shr edx,9
inc edx
mov [esi+4],dx
mov eax,edi
sub eax,esi
mov [esi+3Ch],eax
pop esi
stub_ok:
ret
binary_stub:
mov esi,edi
mov ecx,40h shr 2
xor eax,eax
rep stos dword [edi]
mov al,2
xor edx,edx
call lseek
push eax
xor al,al
xor edx,edx
call lseek
mov ecx,[esp]
add ecx,40h+111b
and ecx,not 111b
mov ax,cx
and ax,1FFh
mov [esi+2],ax
lea eax,[ecx+1FFh]
shr eax,9
mov [esi+4],ax
mov [esi+3Ch],ecx
sub ecx,40h
mov eax,10000h
sub eax,ecx
jbe binary_heap_ok
shr eax,4
mov [esi+0Ah],ax
binary_heap_ok:
mov word [esi],'MZ'
mov byte [esi+8],4
mov ax,0FFFFh
mov [esi+0Ch],ax
dec ax
mov [esi+10h],ax
sub ax,0Eh
mov [esi+0Eh],ax
mov [esi+16h],ax
mov word [esi+14h],100h
mov byte [esi+18h],40h
mov eax,[tagged_blocks]
sub eax,ecx
cmp edi,eax
jae out_of_memory
mov edx,edi
shr ecx,2
xor eax,eax
rep stos dword [edi]
pop ecx
call read
call close
pop esi
ret
 
format_pe:
xor edx,edx
mov [machine],14Ch
mov [subsystem],3
mov [subsystem_version],3 + 10 shl 16
mov [image_base],400000h
and [image_base_high],0
test [format_flags],8
jz pe_settings
mov [machine],8664h
mov [subsystem_version],5 + 0 shl 16
pe_settings:
cmp byte [esi],84h
je get_stub_name
cmp byte [esi],80h
je get_pe_base
cmp byte [esi],1Bh
jne pe_settings_ok
lods byte [esi]
lods byte [esi]
test al,80h+40h
jz subsystem_setting
cmp al,80h
je dll_flag
cmp al,81h
je wdm_flag
cmp al,82h
je large_flag
cmp al,83h
je nx_flag
jmp pe_settings
dll_flag:
bts [format_flags],8
jc setting_already_specified
jmp pe_settings
wdm_flag:
bts [format_flags],9
jc setting_already_specified
jmp pe_settings
large_flag:
bts [format_flags],11
jc setting_already_specified
test [format_flags],8
jnz invalid_argument
jmp pe_settings
nx_flag:
bts [format_flags],12
jc setting_already_specified
jmp pe_settings
subsystem_setting:
bts [format_flags],7
jc setting_already_specified
and ax,3Fh
mov [subsystem],ax
cmp ax,10
jb subsystem_type_ok
or [format_flags],4
subsystem_type_ok:
cmp byte [esi],'('
jne pe_settings
inc esi
cmp byte [esi],'.'
jne invalid_value
inc esi
push edx
cmp byte [esi+11],0
jne invalid_value
cmp byte [esi+10],2
ja invalid_value
mov dx,[esi+8]
cmp dx,8000h
je zero_version
mov eax,[esi+4]
cmp dx,7
jg invalid_value
mov cx,7
sub cx,dx
mov eax,[esi+4]
shr eax,cl
mov ebx,eax
shr ebx,24
cmp bl,100
jae invalid_value
and eax,0FFFFFFh
mov ecx,100
mul ecx
shrd eax,edx,24
jnc version_value_ok
inc eax
version_value_ok:
shl eax,16
mov ax,bx
jmp subsystem_version_ok
zero_version:
xor eax,eax
subsystem_version_ok:
pop edx
add esi,13
mov [subsystem_version],eax
jmp pe_settings
get_pe_base:
bts [format_flags],10
jc setting_already_specified
lods word [esi]
cmp ah,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
push edx edi
add edi,[stub_size]
test [format_flags],4
jnz get_peplus_base
call get_dword_value
mov [image_base],eax
jmp pe_base_ok
get_peplus_base:
call get_qword_value
mov [image_base],eax
mov [image_base_high],edx
pe_base_ok:
pop edi edx
cmp [value_type],0
jne invalid_use_of_symbol
cmp byte [esi],84h
jne pe_settings_ok
get_stub_name:
lods byte [esi]
lods word [esi]
cmp ax,'('
jne invalid_argument
lods dword [esi]
mov edx,esi
add esi,eax
inc esi
pe_settings_ok:
mov ebp,[stub_size]
or ebp,ebp
jz make_pe_stub
cmp edx,[stub_file]
je pe_stub_ok
sub edi,[stub_size]
mov [code_start],edi
make_pe_stub:
call make_stub
mov eax,edi
sub eax,[code_start]
mov [stub_size],eax
mov [code_start],edi
mov ebp,eax
pe_stub_ok:
mov edx,edi
mov ecx,18h+0E0h
test [format_flags],4
jz zero_pe_header
add ecx,10h
zero_pe_header:
add ebp,ecx
shr ecx,2
xor eax,eax
rep stos dword [edi]
mov word [edx],'PE' ; signature
mov ax,[machine]
mov word [edx+4],ax
mov byte [edx+38h+1],10h ; section alignment
mov byte [edx+3Ch+1],2 ; file alignment
mov byte [edx+40h],1 ; OS version
mov eax,[subsystem_version]
mov [edx+48h],eax
mov ax,[subsystem]
mov [edx+5Ch],ax
cmp ax,1
jne pe_alignment_ok
mov eax,20h
mov dword [edx+38h],eax
mov dword [edx+3Ch],eax
pe_alignment_ok:
mov word [edx+1Ah],VERSION_MAJOR + VERSION_MINOR shl 8
test [format_flags],4
jnz init_peplus_specific
mov byte [edx+14h],0E0h ; size of optional header
mov dword [edx+16h],10B010Fh; flags and magic value
mov eax,[image_base]
mov [edx+34h],eax
mov byte [edx+60h+1],10h ; stack reserve
mov byte [edx+64h+1],10h ; stack commit
mov byte [edx+68h+2],1 ; heap reserve
mov byte [edx+74h],16 ; number of directories
jmp pe_header_ok
init_peplus_specific:
mov byte [edx+14h],0F0h ; size of optional header
mov dword [edx+16h],20B002Fh; flags and magic value
mov eax,[image_base]
mov [edx+30h],eax
mov eax,[image_base_high]
mov [edx+34h],eax
mov byte [edx+60h+1],10h ; stack reserve
mov byte [edx+68h+1],10h ; stack commit
mov byte [edx+70h+2],1 ; heap reserve
mov byte [edx+84h],16 ; number of directories
pe_header_ok:
bsf ecx,[edx+3Ch]
imul ebx,[number_of_sections],28h
or ebx,ebx
jnz reserve_space_for_section_headers
mov ebx,28h
reserve_space_for_section_headers:
add ebx,ebp
dec ebx
shr ebx,cl
inc ebx
shl ebx,cl
sub ebx,ebp
mov ecx,ebx
mov eax,[tagged_blocks]
sub eax,ecx
cmp edi,eax
jae out_of_memory
shr ecx,2
xor eax,eax
rep stos dword [edi]
mov eax,edi
sub eax,[code_start]
add eax,[stub_size]
mov [edx+54h],eax ; size of headers
mov ecx,[edx+38h]
dec ecx
add eax,ecx
not ecx
and eax,ecx
bt [format_flags],8
jc pe_entry_init_ok
mov [edx+28h],eax ; entry point rva
pe_entry_init_ok:
and [number_of_sections],0
movzx ebx,word [edx+14h]
lea ebx,[edx+18h+ebx]
mov [current_section],ebx
mov dword [ebx],'.fla'
mov dword [ebx+4],'t'
mov [ebx+14h],edi
mov [ebx+0Ch],eax
mov dword [ebx+24h],0E0000060h
xor ecx,ecx
xor bl,bl
not eax
not ecx
not bl
add eax,1
adc ecx,0
adc bl,0
add eax,edi
adc ecx,0
adc bl,0
test [format_flags],4
jnz peplus_org
sub eax,[edx+34h]
sbb ecx,0
sbb bl,0
jmp pe_org_ok
peplus_org:
sub eax,[edx+30h]
sbb ecx,[edx+34h]
sbb bl,0
pe_org_ok:
test [format_flags],8
jnz pe64_code
mov bh,2
mov [code_type],32
jmp pe_code_type_ok
pe64_code:
mov bh,4
mov [code_type],64
pe_code_type_ok:
bt [resolver_flags],0
jc pe_labels_type_ok
xor bh,bh
pe_labels_type_ok:
push eax ebx
call init_addressing_space
mov ebp,ebx
pop ebx eax
mov [ds:ebp],eax
mov [ds:ebp+4],ecx
mov [ds:ebp+8],bx
mov [ds:ebp+18h],edi
bt [format_flags],8
jnc dll_flag_ok
or byte [edx+16h+1],20h
dll_flag_ok:
bt [format_flags],9
jnc wdm_flag_ok
or byte [edx+5Eh+1],20h
wdm_flag_ok:
bt [format_flags],11
jnc large_flag_ok
or byte [edx+16h],20h
large_flag_ok:
bt [format_flags],12
jnc nx_ok
or byte [edx+5Eh+1],1
nx_ok:
jmp format_defined
pe_section:
call close_pe_section
push eax ebx
call create_addressing_space
mov ebp,ebx
pop ebx eax
bts [format_flags],5
lea ecx,[ebx+28h]
add edx,[edx+54h]
sub edx,[stub_size]
cmp ecx,edx
jbe new_section
lea ebx,[edx-28h]
or [next_pass_needed],-1
push edi
mov edi,ebx
mov ecx,28h shr 4
xor eax,eax
rep stos dword [edi]
pop edi
new_section:
mov [ebx+0Ch],eax
lods word [esi]
cmp ax,'('
jne invalid_argument
lea edx,[esi+4]
mov ecx,[esi]
lea esi,[esi+4+ecx+1]
cmp ecx,8
ja name_too_long
xor eax,eax
mov [ebx],eax
mov [ebx+4],eax
push esi edi
mov edi,ebx
mov esi,edx
rep movs byte [edi],[esi]
pop edi esi
and dword [ebx+24h],0
mov [ebx+14h],edi
mov edx,[code_start]
mov eax,edi
xor ecx,ecx
sub eax,[ebx+0Ch]
sbb ecx,0
sbb byte [ds:ebp+8],0
mov byte [ds:ebp+9],2
mov [code_type],32
test [format_flags],8
jz pe_section_code_type_ok
mov byte [ds:ebp+9],4
mov [code_type],64
pe_section_code_type_ok:
test [format_flags],4
jnz peplus_section_org
sub eax,[edx+34h]
sbb ecx,0
sbb byte [ds:ebp+8],0
bt [resolver_flags],0
jc pe_section_org_ok
mov byte [ds:ebp+9],0
jmp pe_section_org_ok
peplus_section_org:
sub eax,[edx+30h]
sbb ecx,[edx+34h]
sbb byte [ds:ebp+8],0
bt [resolver_flags],0
jc pe_section_org_ok
mov byte [ds:ebp+9],0
pe_section_org_ok:
mov [ds:ebp],eax
mov [ds:ebp+4],ecx
mov [ds:ebp+18h],edi
get_section_flags:
lods byte [esi]
cmp al,1Ah
je set_directory
cmp al,19h
je section_flag
dec esi
jmp instruction_assembled
set_directory:
movzx eax,byte [esi]
inc esi
mov ecx,ebx
test [format_flags],4
jnz peplus_directory
xchg ecx,[edx+78h+eax*8]
mov dword [edx+78h+eax*8+4],-1
jmp pe_directory_set
peplus_directory:
xchg ecx,[edx+88h+eax*8]
mov dword [edx+88h+eax*8+4],-1
pe_directory_set:
or ecx,ecx
jnz data_already_defined
push ebx edx
call generate_pe_data
pop edx ebx
jmp get_section_flags
section_flag:
lods byte [esi]
cmp al,9
je invalid_argument
cmp al,11
je invalid_argument
mov cl,al
mov eax,1
shl eax,cl
test dword [ebx+24h],eax
jnz setting_already_specified
or dword [ebx+24h],eax
jmp get_section_flags
close_pe_section:
mov ebx,[current_section]
mov edx,[code_start]
mov eax,edi
sub eax,[ebx+14h]
jnz finish_section
bt [format_flags],5
jc finish_section
mov eax,[ebx+0Ch]
ret
finish_section:
mov [ebx+8],eax
cmp edi,[undefined_data_end]
jne align_section
cmp dword [edx+38h],1000h
jb align_section
mov edi,[undefined_data_start]
align_section:
and [undefined_data_end],0
mov ebp,edi
sub ebp,[ebx+14h]
mov ecx,[edx+3Ch]
dec ecx
lea eax,[ebp+ecx]
not ecx
and eax,ecx
mov [ebx+10h],eax
sub eax,ebp
mov ecx,eax
xor al,al
rep stos byte [edi]
mov eax,[code_start]
sub eax,[stub_size]
sub [ebx+14h],eax
mov ecx,[ebx+10h]
test byte [ebx+24h],20h
jz pe_code_sum_ok
add [edx+1Ch],ecx
cmp dword [edx+2Ch],0
jne pe_code_sum_ok
mov eax,[ebx+0Ch]
mov [edx+2Ch],eax
pe_code_sum_ok:
test byte [ebx+24h],40h
jz pe_data_sum_ok
add [edx+20h],ecx
test [format_flags],4
jnz pe_data_sum_ok
cmp dword [edx+30h],0
jne pe_data_sum_ok
mov eax,[ebx+0Ch]
mov [edx+30h],eax
pe_data_sum_ok:
mov eax,[ebx+8]
or eax,eax
jz udata_ok
cmp dword [ebx+10h],0
jne udata_ok
or byte [ebx+24h],80h
add [edx+24h],ecx
udata_ok:
mov ecx,[edx+38h]
dec ecx
add eax,ecx
not ecx
and eax,ecx
add eax,[ebx+0Ch]
add ebx,28h
mov [current_section],ebx
inc word [number_of_sections]
jz format_limitations_exceeded
ret
data_directive:
cmp [output_format],3
jne illegal_instruction
lods byte [esi]
cmp al,1Ah
je predefined_data_type
cmp al,'('
jne invalid_argument
call get_byte_value
cmp al,16
jb data_type_ok
jmp invalid_value
predefined_data_type:
movzx eax,byte [esi]
inc esi
data_type_ok:
mov ebx,[current_section]
mov ecx,edi
sub ecx,[ebx+14h]
add ecx,[ebx+0Ch]
mov edx,[code_start]
test [format_flags],4
jnz peplus_data
xchg ecx,[edx+78h+eax*8]
jmp init_pe_data
peplus_data:
xchg ecx,[edx+88h+eax*8]
init_pe_data:
or ecx,ecx
jnz data_already_defined
call allocate_structure_data
mov word [ebx],data_directive-instruction_handler
mov [ebx+2],al
mov edx,[current_line]
mov [ebx+4],edx
call generate_pe_data
jmp instruction_assembled
end_data:
cmp [output_format],3
jne illegal_instruction
call find_structure_data
jc unexpected_instruction
movzx eax,byte [ebx+2]
mov edx,[current_section]
mov ecx,edi
sub ecx,[edx+14h]
add ecx,[edx+0Ch]
mov edx,[code_start]
test [format_flags],4
jnz end_peplus_data
sub ecx,[edx+78h+eax*8]
mov [edx+78h+eax*8+4],ecx
jmp remove_structure_data
end_peplus_data:
sub ecx,[edx+88h+eax*8]
mov [edx+88h+eax*8+4],ecx
jmp remove_structure_data
pe_entry:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
test [format_flags],8
jnz pe64_entry
call get_dword_value
mov bl,2
bt [resolver_flags],0
jc check_pe_entry_label_type
xor bl,bl
check_pe_entry_label_type:
cmp [value_type],bl
je pe_entry_ok
call recoverable_invalid_address
pe_entry_ok:
cdq
test [format_flags],4
jnz pe64_entry_type_ok
mov edx,[code_start]
sub eax,[edx+34h]
mov [edx+28h],eax
jmp instruction_assembled
pe64_entry:
call get_qword_value
mov bl,4
bt [resolver_flags],0
jc check_pe64_entry_label_type
xor bl,bl
check_pe64_entry_label_type:
cmp [value_type],bl
je pe64_entry_type_ok
call recoverable_invalid_address
pe64_entry_type_ok:
mov ecx,[code_start]
sub eax,[ecx+30h]
sbb edx,[ecx+34h]
jz pe64_entry_range_ok
call recoverable_overflow
pe64_entry_range_ok:
mov [ecx+28h],eax
jmp instruction_assembled
pe_stack:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
test [format_flags],4
jnz peplus_stack
call get_count_value
mov edx,[code_start]
mov [edx+60h],eax
cmp byte [esi],','
jne default_stack_commit
lods byte [esi]
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
mov edx,[code_start]
mov [edx+64h],eax
cmp eax,[edx+60h]
ja value_out_of_range
jmp instruction_assembled
default_stack_commit:
mov dword [edx+64h],1000h
mov eax,[edx+60h]
cmp eax,1000h
ja instruction_assembled
mov dword [edx+64h],eax
jmp instruction_assembled
peplus_stack:
call get_qword_value
cmp [value_type],0
jne invalid_use_of_symbol
mov ecx,[code_start]
mov [ecx+60h],eax
mov [ecx+64h],edx
cmp byte [esi],','
jne default_peplus_stack_commit
lods byte [esi]
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_qword_value
cmp [value_type],0
jne invalid_use_of_symbol
mov ecx,[code_start]
mov [ecx+68h],eax
mov [ecx+6Ch],edx
cmp edx,[ecx+64h]
ja value_out_of_range
jb instruction_assembled
cmp eax,[ecx+60h]
ja value_out_of_range
jmp instruction_assembled
default_peplus_stack_commit:
mov dword [ecx+68h],1000h
cmp dword [ecx+64h],0
jne instruction_assembled
mov eax,[ecx+60h]
cmp eax,1000h
ja instruction_assembled
mov dword [ecx+68h],eax
jmp instruction_assembled
pe_heap:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
test [format_flags],4
jnz peplus_heap
call get_count_value
mov edx,[code_start]
mov [edx+68h],eax
cmp byte [esi],','
jne instruction_assembled
lods byte [esi]
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_count_value
mov edx,[code_start]
mov [edx+6Ch],eax
cmp eax,[edx+68h]
ja value_out_of_range
jmp instruction_assembled
peplus_heap:
call get_qword_value
cmp [value_type],0
jne invalid_use_of_symbol
mov ecx,[code_start]
mov [ecx+70h],eax
mov [ecx+74h],edx
cmp byte [esi],','
jne instruction_assembled
lods byte [esi]
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_qword_value
cmp [value_type],0
jne invalid_use_of_symbol
mov ecx,[code_start]
mov [ecx+78h],eax
mov [ecx+7Ch],edx
cmp edx,[ecx+74h]
ja value_out_of_range
jb instruction_assembled
cmp eax,[ecx+70h]
ja value_out_of_range
jmp instruction_assembled
mark_pe_relocation:
push eax ebx
test [format_flags],4
jz check_standard_pe_relocation_type
cmp [value_type],4
je pe_relocation_type_ok
check_standard_pe_relocation_type:
cmp [value_type],2
je pe_relocation_type_ok
call recoverable_misuse
pe_relocation_type_ok:
mov ebx,[current_section]
mov eax,edi
sub eax,[ebx+14h]
add eax,[ebx+0Ch]
mov ebx,[free_additional_memory]
inc [number_of_relocations]
add ebx,5
cmp ebx,[structures_buffer]
jae out_of_memory
mov [free_additional_memory],ebx
mov [ebx-5],eax
cmp [value_type],2
je fixup_32bit
mov byte [ebx-1],0Ah
jmp fixup_ok
fixup_32bit:
mov byte [ebx-1],3
fixup_ok:
pop ebx eax
ret
generate_pe_data:
cmp al,2
je make_pe_resource
cmp al,5
je make_pe_fixups
ret
make_pe_fixups:
mov edx,[code_start]
and byte [edx+16h],not 1
or byte [edx+5Eh],40h
bts [resolver_flags],0
jc fixups_ready
or [next_pass_needed],-1
fixups_ready:
and [last_fixup_base],0
call make_fixups
xchg eax,[actual_fixups_size]
sub eax,[actual_fixups_size]
ja reserve_forward_fixups
xor eax,eax
reserve_forward_fixups:
mov [reserved_fixups],edi
add edi,eax
mov [reserved_fixups_size],eax
ret
make_fixups:
push esi
xor ecx,ecx
xchg ecx,[number_of_relocations]
mov esi,[free_additional_memory]
lea eax,[ecx*5]
sub esi,eax
mov [free_additional_memory],esi
mov edx,[last_fixup_base]
mov ebx,[last_fixup_header]
mov ebp,edi
jecxz fixups_done
make_fixup:
cmp [esi],edx
jb store_fixup
mov eax,edi
sub eax,ebp
test eax,11b
jz fixups_block
xor ax,ax
stos word [edi]
add dword [ebx],2
fixups_block:
mov eax,edx
add edx,1000h
cmp [esi],edx
jae fixups_block
stos dword [edi]
mov ebx,edi
mov eax,8
stos dword [edi]
store_fixup:
add dword [ebx],2
mov ah,[esi+1]
and ah,0Fh
mov al,[esi+4]
shl al,4
or ah,al
mov al,[esi]
stos word [edi]
add esi,5
loop make_fixup
fixups_done:
mov [last_fixup_base],edx
mov [last_fixup_header],ebx
pop esi
mov eax,edi
sub eax,ebp
ret
make_pe_resource:
cmp byte [esi],82h
jne resource_done
inc esi
lods word [esi]
cmp ax,'('
jne invalid_argument
lods dword [esi]
mov edx,esi
lea esi,[esi+eax+1]
cmp [next_pass_needed],0
je resource_from_file
cmp [current_pass],0
jne reserve_space_for_resource
and [resource_size],0
reserve_space_for_resource:
add edi,[resource_size]
cmp edi,[tagged_blocks]
ja out_of_memory
jmp resource_done
resource_from_file:
push esi
mov esi,edx
call open_binary_file
push ebx
mov esi,[free_additional_memory]
lea eax,[esi+20h]
cmp eax,[structures_buffer]
ja out_of_memory
mov edx,esi
mov ecx,20h
call read
jc invalid_file_format
xor eax,eax
cmp [esi],eax
jne invalid_file_format
mov ax,0FFFFh
cmp [esi+8],eax
jne invalid_file_format
cmp [esi+12],eax
jne invalid_file_format
mov eax,20h
cmp [esi+4],eax
jne invalid_file_format
read_resource_headers:
test eax,11b
jz resource_file_alignment_ok
mov edx,4
and eax,11b
sub edx,eax
mov al,1
call lseek
resource_file_alignment_ok:
mov [esi],eax
lea edx,[esi+12]
mov ecx,8
call read
jc resource_headers_ok
mov ecx,[esi+16]
add [esi],ecx
lea edx,[esi+20]
sub ecx,8
mov [esi+16],ecx
lea eax,[edx+ecx]
cmp eax,[structures_buffer]
ja out_of_memory
call read
jc invalid_file_format
mov edx,[esi]
add edx,[esi+12]
mov eax,[esi+16]
lea ecx,[esi+20]
lea esi,[ecx+eax]
add ecx,2
cmp word [ecx-2],0FFFFh
je resource_header_type_ok
check_resource_header_type:
cmp ecx,esi
jae invalid_file_format
cmp word [ecx],0
je resource_header_type_ok
add ecx,2
jmp check_resource_header_type
resource_header_type_ok:
add ecx,2
cmp word [ecx],0FFFFh
je resource_header_name_ok
check_resource_header_name:
cmp ecx,esi
jae invalid_file_format
cmp word [ecx],0
je resource_header_name_ok
add ecx,2
jmp check_resource_header_name
resource_header_name_ok:
xor al,al
call lseek
jmp read_resource_headers
resource_headers_ok:
xor eax,eax
mov [esi],eax
mov [resource_data],edi
lea eax,[edi+16]
cmp eax,[tagged_blocks]
jae out_of_memory
xor eax,eax
stos dword [edi]
call make_timestamp
stos dword [edi]
xor eax,eax
stos dword [edi]
stos dword [edi]
xor ebx,ebx
make_type_name_directory:
mov esi,[free_additional_memory]
xor edx,edx
find_type_name:
cmp dword [esi],0
je type_name_ok
add esi,20
cmp word [esi],0FFFFh
je check_next_type_name
or ebx,ebx
jz check_this_type_name
xor ecx,ecx
compare_with_previous_type_name:
mov ax,[esi+ecx]
cmp ax,[ebx+ecx]
ja check_this_type_name
jb check_next_type_name
add ecx,2
mov ax,[esi+ecx]
or ax,[ebx+ecx]
jnz compare_with_previous_type_name
jmp check_next_type_name
check_this_type_name:
or edx,edx
jz type_name_found
xor ecx,ecx
compare_with_current_type_name:
mov ax,[esi+ecx]
cmp ax,[edx+ecx]
ja check_next_type_name
jb type_name_found
add ecx,2
mov ax,[esi+ecx]
or ax,[edx+ecx]
jnz compare_with_current_type_name
jmp same_type_name
type_name_found:
mov edx,esi
same_type_name:
mov [esi-16],edi
check_next_type_name:
mov eax,[esi-4]
add esi,eax
jmp find_type_name
type_name_ok:
or edx,edx
jz type_name_directory_done
mov ebx,edx
make_type_name_entry:
mov eax,[resource_data]
inc word [eax+12]
lea eax,[edi+8]
cmp eax,[tagged_blocks]
jae out_of_memory
mov eax,ebx
stos dword [edi]
xor eax,eax
stos dword [edi]
jmp make_type_name_directory
type_name_directory_done:
mov ebx,-1
make_type_id_directory:
mov esi,[free_additional_memory]
mov edx,10000h
find_type_id:
cmp dword [esi],0
je type_id_ok
add esi,20
cmp word [esi],0FFFFh
jne check_next_type_id
movzx eax,word [esi+2]
cmp eax,ebx
jle check_next_type_id
cmp eax,edx
jg check_next_type_id
mov edx,eax
mov [esi-16],edi
check_next_type_id:
mov eax,[esi-4]
add esi,eax
jmp find_type_id
type_id_ok:
cmp edx,10000h
je type_id_directory_done
mov ebx,edx
make_type_id_entry:
mov eax,[resource_data]
inc word [eax+14]
lea eax,[edi+8]
cmp eax,[tagged_blocks]
jae out_of_memory
mov eax,ebx
stos dword [edi]
xor eax,eax
stos dword [edi]
jmp make_type_id_directory
type_id_directory_done:
mov esi,[resource_data]
add esi,10h
mov ecx,[esi-4]
or cx,cx
jz resource_directories_ok
make_resource_directories:
push ecx
push edi
mov edx,edi
sub edx,[resource_data]
bts edx,31
mov [esi+4],edx
lea eax,[edi+16]
cmp eax,[tagged_blocks]
jae out_of_memory
xor eax,eax
stos dword [edi]
call make_timestamp
stos dword [edi]
xor eax,eax
stos dword [edi]
stos dword [edi]
mov ebp,esi
xor ebx,ebx
make_resource_name_directory:
mov esi,[free_additional_memory]
xor edx,edx
find_resource_name:
cmp dword [esi],0
je resource_name_ok
push esi
cmp [esi+4],ebp
jne check_next_resource_name
add esi,20
call skip_resource_name
cmp word [esi],0FFFFh
je check_next_resource_name
or ebx,ebx
jz check_this_resource_name
xor ecx,ecx
compare_with_previous_resource_name:
mov ax,[esi+ecx]
cmp ax,[ebx+ecx]
ja check_this_resource_name
jb check_next_resource_name
add ecx,2
mov ax,[esi+ecx]
or ax,[ebx+ecx]
jnz compare_with_previous_resource_name
jmp check_next_resource_name
skip_resource_name:
cmp word [esi],0FFFFh
jne skip_unicode_string
add esi,4
ret
skip_unicode_string:
add esi,2
cmp word [esi-2],0
jne skip_unicode_string
ret
check_this_resource_name:
or edx,edx
jz resource_name_found
xor ecx,ecx
compare_with_current_resource_name:
mov ax,[esi+ecx]
cmp ax,[edx+ecx]
ja check_next_resource_name
jb resource_name_found
add ecx,2
mov ax,[esi+ecx]
or ax,[edx+ecx]
jnz compare_with_current_resource_name
jmp same_resource_name
resource_name_found:
mov edx,esi
same_resource_name:
mov eax,[esp]
mov [eax+8],edi
check_next_resource_name:
pop esi
mov eax,[esi+16]
lea esi,[esi+20+eax]
jmp find_resource_name
resource_name_ok:
or edx,edx
jz resource_name_directory_done
mov ebx,edx
make_resource_name_entry:
mov eax,[esp]
inc word [eax+12]
lea eax,[edi+8]
cmp eax,[tagged_blocks]
jae out_of_memory
mov eax,ebx
stos dword [edi]
xor eax,eax
stos dword [edi]
jmp make_resource_name_directory
resource_name_directory_done:
mov ebx,-1
make_resource_id_directory:
mov esi,[free_additional_memory]
mov edx,10000h
find_resource_id:
cmp dword [esi],0
je resource_id_ok
push esi
cmp [esi+4],ebp
jne check_next_resource_id
add esi,20
call skip_resource_name
cmp word [esi],0FFFFh
jne check_next_resource_id
movzx eax,word [esi+2]
cmp eax,ebx
jle check_next_resource_id
cmp eax,edx
jg check_next_resource_id
mov edx,eax
mov eax,[esp]
mov [eax+8],edi
check_next_resource_id:
pop esi
mov eax,[esi+16]
lea esi,[esi+20+eax]
jmp find_resource_id
resource_id_ok:
cmp edx,10000h
je resource_id_directory_done
mov ebx,edx
make_resource_id_entry:
mov eax,[esp]
inc word [eax+14]
lea eax,[edi+8]
cmp eax,[tagged_blocks]
jae out_of_memory
mov eax,ebx
stos dword [edi]
xor eax,eax
stos dword [edi]
jmp make_resource_id_directory
resource_id_directory_done:
pop eax
mov esi,ebp
pop ecx
add esi,8
dec cx
jnz make_resource_directories
resource_directories_ok:
shr ecx,16
jnz make_resource_directories
mov esi,[resource_data]
add esi,10h
movzx eax,word [esi-4]
movzx edx,word [esi-2]
add eax,edx
lea esi,[esi+eax*8]
push edi ; address of language directories
update_resource_directories:
cmp esi,[esp]
je resource_directories_updated
add esi,10h
mov ecx,[esi-4]
or cx,cx
jz language_directories_ok
make_language_directories:
push ecx
push edi
mov edx,edi
sub edx,[resource_data]
bts edx,31
mov [esi+4],edx
lea eax,[edi+16]
cmp eax,[tagged_blocks]
jae out_of_memory
xor eax,eax
stos dword [edi]
call make_timestamp
stos dword [edi]
xor eax,eax
stos dword [edi]
stos dword [edi]
mov ebp,esi
mov ebx,-1
make_language_id_directory:
mov esi,[free_additional_memory]
mov edx,10000h
find_language_id:
cmp dword [esi],0
je language_id_ok
push esi
cmp [esi+8],ebp
jne check_next_language_id
add esi,20
mov eax,esi
call skip_resource_name
call skip_resource_name
neg eax
add eax,esi
and eax,11b
add esi,eax
get_language_id:
movzx eax,word [esi+6]
cmp eax,ebx
jle check_next_language_id
cmp eax,edx
jge check_next_language_id
mov edx,eax
mov eax,[esp]
mov dword [value],eax
check_next_language_id:
pop esi
mov eax,[esi+16]
lea esi,[esi+20+eax]
jmp find_language_id
language_id_ok:
cmp edx,10000h
je language_id_directory_done
mov ebx,edx
make_language_id_entry:
mov eax,[esp]
inc word [eax+14]
lea eax,[edi+8]
cmp eax,[tagged_blocks]
jae out_of_memory
mov eax,ebx
stos dword [edi]
mov eax,dword [value]
stos dword [edi]
jmp make_language_id_directory
language_id_directory_done:
pop eax
mov esi,ebp
pop ecx
add esi,8
dec cx
jnz make_language_directories
language_directories_ok:
shr ecx,16
jnz make_language_directories
jmp update_resource_directories
resource_directories_updated:
mov esi,[resource_data]
push edi
make_name_strings:
add esi,10h
movzx eax,word [esi-2]
movzx ecx,word [esi-4]
add eax,ecx
lea eax,[esi+eax*8]
push eax
or ecx,ecx
jz string_entries_processed
process_string_entries:
push ecx
mov edx,edi
sub edx,[resource_data]
bts edx,31
xchg [esi],edx
mov ebx,edi
xor ax,ax
stos word [edi]
copy_string_data:
lea eax,[edi+2]
cmp eax,[tagged_blocks]
jae out_of_memory
mov ax,[edx]
or ax,ax
jz string_data_copied
stos word [edi]
inc word [ebx]
add edx,2
jmp copy_string_data
string_data_copied:
add esi,8
pop ecx
loop process_string_entries
string_entries_processed:
pop esi
cmp esi,[esp]
jb make_name_strings
mov eax,edi
sub eax,[resource_data]
test al,11b
jz resource_strings_alignment_ok
xor ax,ax
stos word [edi]
resource_strings_alignment_ok:
pop edx
pop ebx ; address of language directories
mov ebp,edi
update_language_directories:
add ebx,10h
movzx eax,word [ebx-2]
movzx ecx,word [ebx-4]
add ecx,eax
make_data_records:
push ecx
mov esi,edi
sub esi,[resource_data]
xchg esi,[ebx+4]
lea eax,[edi+16]
cmp eax,[tagged_blocks]
jae out_of_memory
mov eax,esi
stos dword [edi]
mov eax,[esi+12]
stos dword [edi]
xor eax,eax
stos dword [edi]
stos dword [edi]
pop ecx
add ebx,8
loop make_data_records
cmp ebx,edx
jb update_language_directories
pop ebx ; file handle
mov esi,ebp
mov ebp,edi
update_data_records:
push ebp
mov ecx,edi
mov eax,[current_section]
sub ecx,[eax+14h]
add ecx,[eax+0Ch]
xchg ecx,[esi]
mov edx,[ecx]
xor al,al
call lseek
mov edx,edi
mov ecx,[esi+4]
add edi,ecx
cmp edi,[tagged_blocks]
ja out_of_memory
call read
mov eax,edi
sub eax,[resource_data]
and eax,11b
jz resource_data_alignment_ok
mov ecx,4
sub ecx,eax
xor al,al
rep stos byte [edi]
resource_data_alignment_ok:
pop ebp
add esi,16
cmp esi,ebp
jb update_data_records
pop esi
call close
mov eax,edi
sub eax,[resource_data]
mov [resource_size],eax
resource_done:
ret
close_pe:
call close_pe_section
mov edx,[code_start]
mov [edx+50h],eax
call make_timestamp
mov edx,[code_start]
mov [edx+8],eax
mov eax,[number_of_sections]
mov [edx+6],ax
imul eax,28h
movzx ecx,word [edx+14h]
lea eax,[eax+18h+ecx]
add eax,[stub_size]
mov ecx,[edx+3Ch]
dec ecx
add eax,ecx
not ecx
and eax,ecx
cmp eax,[edx+54h]
je pe_sections_ok
or [next_pass_needed],-1
pe_sections_ok:
xor ecx,ecx
add edx,78h
test [format_flags],4
jz process_directories
add edx,10h
process_directories:
mov eax,[edx+ecx*8]
or eax,eax
jz directory_ok
cmp dword [edx+ecx*8+4],-1
jne directory_ok
section_data:
mov ebx,[edx+ecx*8]
mov eax,[ebx+0Ch]
mov [edx+ecx*8],eax ; directory rva
mov eax,[ebx+8]
mov [edx+ecx*8+4],eax ; directory size
directory_ok:
inc cl
cmp cl,10h
jb process_directories
cmp dword [edx+5*8],0
jne finish_pe_relocations
mov eax,[number_of_relocations]
shl eax,2
sub [free_additional_memory],eax
btr [resolver_flags],0
jnc pe_relocations_ok
or [next_pass_needed],-1
jmp pe_relocations_ok
finish_pe_relocations:
push edi
mov edi,[reserved_fixups]
call make_fixups
pop edi
add [actual_fixups_size],eax
cmp eax,[reserved_fixups_size]
je pe_relocations_ok
or [next_pass_needed],-1
pe_relocations_ok:
mov ebx,[code_start]
sub ebx,[stub_size]
mov ecx,edi
sub ecx,ebx
mov ebp,ecx
shr ecx,1
xor eax,eax
cdq
calculate_checksum:
mov dx,[ebx]
add eax,edx
mov dx,ax
shr eax,16
add eax,edx
add ebx,2
loop calculate_checksum
add eax,ebp
mov ebx,[code_start]
mov [ebx+58h],eax
ret
 
format_coff:
mov eax,[additional_memory]
mov [symbols_stream],eax
mov ebx,eax
add eax,20h
cmp eax,[structures_buffer]
jae out_of_memory
mov [free_additional_memory],eax
xor eax,eax
mov [ebx],al
mov [ebx+4],eax
mov [ebx+8],edi
mov al,4
mov [ebx+10h],eax
mov al,60h
bt [format_flags],0
jnc flat_section_flags_ok
or eax,0E0000000h
flat_section_flags_ok:
mov dword [ebx+14h],eax
mov [current_section],ebx
xor eax,eax
mov [number_of_sections],eax
mov edx,ebx
call init_addressing_space
mov [ebx+14h],edx
mov byte [ebx+9],2
mov [code_type],32
test [format_flags],8
jz format_defined
mov byte [ebx+9],4
mov [code_type],64
jmp format_defined
coff_section:
call close_coff_section
mov ebx,[free_additional_memory]
lea eax,[ebx+20h]
cmp eax,[structures_buffer]
jae out_of_memory
mov [free_additional_memory],eax
mov [current_section],ebx
inc [number_of_sections]
xor eax,eax
mov [ebx],al
mov [ebx+8],edi
mov [ebx+10h],eax
mov [ebx+14h],eax
mov edx,ebx
call create_addressing_space
xchg edx,ebx
mov [edx+14h],ebx
mov byte [edx+9],2
test [format_flags],8
jz coff_labels_type_ok
mov byte [edx+9],4
coff_labels_type_ok:
lods word [esi]
cmp ax,'('
jne invalid_argument
mov [ebx+4],esi
mov ecx,[esi]
lea esi,[esi+4+ecx+1]
cmp ecx,8
ja name_too_long
coff_section_flags:
cmp byte [esi],8Ch
je coff_section_alignment
cmp byte [esi],19h
jne coff_section_settings_ok
inc esi
lods byte [esi]
bt [format_flags],0
jc coff_section_flag_ok
cmp al,7
ja invalid_argument
coff_section_flag_ok:
mov cl,al
mov eax,1
shl eax,cl
test dword [ebx+14h],eax
jnz setting_already_specified
or dword [ebx+14h],eax
jmp coff_section_flags
coff_section_alignment:
bt [format_flags],0
jnc invalid_argument
inc esi
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
push ebx
call get_count_value
pop ebx
mov edx,eax
dec edx
test eax,edx
jnz invalid_value
or eax,eax
jz invalid_value
cmp eax,2000h
ja invalid_value
bsf edx,eax
inc edx
shl edx,20
or [ebx+14h],edx
xchg [ebx+10h],eax
or eax,eax
jnz setting_already_specified
jmp coff_section_flags
coff_section_settings_ok:
cmp dword [ebx+10h],0
jne instruction_assembled
mov dword [ebx+10h],4
bt [format_flags],0
jnc instruction_assembled
or dword [ebx+14h],300000h
jmp instruction_assembled
close_coff_section:
mov ebx,[current_section]
mov eax,edi
mov edx,[ebx+8]
sub eax,edx
mov [ebx+0Ch],eax
xor eax,eax
xchg [undefined_data_end],eax
cmp eax,edi
jne coff_section_ok
cmp edx,[undefined_data_start]
jne coff_section_ok
mov edi,edx
or byte [ebx+14h],80h
coff_section_ok:
ret
mark_coff_relocation:
cmp [value_type],3
je coff_relocation_relative
push ebx eax
test [format_flags],8
jnz coff_64bit_relocation
mov al,6
cmp [value_type],2
je coff_relocation
cmp [value_type],5
jne invalid_use_of_symbol
inc al
jmp coff_relocation
coff_64bit_relocation:
mov al,1
cmp [value_type],4
je coff_relocation
mov al,2
cmp [value_type],2
je coff_relocation
cmp [value_type],5
jne invalid_use_of_symbol
inc al
jmp coff_relocation
coff_relocation_relative:
push ebx
bt [format_flags],0
jnc relative_ok
mov ebx,[current_section]
mov ebx,[ebx+8]
sub ebx,edi
sub eax,ebx
add eax,4
relative_ok:
mov ebx,[addressing_space]
push eax
mov al,20
test [format_flags],8
jnz relative_coff_64bit_relocation
cmp byte [ebx+9],2
jne invalid_use_of_symbol
jmp coff_relocation
relative_coff_64bit_relocation:
mov al,4
cmp byte [ebx+9],4
jne invalid_use_of_symbol
coff_relocation:
mov ebx,[free_additional_memory]
add ebx,0Ch
cmp ebx,[structures_buffer]
jae out_of_memory
mov [free_additional_memory],ebx
mov byte [ebx-0Ch],al
mov eax,[current_section]
mov eax,[eax+8]
neg eax
add eax,edi
mov [ebx-0Ch+4],eax
mov eax,[symbol_identifier]
mov [ebx-0Ch+8],eax
pop eax ebx
ret
close_coff:
call close_coff_section
cmp [next_pass_needed],0
je coff_closed
mov eax,[symbols_stream]
mov [free_additional_memory],eax
coff_closed:
ret
coff_formatter:
sub edi,[code_start]
mov [code_size],edi
call prepare_default_section
mov edi,[free_additional_memory]
mov ebx,edi
mov ecx,28h shr 2
imul ecx,[number_of_sections]
add ecx,14h shr 2
lea eax,[edi+ecx*4]
cmp eax,[structures_buffer]
jae out_of_memory
xor eax,eax
rep stos dword [edi]
mov word [ebx],14Ch
test [format_flags],8
jz coff_magic_ok
mov word [ebx],8664h
coff_magic_ok:
mov word [ebx+12h],104h
bt [format_flags],0
jnc coff_flags_ok
or byte [ebx+12h],80h
coff_flags_ok:
push ebx
call make_timestamp
pop ebx
mov [ebx+4],eax
mov eax,[number_of_sections]
mov [ebx+2],ax
mov esi,[symbols_stream]
xor eax,eax
xor ecx,ecx
enumerate_symbols:
cmp esi,[free_additional_memory]
je symbols_enumerated
mov dl,[esi]
or dl,dl
jz enumerate_section
cmp dl,0C0h
jae enumerate_public
cmp dl,80h
jae enumerate_extrn
add esi,0Ch
jmp enumerate_symbols
enumerate_section:
mov edx,eax
shl edx,8
mov [esi],edx
inc eax
inc ecx
mov [esi+1Eh],cx
add esi,20h
jmp enumerate_symbols
enumerate_public:
mov edx,eax
shl edx,8
mov dl,[esi]
mov [esi],edx
mov edx,[esi+8]
add esi,10h
inc eax
cmp byte [edx+11],0
je enumerate_symbols
mov edx,[edx+20]
cmp byte [edx],0C0h
jae enumerate_symbols
cmp byte [edx],80h
jb enumerate_symbols
inc eax
jmp enumerate_symbols
enumerate_extrn:
mov edx,eax
shl edx,8
mov dl,[esi]
mov [esi],edx
add esi,0Ch
inc eax
jmp enumerate_symbols
prepare_default_section:
mov ebx,[symbols_stream]
cmp dword [ebx+0Ch],0
jne default_section_ok
cmp [number_of_sections],0
je default_section_ok
mov edx,ebx
find_references_to_default_section:
cmp ebx,[free_additional_memory]
jne check_reference
add [symbols_stream],20h
ret
check_reference:
mov al,[ebx]
or al,al
jz skip_other_section
cmp al,0C0h
jae check_public_reference
cmp al,80h
jae next_reference
cmp edx,[ebx+8]
je default_section_ok
next_reference:
add ebx,0Ch
jmp find_references_to_default_section
check_public_reference:
mov eax,[ebx+8]
add ebx,10h
test byte [eax+8],1
jz find_references_to_default_section
mov cx,[current_pass]
cmp cx,[eax+16]
jne find_references_to_default_section
cmp edx,[eax+20]
je default_section_ok
jmp find_references_to_default_section
skip_other_section:
add ebx,20h
jmp find_references_to_default_section
default_section_ok:
inc [number_of_sections]
ret
symbols_enumerated:
mov [ebx+0Ch],eax
mov ebp,edi
sub ebp,ebx
push ebp
lea edi,[ebx+14h]
mov esi,[symbols_stream]
find_section:
cmp esi,[free_additional_memory]
je sections_finished
mov al,[esi]
or al,al
jz section_found
add esi,0Ch
cmp al,0C0h
jb find_section
add esi,4
jmp find_section
section_found:
push esi edi
mov esi,[esi+4]
or esi,esi
jz default_section
mov ecx,[esi]
add esi,4
rep movs byte [edi],[esi]
jmp section_name_ok
default_section:
mov al,'.'
stos byte [edi]
mov eax,'flat'
stos dword [edi]
section_name_ok:
pop edi esi
mov eax,[esi+0Ch]
mov [edi+10h],eax
mov eax,[esi+14h]
mov [edi+24h],eax
test al,80h
jnz section_ptr_ok
mov eax,[esi+8]
sub eax,[code_start]
add eax,ebp
mov [edi+14h],eax
section_ptr_ok:
mov ebx,[code_start]
mov edx,[code_size]
add ebx,edx
add edx,ebp
xor ecx,ecx
add esi,20h
find_relocations:
cmp esi,[free_additional_memory]
je section_relocations_done
mov al,[esi]
or al,al
jz section_relocations_done
cmp al,80h
jb add_relocation
cmp al,0C0h
jb next_relocation
add esi,10h
jmp find_relocations
add_relocation:
lea eax,[ebx+0Ah]
cmp eax,[tagged_blocks]
ja out_of_memory
mov eax,[esi+4]
mov [ebx],eax
mov eax,[esi+8]
mov eax,[eax]
shr eax,8
mov [ebx+4],eax
movzx ax,byte [esi]
mov [ebx+8],ax
add ebx,0Ah
inc ecx
next_relocation:
add esi,0Ch
jmp find_relocations
section_relocations_done:
cmp ecx,10000h
jb section_relocations_count_16bit
bt [format_flags],0
jnc format_limitations_exceeded
mov word [edi+20h],0FFFFh
or dword [edi+24h],1000000h
mov [edi+18h],edx
push esi edi
push ecx
lea esi,[ebx-1]
add ebx,0Ah
lea edi,[ebx-1]
imul ecx,0Ah
std
rep movs byte [edi],[esi]
cld
pop ecx
inc esi
inc ecx
mov [esi],ecx
xor eax,eax
mov [esi+4],eax
mov [esi+8],ax
pop edi esi
jmp section_relocations_ok
section_relocations_count_16bit:
mov [edi+20h],cx
jcxz section_relocations_ok
mov [edi+18h],edx
section_relocations_ok:
sub ebx,[code_start]
mov [code_size],ebx
add edi,28h
jmp find_section
sections_finished:
mov edx,[free_additional_memory]
mov ebx,[code_size]
add ebp,ebx
mov [edx+8],ebp
add ebx,[code_start]
mov edi,ebx
mov ecx,[edx+0Ch]
imul ecx,12h shr 1
xor eax,eax
shr ecx,1
jnc zero_symbols_table
stos word [edi]
zero_symbols_table:
rep stos dword [edi]
mov edx,edi
stos dword [edi]
mov esi,[symbols_stream]
make_symbols_table:
cmp esi,[free_additional_memory]
je symbols_table_ok
mov al,[esi]
cmp al,0C0h
jae add_public_symbol
cmp al,80h
jae add_extrn_symbol
or al,al
jz add_section_symbol
add esi,0Ch
jmp make_symbols_table
add_section_symbol:
call store_symbol_name
movzx eax,word [esi+1Eh]
mov [ebx+0Ch],ax
mov byte [ebx+10h],3
add esi,20h
add ebx,12h
jmp make_symbols_table
add_extrn_symbol:
call store_symbol_name
mov byte [ebx+10h],2
add esi,0Ch
add ebx,12h
jmp make_symbols_table
add_public_symbol:
call store_symbol_name
mov eax,[esi+0Ch]
mov [current_line],eax
mov eax,[esi+8]
test byte [eax+8],1
jz undefined_coff_public
mov cx,[current_pass]
cmp cx,[eax+16]
jne undefined_coff_public
mov cl,[eax+11]
or cl,cl
jz public_constant
test [format_flags],8
jnz check_64bit_public_symbol
cmp cl,2
je public_symbol_type_ok
jmp invalid_use_of_symbol
undefined_coff_public:
mov [error_info],eax
jmp undefined_symbol
check_64bit_public_symbol:
cmp cl,4
jne invalid_use_of_symbol
public_symbol_type_ok:
mov ecx,[eax+20]
cmp byte [ecx],80h
je alias_symbol
cmp byte [ecx],0
jne invalid_use_of_symbol
mov cx,[ecx+1Eh]
mov [ebx+0Ch],cx
public_symbol_section_ok:
movzx ecx,byte [eax+9]
shr cl,1
and cl,1
neg ecx
cmp ecx,[eax+4]
jne value_out_of_range
xor ecx,[eax]
js value_out_of_range
mov eax,[eax]
mov [ebx+8],eax
mov al,2
cmp byte [esi],0C0h
je store_symbol_class
inc al
cmp byte [esi],0C1h
je store_symbol_class
mov al,105
store_symbol_class:
mov byte [ebx+10h],al
add esi,10h
add ebx,12h
jmp make_symbols_table
alias_symbol:
bt [format_flags],0
jnc invalid_use_of_symbol
mov ecx,[eax]
or ecx,[eax+4]
jnz invalid_use_of_symbol
mov byte [ebx+10h],69h
mov byte [ebx+11h],1
add ebx,12h
mov ecx,[eax+20]
mov ecx,[ecx]
shr ecx,8
mov [ebx],ecx
mov byte [ebx+4],3
add esi,10h
add ebx,12h
jmp make_symbols_table
public_constant:
mov word [ebx+0Ch],0FFFFh
jmp public_symbol_section_ok
symbols_table_ok:
mov eax,edi
sub eax,edx
mov [edx],eax
sub edi,[code_start]
mov [code_size],edi
and [written_size],0
mov edx,[output_file]
call create
jc write_failed
mov edx,[free_additional_memory]
pop ecx
add [written_size],ecx
call write
jc write_failed
jmp write_output
store_symbol_name:
push esi
mov esi,[esi+4]
or esi,esi
jz default_name
lods dword [esi]
mov ecx,eax
cmp ecx,8
ja add_string
push edi
mov edi,ebx
rep movs byte [edi],[esi]
pop edi esi
ret
default_name:
mov dword [ebx],'.fla'
mov dword [ebx+4],'t'
pop esi
ret
add_string:
mov eax,edi
sub eax,edx
mov [ebx+4],eax
inc ecx
rep movs byte [edi],[esi]
pop esi
ret
 
format_elf:
test [format_flags],8
jnz format_elf64
mov edx,edi
mov ecx,34h shr 2
lea eax,[edi+ecx*4]
cmp eax,[tagged_blocks]
jae out_of_memory
xor eax,eax
rep stos dword [edi]
mov dword [edx],7Fh + 'ELF' shl 8
mov al,1
mov [edx+4],al
mov [edx+5],al
mov [edx+6],al
mov [edx+14h],al
mov byte [edx+12h],3
mov byte [edx+28h],34h
mov byte [edx+2Eh],28h
mov [code_type],32
cmp word [esi],1D19h
je format_elf_exe
elf_header_ok:
mov byte [edx+10h],1
mov eax,[additional_memory]
mov [symbols_stream],eax
mov ebx,eax
add eax,20h
cmp eax,[structures_buffer]
jae out_of_memory
mov [free_additional_memory],eax
xor eax,eax
mov [current_section],ebx
mov [number_of_sections],eax
mov [ebx],al
mov [ebx+4],eax
mov [ebx+8],edi
mov al,111b
mov [ebx+14h],eax
mov al,4
mov [ebx+10h],eax
mov edx,ebx
call init_addressing_space
xchg edx,ebx
mov [edx+14h],ebx
mov byte [edx+9],2
test [format_flags],8
jz format_defined
mov byte [edx+9],4
mov byte [ebx+10h],8
jmp format_defined
format_elf64:
mov edx,edi
mov ecx,40h shr 2
lea eax,[edi+ecx*4]
cmp eax,[tagged_blocks]
jae out_of_memory
xor eax,eax
rep stos dword [edi]
mov dword [edx],7Fh + 'ELF' shl 8
mov al,1
mov [edx+5],al
mov [edx+6],al
mov [edx+14h],al
mov byte [edx+4],2
mov byte [edx+12h],62
mov byte [edx+34h],40h
mov byte [edx+3Ah],40h
mov [code_type],64
cmp word [esi],1D19h
jne elf_header_ok
jmp format_elf64_exe
elf_section:
bt [format_flags],0
jc illegal_instruction
call close_coff_section
mov ebx,[free_additional_memory]
lea eax,[ebx+20h]
cmp eax,[structures_buffer]
jae out_of_memory
mov [free_additional_memory],eax
mov [current_section],ebx
inc word [number_of_sections]
jz format_limitations_exceeded
xor eax,eax
mov [ebx],al
mov [ebx+8],edi
mov [ebx+10h],eax
mov al,10b
mov [ebx+14h],eax
mov edx,ebx
call create_addressing_space
xchg edx,ebx
mov [edx+14h],ebx
mov byte [edx+9],2
test [format_flags],8
jz elf_labels_type_ok
mov byte [edx+9],4
elf_labels_type_ok:
lods word [esi]
cmp ax,'('
jne invalid_argument
mov [ebx+4],esi
mov ecx,[esi]
lea esi,[esi+4+ecx+1]
elf_section_flags:
cmp byte [esi],8Ch
je elf_section_alignment
cmp byte [esi],19h
jne elf_section_settings_ok
inc esi
lods byte [esi]
sub al,28
xor al,11b
test al,not 10b
jnz invalid_argument
mov cl,al
mov al,1
shl al,cl
test byte [ebx+14h],al
jnz setting_already_specified
or byte [ebx+14h],al
jmp elf_section_flags
elf_section_alignment:
inc esi
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
push ebx
call get_count_value
pop ebx
mov edx,eax
dec edx
test eax,edx
jnz invalid_value
or eax,eax
jz invalid_value
xchg [ebx+10h],eax
or eax,eax
jnz setting_already_specified
jmp elf_section_flags
elf_section_settings_ok:
cmp dword [ebx+10h],0
jne instruction_assembled
mov dword [ebx+10h],4
test [format_flags],8
jz instruction_assembled
mov byte [ebx+10h],8
jmp instruction_assembled
mark_elf_relocation:
push ebx
mov ebx,[addressing_space]
cmp [value_type],3
je elf_relocation_relative
cmp [value_type],7
je elf_relocation_relative
push eax
cmp [value_type],5
je elf_gotoff_relocation
ja invalid_use_of_symbol
mov al,1 ; R_386_32 / R_AMD64_64
test [format_flags],8
jz coff_relocation
cmp [value_type],4
je coff_relocation
mov al,11 ; R_AMD64_32S
jmp coff_relocation
elf_gotoff_relocation:
test [format_flags],8
jnz invalid_use_of_symbol
mov al,9 ; R_386_GOTOFF
jmp coff_relocation
elf_relocation_relative:
cmp byte [ebx+9],0
je invalid_use_of_symbol
mov ebx,[current_section]
mov ebx,[ebx+8]
sub ebx,edi
sub eax,ebx
push eax
mov al,2 ; R_386_PC32 / R_AMD64_PC32
cmp [value_type],3
je coff_relocation
mov al,4 ; R_386_PLT32 / R_AMD64_PLT32
jmp coff_relocation
close_elf:
bt [format_flags],0
jc close_elf_exe
call close_coff_section
cmp [next_pass_needed],0
je elf_closed
mov eax,[symbols_stream]
mov [free_additional_memory],eax
elf_closed:
ret
elf_formatter:
push edi
call prepare_default_section
mov esi,[symbols_stream]
mov edi,[free_additional_memory]
xor eax,eax
mov ecx,4
rep stos dword [edi]
test [format_flags],8
jz find_first_section
mov ecx,2
rep stos dword [edi]
find_first_section:
mov al,[esi]
or al,al
jz first_section_found
cmp al,0C0h
jb skip_other_symbol
add esi,4
skip_other_symbol:
add esi,0Ch
jmp find_first_section
first_section_found:
mov ebx,esi
mov ebp,esi
add esi,20h
xor ecx,ecx
xor edx,edx
find_next_section:
cmp esi,[free_additional_memory]
je make_section_symbol
mov al,[esi]
or al,al
jz make_section_symbol
cmp al,0C0h
jae skip_public
cmp al,80h
jae skip_extrn
or byte [ebx+14h],40h
skip_extrn:
add esi,0Ch
jmp find_next_section
skip_public:
add esi,10h
jmp find_next_section
make_section_symbol:
mov eax,edi
xchg eax,[ebx+4]
stos dword [edi]
test [format_flags],8
jnz elf64_section_symbol
xor eax,eax
stos dword [edi]
stos dword [edi]
call store_section_index
jmp section_symbol_ok
store_section_index:
inc ecx
mov eax,ecx
shl eax,8
mov [ebx],eax
inc dx
jz format_limitations_exceeded
mov eax,edx
shl eax,16
mov al,3
test byte [ebx+14h],40h
jz section_index_ok
or ah,-1
inc dx
jz format_limitations_exceeded
section_index_ok:
stos dword [edi]
ret
elf64_section_symbol:
call store_section_index
xor eax,eax
stos dword [edi]
stos dword [edi]
stos dword [edi]
stos dword [edi]
section_symbol_ok:
mov ebx,esi
add esi,20h
cmp ebx,[free_additional_memory]
jne find_next_section
inc dx
jz format_limitations_exceeded
mov [current_section],edx
mov esi,[symbols_stream]
find_other_symbols:
cmp esi,[free_additional_memory]
je elf_symbol_table_ok
mov al,[esi]
or al,al
jz skip_section
cmp al,0C0h
jae make_public_symbol
cmp al,80h
jae make_extrn_symbol
add esi,0Ch
jmp find_other_symbols
skip_section:
add esi,20h
jmp find_other_symbols
make_public_symbol:
mov eax,[esi+0Ch]
mov [current_line],eax
cmp byte [esi],0C0h
jne invalid_argument
mov ebx,[esi+8]
test byte [ebx+8],1
jz undefined_public
mov ax,[current_pass]
cmp ax,[ebx+16]
jne undefined_public
mov dl,[ebx+11]
or dl,dl
jz public_absolute
mov eax,[ebx+20]
cmp byte [eax],0
jne invalid_use_of_symbol
mov eax,[eax+4]
test [format_flags],8
jnz elf64_public
cmp dl,2
jne invalid_use_of_symbol
mov dx,[eax+0Eh]
jmp section_for_public_ok
undefined_public:
mov [error_info],ebx
jmp undefined_symbol
elf64_public:
cmp dl,4
jne invalid_use_of_symbol
mov dx,[eax+6]
jmp section_for_public_ok
public_absolute:
mov dx,0FFF1h
section_for_public_ok:
mov eax,[esi+4]
stos dword [edi]
test [format_flags],8
jnz elf64_public_symbol
movzx eax,byte [ebx+9]
shr al,1
and al,1
neg eax
cmp eax,[ebx+4]
jne value_out_of_range
xor eax,[ebx]
js value_out_of_range
mov eax,[ebx]
stos dword [edi]
xor eax,eax
mov al,[ebx+10]
stos dword [edi]
mov eax,edx
shl eax,16
mov al,10h
cmp byte [ebx+10],0
je elf_public_function
or al,1
jmp store_elf_public_info
elf_public_function:
or al,2
store_elf_public_info:
stos dword [edi]
jmp public_symbol_ok
elf64_public_symbol:
mov eax,edx
shl eax,16
mov al,10h
cmp byte [ebx+10],0
je elf64_public_function
or al,1
jmp store_elf64_public_info
elf64_public_function:
or al,2
store_elf64_public_info:
stos dword [edi]
mov al,[ebx+9]
shl eax,31-1
xor eax,[ebx+4]
js value_out_of_range
mov eax,[ebx]
stos dword [edi]
mov eax,[ebx+4]
stos dword [edi]
mov al,[ebx+10]
stos dword [edi]
xor al,al
stos dword [edi]
public_symbol_ok:
inc ecx
mov eax,ecx
shl eax,8
mov al,0C0h
mov [esi],eax
add esi,10h
jmp find_other_symbols
make_extrn_symbol:
mov eax,[esi+4]
stos dword [edi]
test [format_flags],8
jnz elf64_extrn_symbol
xor eax,eax
stos dword [edi]
mov eax,[esi+8]
stos dword [edi]
mov eax,10h
stos dword [edi]
jmp extrn_symbol_ok
elf64_extrn_symbol:
mov eax,10h
stos dword [edi]
xor al,al
stos dword [edi]
stos dword [edi]
mov eax,[esi+8]
stos dword [edi]
xor eax,eax
stos dword [edi]
extrn_symbol_ok:
inc ecx
mov eax,ecx
shl eax,8
mov al,80h
mov [esi],eax
add esi,0Ch
jmp find_other_symbols
elf_symbol_table_ok:
mov edx,edi
mov ebx,[free_additional_memory]
xor al,al
stos byte [edi]
add edi,16
mov [edx+1],edx
add ebx,10h
test [format_flags],8
jz make_string_table
add ebx,8
make_string_table:
cmp ebx,edx
je elf_string_table_ok
test [format_flags],8
jnz make_elf64_string
cmp byte [ebx+0Dh],0
je rel_prefix_ok
mov byte [ebx+0Dh],0
mov eax,'.rel'
stos dword [edi]
rel_prefix_ok:
mov esi,edi
sub esi,edx
xchg esi,[ebx]
add ebx,10h
make_elf_string:
or esi,esi
jz default_string
lods dword [esi]
mov ecx,eax
rep movs byte [edi],[esi]
xor al,al
stos byte [edi]
jmp make_string_table
make_elf64_string:
cmp byte [ebx+5],0
je elf64_rel_prefix_ok
mov byte [ebx+5],0
mov eax,'.rel'
stos dword [edi]
mov al,'a'
stos byte [edi]
elf64_rel_prefix_ok:
mov esi,edi
sub esi,edx
xchg esi,[ebx]
add ebx,18h
jmp make_elf_string
default_string:
mov eax,'.fla'
stos dword [edi]
mov ax,'t'
stos word [edi]
jmp make_string_table
elf_string_table_ok:
mov [edx+1+8],edi
mov ebx,[code_start]
mov eax,edi
sub eax,[free_additional_memory]
test [format_flags],8
jnz finish_elf64_header
mov [ebx+20h],eax
mov eax,[current_section]
inc ax
jz format_limitations_exceeded
mov [ebx+32h],ax
inc ax
jz format_limitations_exceeded
mov [ebx+30h],ax
jmp elf_header_finished
finish_elf64_header:
mov [ebx+28h],eax
mov eax,[current_section]
inc ax
jz format_limitations_exceeded
mov [ebx+3Eh],ax
inc ax
jz format_limitations_exceeded
mov [ebx+3Ch],ax
elf_header_finished:
xor eax,eax
mov ecx,10
rep stos dword [edi]
test [format_flags],8
jz elf_null_section_ok
mov ecx,6
rep stos dword [edi]
elf_null_section_ok:
mov esi,ebp
xor ecx,ecx
make_section_entry:
mov ebx,edi
mov eax,[esi+4]
mov eax,[eax]
stos dword [edi]
mov eax,1
cmp dword [esi+0Ch],0
je bss_section
test byte [esi+14h],80h
jz section_type_ok
bss_section:
mov al,8
section_type_ok:
stos dword [edi]
mov eax,[esi+14h]
and al,3Fh
call store_elf_machine_word
xor eax,eax
call store_elf_machine_word
mov eax,[esi+8]
mov [image_base],eax
sub eax,[code_start]
call store_elf_machine_word
mov eax,[esi+0Ch]
call store_elf_machine_word
xor eax,eax
stos dword [edi]
stos dword [edi]
mov eax,[esi+10h]
call store_elf_machine_word
xor eax,eax
call store_elf_machine_word
inc ecx
add esi,20h
xchg edi,[esp]
mov ebp,edi
convert_relocations:
cmp esi,[free_additional_memory]
je relocations_converted
mov al,[esi]
or al,al
jz relocations_converted
cmp al,80h
jb make_relocation_entry
cmp al,0C0h
jb relocation_entry_ok
add esi,10h
jmp convert_relocations
make_relocation_entry:
test [format_flags],8
jnz make_elf64_relocation_entry
mov eax,[esi+4]
stos dword [edi]
mov eax,[esi+8]
mov eax,[eax]
mov al,[esi]
stos dword [edi]
jmp relocation_entry_ok
make_elf64_relocation_entry:
mov eax,[esi+4]
stos dword [edi]
xor eax,eax
stos dword [edi]
movzx eax,byte [esi]
stos dword [edi]
mov eax,[esi+8]
mov eax,[eax]
shr eax,8
stos dword [edi]
xor eax,eax
push edx
mov edx,[esi+4]
add edx,[image_base]
xchg eax,[edx]
stos dword [edi]
cmp byte [esi],1
je addend_64bit
pop edx
sar eax,31
stos dword [edi]
jmp relocation_entry_ok
addend_64bit:
xor eax,eax
xchg eax,[edx+4]
stos dword [edi]
pop edx
relocation_entry_ok:
add esi,0Ch
jmp convert_relocations
store_elf_machine_word:
stos dword [edi]
test [format_flags],8
jz elf_machine_word_ok
and dword [edi],0
add edi,4
elf_machine_word_ok:
ret
relocations_converted:
cmp edi,ebp
xchg edi,[esp]
je rel_section_ok
mov eax,[ebx]
sub eax,4
test [format_flags],8
jz store_relocations_name_offset
dec eax
store_relocations_name_offset:
stos dword [edi]
test [format_flags],8
jnz rela_section
mov eax,9
jmp store_relocations_type
rela_section:
mov eax,4
store_relocations_type:
stos dword [edi]
xor al,al
call store_elf_machine_word
call store_elf_machine_word
mov eax,ebp
sub eax,[code_start]
call store_elf_machine_word
mov eax,[esp]
sub eax,ebp
call store_elf_machine_word
mov eax,[current_section]
stos dword [edi]
mov eax,ecx
stos dword [edi]
inc ecx
test [format_flags],8
jnz finish_elf64_rela_section
mov eax,4
stos dword [edi]
mov al,8
stos dword [edi]
jmp rel_section_ok
finish_elf64_rela_section:
mov eax,8
stos dword [edi]
xor al,al
stos dword [edi]
mov al,24
stos dword [edi]
xor al,al
stos dword [edi]
rel_section_ok:
cmp esi,[free_additional_memory]
jne make_section_entry
pop eax
mov ebx,[code_start]
sub eax,ebx
mov [code_size],eax
mov ecx,20h
test [format_flags],8
jz adjust_elf_section_headers_offset
mov ecx,28h
adjust_elf_section_headers_offset:
add [ebx+ecx],eax
mov eax,1
stos dword [edi]
mov al,2
stos dword [edi]
xor al,al
call store_elf_machine_word
call store_elf_machine_word
mov eax,[code_size]
call store_elf_machine_word
mov eax,[edx+1]
sub eax,[free_additional_memory]
call store_elf_machine_word
mov eax,[current_section]
inc eax
stos dword [edi]
mov eax,[number_of_sections]
inc eax
stos dword [edi]
test [format_flags],8
jnz finish_elf64_sym_section
mov eax,4
stos dword [edi]
mov al,10h
stos dword [edi]
jmp sym_section_ok
finish_elf64_sym_section:
mov eax,8
stos dword [edi]
xor al,al
stos dword [edi]
mov al,18h
stos dword [edi]
xor al,al
stos dword [edi]
sym_section_ok:
mov al,1+8
stos dword [edi]
mov al,3
stos dword [edi]
xor al,al
call store_elf_machine_word
call store_elf_machine_word
mov eax,[edx+1]
sub eax,[free_additional_memory]
add eax,[code_size]
call store_elf_machine_word
mov eax,[edx+1+8]
sub eax,[edx+1]
call store_elf_machine_word
xor eax,eax
stos dword [edi]
stos dword [edi]
mov al,1
call store_elf_machine_word
xor eax,eax
call store_elf_machine_word
mov eax,'tab'
mov dword [edx+1],'.sym'
mov [edx+1+4],eax
mov dword [edx+1+8],'.str'
mov [edx+1+8+4],eax
mov [resource_data],edx
mov [written_size],0
mov edx,[output_file]
call create
jc write_failed
call write_code
mov ecx,edi
mov edx,[free_additional_memory]
sub ecx,edx
add [written_size],ecx
call write
jc write_failed
jmp output_written
 
format_elf_exe:
add esi,2
or [format_flags],1
cmp byte [esi],'('
jne elf_exe_brand_ok
inc esi
cmp byte [esi],'.'
je invalid_value
push edx
call get_byte_value
cmp [value_type],0
jne invalid_use_of_symbol
pop edx
mov [edx+7],al
elf_exe_brand_ok:
mov [image_base],8048000h
cmp byte [esi],80h
jne elf_exe_base_ok
lods word [esi]
cmp ah,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
push edx
call get_dword_value
cmp [value_type],0
jne invalid_use_of_symbol
mov [image_base],eax
pop edx
elf_exe_base_ok:
mov byte [edx+10h],2
mov byte [edx+2Ah],20h
mov ebx,edi
mov ecx,20h shr 2
cmp [current_pass],0
je init_elf_segments
imul ecx,[number_of_sections]
init_elf_segments:
xor eax,eax
rep stos dword [edi]
and [number_of_sections],0
mov byte [ebx],1
mov word [ebx+1Ch],1000h
mov byte [ebx+18h],111b
mov eax,edi
xor ebp,ebp
xor cl,cl
sub eax,[code_start]
sbb ebp,0
sbb cl,0
mov [ebx+4],eax
add eax,[image_base]
adc ebp,0
adc cl,0
mov [ebx+8],eax
mov [ebx+0Ch],eax
mov [edx+18h],eax
not eax
not ebp
not cl
add eax,1
adc ebp,0
adc cl,0
add eax,edi
adc ebp,0
adc cl,0
mov edx,ebp
elf_exe_addressing_setup:
push eax
call init_addressing_space
pop eax
mov [ebx],eax
mov [ebx+4],edx
mov [ebx+8],cl
mov [symbols_stream],edi
jmp format_defined
format_elf64_exe:
add esi,2
or [format_flags],1
cmp byte [esi],'('
jne elf64_exe_brand_ok
inc esi
cmp byte [esi],'.'
je invalid_value
push edx
call get_byte_value
cmp [value_type],0
jne invalid_use_of_symbol
pop edx
mov [edx+7],al
elf64_exe_brand_ok:
mov [image_base],400000h
and [image_base_high],0
cmp byte [esi],80h
jne elf64_exe_base_ok
lods word [esi]
cmp ah,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
push edx
call get_qword_value
cmp [value_type],0
jne invalid_use_of_symbol
mov [image_base],eax
mov [image_base_high],edx
pop edx
elf64_exe_base_ok:
mov byte [edx+10h],2
mov byte [edx+36h],38h
mov ebx,edi
mov ecx,38h shr 2
cmp [current_pass],0
je init_elf64_segments
imul ecx,[number_of_sections]
init_elf64_segments:
xor eax,eax
rep stos dword [edi]
and [number_of_sections],0
mov byte [ebx],1
mov word [ebx+30h],1000h
mov byte [ebx+4],111b
push edx
mov eax,edi
sub eax,[code_start]
mov [ebx+8],eax
xor edx,edx
xor cl,cl
add eax,[image_base]
adc edx,[image_base_high]
adc cl,0
mov [ebx+10h],eax
mov [ebx+10h+4],edx
mov [ebx+18h],eax
mov [ebx+18h+4],edx
pop ebx
mov [ebx+18h],eax
mov [ebx+18h+4],edx
not eax
not edx
not cl
add eax,1
adc edx,0
adc cl,0
add eax,edi
adc edx,0
adc cl,0
jmp elf_exe_addressing_setup
elf_entry:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
test [format_flags],8
jnz elf64_entry
call get_dword_value
cmp [value_type],0
jne invalid_use_of_symbol
mov edx,[code_start]
mov [edx+18h],eax
jmp instruction_assembled
elf64_entry:
call get_qword_value
cmp [value_type],0
jne invalid_use_of_symbol
mov ebx,[code_start]
mov [ebx+18h],eax
mov [ebx+1Ch],edx
jmp instruction_assembled
elf_segment:
bt [format_flags],0
jnc illegal_instruction
test [format_flags],8
jnz elf64_segment
call close_elf_segment
push eax
call create_addressing_space
mov ebp,ebx
mov ebx,[number_of_sections]
shl ebx,5
add ebx,[code_start]
add ebx,34h
cmp ebx,[symbols_stream]
jb new_elf_segment
mov ebx,[symbols_stream]
sub ebx,20h
push edi
mov edi,ebx
mov ecx,20h shr 2
xor eax,eax
rep stos dword [edi]
pop edi
or [next_pass_needed],-1
new_elf_segment:
mov byte [ebx],1
mov word [ebx+1Ch],1000h
elf_segment_flags:
cmp byte [esi],1Eh
je elf_segment_type
cmp byte [esi],19h
jne elf_segment_flags_ok
lods word [esi]
sub ah,28
jbe invalid_argument
cmp ah,1
je mark_elf_segment_flag
cmp ah,3
ja invalid_argument
xor ah,1
cmp ah,2
je mark_elf_segment_flag
inc ah
mark_elf_segment_flag:
test [ebx+18h],ah
jnz setting_already_specified
or [ebx+18h],ah
jmp elf_segment_flags
elf_segment_type:
cmp byte [ebx],1
jne setting_already_specified
lods word [esi]
mov ecx,[number_of_sections]
jecxz elf_segment_type_ok
mov edx,[code_start]
add edx,34h
scan_elf_segment_types:
cmp edx,[symbols_stream]
jae elf_segment_type_ok
cmp [edx],ah
je data_already_defined
add edx,20h
loop scan_elf_segment_types
elf_segment_type_ok:
mov [ebx],ah
mov word [ebx+1Ch],1
jmp elf_segment_flags
elf_segment_flags_ok:
mov eax,edi
sub eax,[code_start]
mov [ebx+4],eax
pop edx
and eax,0FFFh
add edx,eax
mov [ebx+8],edx
mov [ebx+0Ch],edx
mov eax,edx
xor edx,edx
xor cl,cl
not eax
not edx
not cl
add eax,1
adc edx,0
adc cl,0
add eax,edi
adc edx,0
adc cl,0
elf_segment_addressing_setup:
mov [ds:ebp],eax
mov [ds:ebp+4],edx
mov [ds:ebp+8],cl
inc [number_of_sections]
jmp instruction_assembled
close_elf_segment:
cmp [number_of_sections],0
jne finish_elf_segment
cmp edi,[symbols_stream]
jne first_elf_segment_ok
push edi
mov edi,[code_start]
add edi,34h
mov ecx,20h shr 2
xor eax,eax
rep stos dword [edi]
pop edi
mov eax,[image_base]
ret
first_elf_segment_ok:
inc [number_of_sections]
finish_elf_segment:
mov ebx,[number_of_sections]
dec ebx
shl ebx,5
add ebx,[code_start]
add ebx,34h
mov eax,edi
sub eax,[code_start]
sub eax,[ebx+4]
mov edx,edi
cmp edi,[undefined_data_end]
jne elf_segment_size_ok
mov edi,[undefined_data_start]
elf_segment_size_ok:
mov [ebx+14h],eax
add eax,edi
sub eax,edx
mov [ebx+10h],eax
and [undefined_data_end],0
mov eax,[ebx+8]
cmp byte [ebx],1
jne elf_segment_position_ok
add eax,[ebx+14h]
add eax,0FFFh
elf_segment_position_ok:
and eax,not 0FFFh
ret
elf64_segment:
call close_elf64_segment
push eax edx
call create_addressing_space
mov ebp,ebx
mov ebx,[number_of_sections]
imul ebx,38h
add ebx,[code_start]
add ebx,40h
cmp ebx,[symbols_stream]
jb new_elf64_segment
mov ebx,[symbols_stream]
sub ebx,38h
push edi
mov edi,ebx
mov ecx,38h shr 2
xor eax,eax
rep stos dword [edi]
pop edi
or [next_pass_needed],-1
new_elf64_segment:
mov byte [ebx],1
mov word [ebx+30h],1000h
elf64_segment_flags:
cmp byte [esi],1Eh
je elf64_segment_type
cmp byte [esi],19h
jne elf64_segment_flags_ok
lods word [esi]
sub ah,28
jbe invalid_argument
cmp ah,1
je mark_elf64_segment_flag
cmp ah,3
ja invalid_argument
xor ah,1
cmp ah,2
je mark_elf64_segment_flag
inc ah
mark_elf64_segment_flag:
test [ebx+4],ah
jnz setting_already_specified
or [ebx+4],ah
jmp elf64_segment_flags
elf64_segment_type:
cmp byte [ebx],1
jne setting_already_specified
lods word [esi]
mov ecx,[number_of_sections]
jecxz elf64_segment_type_ok
mov edx,[code_start]
add edx,40h
scan_elf64_segment_types:
cmp edx,[symbols_stream]
jae elf64_segment_type_ok
cmp [edx],ah
je data_already_defined
add edx,38h
loop scan_elf64_segment_types
elf64_segment_type_ok:
mov [ebx],ah
mov word [ebx+30h],1
jmp elf64_segment_flags
elf64_segment_flags_ok:
mov ecx,edi
sub ecx,[code_start]
mov [ebx+8],ecx
pop edx eax
and ecx,0FFFh
add eax,ecx
adc edx,0
mov [ebx+10h],eax
mov [ebx+10h+4],edx
mov [ebx+18h],eax
mov [ebx+18h+4],edx
xor cl,cl
not eax
not edx
not cl
add eax,1
adc edx,0
adc cl,0
add eax,edi
adc edx,0
adc cl,0
jmp elf_segment_addressing_setup
close_elf64_segment:
cmp [number_of_sections],0
jne finish_elf64_segment
cmp edi,[symbols_stream]
jne first_elf64_segment_ok
push edi
mov edi,[code_start]
add edi,40h
mov ecx,38h shr 2
xor eax,eax
rep stos dword [edi]
pop edi
mov eax,[image_base]
mov edx,[image_base_high]
ret
first_elf64_segment_ok:
inc [number_of_sections]
finish_elf64_segment:
mov ebx,[number_of_sections]
dec ebx
imul ebx,38h
add ebx,[code_start]
add ebx,40h
mov eax,edi
sub eax,[code_start]
sub eax,[ebx+8]
mov edx,edi
cmp edi,[undefined_data_end]
jne elf64_segment_size_ok
mov edi,[undefined_data_start]
elf64_segment_size_ok:
mov [ebx+28h],eax
add eax,edi
sub eax,edx
mov [ebx+20h],eax
and [undefined_data_end],0
mov eax,[ebx+10h]
mov edx,[ebx+10h+4]
cmp byte [ebx],1
jne elf64_segment_position_ok
add eax,[ebx+28h]
adc edx,0
add eax,0FFFh
adc edx,0
elf64_segment_position_ok:
and eax,not 0FFFh
ret
close_elf_exe:
test [format_flags],8
jnz close_elf64_exe
call close_elf_segment
mov edx,[code_start]
mov eax,[number_of_sections]
mov byte [edx+1Ch],34h
mov [edx+2Ch],ax
shl eax,5
add eax,edx
add eax,34h
cmp eax,[symbols_stream]
je elf_exe_ok
or [next_pass_needed],-1
elf_exe_ok:
ret
close_elf64_exe:
call close_elf64_segment
mov edx,[code_start]
mov eax,[number_of_sections]
mov byte [edx+20h],40h
mov [edx+38h],ax
imul eax,38h
add eax,edx
add eax,40h
cmp eax,[symbols_stream]
je elf64_exe_ok
or [next_pass_needed],-1
elf64_exe_ok:
ret
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/messages.inc
0,0 → 1,52
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
_out_of_memory db 'out of memory',0
_stack_overflow db 'out of stack space',0
_main_file_not_found db 'source file not found',0
_unexpected_end_of_file db 'unexpected end of file',0
_code_cannot_be_generated db 'code cannot be generated',0
_format_limitations_exceeded db 'format limitations exceeded',0
_invalid_definition db 'invalid definition provided',0
_write_failed db 'write failed',0
_file_not_found db 'file not found',0
_error_reading_file db 'error reading file',0
_invalid_file_format db 'invalid file format',0
_invalid_macro_arguments db 'invalid macro arguments',0
_incomplete_macro db 'incomplete macro',0
_unexpected_characters db 'unexpected characters',0
_invalid_argument db 'invalid argument',0
_illegal_instruction db 'illegal instruction',0
_invalid_operand db 'invalid operand',0
_invalid_operand_size db 'invalid size of operand',0
_operand_size_not_specified db 'operand size not specified',0
_operand_sizes_do_not_match db 'operand sizes do not match',0
_invalid_address_size db 'invalid size of address value',0
_address_sizes_do_not_agree db 'address sizes do not agree',0
_disallowed_combination_of_registers db 'disallowed combination of registers',0
_long_immediate_not_encodable db 'not encodable with long immediate',0
_relative_jump_out_of_range db 'relative jump out of range',0
_invalid_expression db 'invalid expression',0
_invalid_address db 'invalid address',0
_invalid_value db 'invalid value',0
_value_out_of_range db 'value out of range',0
_undefined_symbol db 'undefined symbol',0
_symbol_out_of_scope_1 db 'symbol',0
_symbol_out_of_scope_2 db 'out of scope',0
_invalid_use_of_symbol db 'invalid use of symbol',0
_name_too_long db 'name too long',0
_invalid_name db 'invalid name',0
_reserved_word_used_as_symbol db 'reserved word used as symbol',0
_symbol_already_defined db 'symbol already defined',0
_missing_end_quote db 'missing end quote',0
_missing_end_directive db 'missing end directive',0
_unexpected_instruction db 'unexpected instruction',0
_extra_characters_on_line db 'extra characters on line',0
_section_not_aligned_enough db 'section is not aligned enough',0
_setting_already_specified db 'setting already specified',0
_data_already_defined db 'data already defined',0
_too_many_repeats db 'too many repeats',0
_invoked_error db 'error directive encountered in source file',0
_assertion_failed db 'assertion failed',0
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/parser.inc
0,0 → 1,1450
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
parser:
mov eax,[memory_end]
mov [labels_list],eax
mov eax,[additional_memory]
mov [free_additional_memory],eax
xor eax,eax
mov [current_locals_prefix],eax
mov [anonymous_reverse],eax
mov [anonymous_forward],eax
mov [hash_tree],eax
mov [blocks_stack],eax
mov [parsed_lines],eax
mov esi,[memory_start]
mov edi,[source_start]
parser_loop:
mov [current_line],esi
lea eax,[edi+100h]
cmp eax,[labels_list]
jae out_of_memory
cmp byte [esi+16],0
je empty_line
cmp byte [esi+16],3Bh
je empty_line
mov al,0Fh
stos byte [edi]
mov eax,esi
stos dword [edi]
inc [parsed_lines]
add esi,16
parse_line:
mov [formatter_symbols_allowed],0
mov [decorator_symbols_allowed],0
cmp byte [esi],1Ah
jne empty_instruction
push edi
add esi,2
movzx ecx,byte [esi-1]
cmp byte [esi+ecx],':'
je simple_label
cmp byte [esi+ecx],'='
je constant_label
call get_instruction
jnc main_instruction_identified
cmp byte [esi+ecx],1Ah
jne no_data_label
push esi ecx
lea esi,[esi+ecx+2]
movzx ecx,byte [esi-1]
call get_data_directive
jnc data_label
pop ecx esi
no_data_label:
call get_data_directive
jnc main_instruction_identified
pop edi
sub esi,2
xor bx,bx
call parse_line_contents
jmp parse_next_line
simple_label:
pop edi
call identify_label
cmp byte [esi+1],':'
je block_label
mov byte [edi],2
inc edi
stos dword [edi]
inc esi
xor al,al
stos byte [edi]
jmp parse_line
block_label:
mov byte [edi],4
inc edi
stos dword [edi]
add esi,2
jmp parse_line
constant_label:
pop edi
call get_label_id
mov byte [edi],3
inc edi
stos dword [edi]
xor al,al
stos byte [edi]
inc esi
xor bx,bx
call parse_line_contents
jmp parse_next_line
data_label:
pop ecx edx
pop edi
push eax ebx esi
mov esi,edx
movzx ecx,byte [esi-1]
call identify_label
mov byte [edi],2
inc edi
stos dword [edi]
pop esi ebx eax
stos byte [edi]
push edi
main_instruction_identified:
pop edi
mov dl,al
mov al,1
stos byte [edi]
mov ax,bx
stos word [edi]
mov al,dl
stos byte [edi]
cmp bx,if_directive-instruction_handler
je parse_block
cmp bx,repeat_directive-instruction_handler
je parse_block
cmp bx,while_directive-instruction_handler
je parse_block
cmp bx,end_directive-instruction_handler
je parse_end_directive
cmp bx,else_directive-instruction_handler
je parse_else
cmp bx,assert_directive-instruction_handler
je parse_assert
common_parse:
call parse_line_contents
jmp parse_next_line
empty_instruction:
lods byte [esi]
or al,al
jz parse_next_line
cmp al,':'
je invalid_name
dec esi
mov [parenthesis_stack],0
call parse_argument
jmp parse_next_line
empty_line:
add esi,16
skip_rest_of_line:
call skip_foreign_line
parse_next_line:
cmp esi,[source_start]
jb parser_loop
source_parsed:
cmp [blocks_stack],0
je blocks_stack_ok
pop eax
pop [current_line]
jmp missing_end_directive
blocks_stack_ok:
xor al,al
stos byte [edi]
add edi,0Fh
and edi,not 0Fh
mov [code_start],edi
ret
parse_block:
mov eax,esp
sub eax,100h
jc stack_overflow
cmp eax,[stack_limit]
jb stack_overflow
push [current_line]
mov ax,bx
shl eax,16
push eax
inc [blocks_stack]
cmp bx,if_directive-instruction_handler
je parse_if
cmp bx,while_directive-instruction_handler
je parse_while
call parse_line_contents
jmp parse_next_line
parse_end_directive:
cmp byte [esi],1Ah
jne common_parse
push edi
inc esi
movzx ecx,byte [esi]
inc esi
call get_instruction
pop edi
jnc parse_end_block
sub esi,2
jmp common_parse
parse_end_block:
mov dl,al
mov al,1
stos byte [edi]
mov ax,bx
stos word [edi]
mov al,dl
stos byte [edi]
lods byte [esi]
or al,al
jnz extra_characters_on_line
cmp bx,if_directive-instruction_handler
je close_parsing_block
cmp bx,repeat_directive-instruction_handler
je close_parsing_block
cmp bx,while_directive-instruction_handler
je close_parsing_block
jmp parse_next_line
close_parsing_block:
cmp [blocks_stack],0
je unexpected_instruction
cmp bx,[esp+2]
jne unexpected_instruction
dec [blocks_stack]
pop eax edx
cmp bx,if_directive-instruction_handler
jne parse_next_line
test al,1100b
jz parse_next_line
test al,10000b
jnz parse_next_line
sub edi,8
jmp parse_next_line
parse_if:
push edi
call parse_line_contents
xor al,al
stos byte [edi]
xchg esi,[esp]
mov edi,esi
call preevaluate_logical_expression
pop esi
cmp al,'0'
je parse_false_condition_block
cmp al,'1'
je parse_true_condition_block
or byte [esp],10000b
jmp parse_next_line
parse_while:
push edi
call parse_line_contents
xor al,al
stos byte [edi]
xchg esi,[esp]
mov edi,esi
call preevaluate_logical_expression
pop esi
cmp al,'0'
je parse_false_condition_block
cmp al,'1'
jne parse_next_line
stos byte [edi]
jmp parse_next_line
parse_false_condition_block:
or byte [esp],1
sub edi,4
jmp skip_parsing
parse_true_condition_block:
or byte [esp],100b
sub edi,4
jmp parse_next_line
parse_else:
cmp [blocks_stack],0
je unexpected_instruction
cmp word [esp+2],if_directive-instruction_handler
jne unexpected_instruction
lods byte [esi]
or al,al
jz parse_pure_else
cmp al,1Ah
jne extra_characters_on_line
push edi
movzx ecx,byte [esi]
inc esi
call get_instruction
jc extra_characters_on_line
pop edi
cmp bx,if_directive-instruction_handler
jne extra_characters_on_line
test byte [esp],100b
jnz skip_true_condition_else
mov dl,al
mov al,1
stos byte [edi]
mov ax,bx
stos word [edi]
mov al,dl
stos byte [edi]
jmp parse_if
parse_assert:
push edi
call parse_line_contents
xor al,al
stos byte [edi]
xchg esi,[esp]
mov edi,esi
call preevaluate_logical_expression
pop esi
or al,al
jz parse_next_line
stos byte [edi]
jmp parse_next_line
skip_true_condition_else:
sub edi,4
or byte [esp],1
jmp skip_parsing_contents
parse_pure_else:
bts dword [esp],1
jc unexpected_instruction
test byte [esp],100b
jz parse_next_line
sub edi,4
or byte [esp],1
jmp skip_parsing
skip_parsing:
cmp esi,[source_start]
jae source_parsed
mov [current_line],esi
add esi,16
skip_parsing_line:
cmp byte [esi],1Ah
jne skip_parsing_contents
inc esi
movzx ecx,byte [esi]
inc esi
cmp byte [esi+ecx],':'
je skip_parsing_label
push edi
call get_instruction
pop edi
jnc skip_parsing_instruction
add esi,ecx
jmp skip_parsing_contents
skip_parsing_label:
lea esi,[esi+ecx+1]
jmp skip_parsing_line
skip_parsing_instruction:
cmp bx,if_directive-instruction_handler
je skip_parsing_block
cmp bx,repeat_directive-instruction_handler
je skip_parsing_block
cmp bx,while_directive-instruction_handler
je skip_parsing_block
cmp bx,end_directive-instruction_handler
je skip_parsing_end_directive
cmp bx,else_directive-instruction_handler
je skip_parsing_else
skip_parsing_contents:
lods byte [esi]
or al,al
jz skip_parsing
cmp al,1Ah
je skip_parsing_symbol
cmp al,3Bh
je skip_parsing_symbol
cmp al,22h
je skip_parsing_string
jmp skip_parsing_contents
skip_parsing_symbol:
lods byte [esi]
movzx eax,al
add esi,eax
jmp skip_parsing_contents
skip_parsing_string:
lods dword [esi]
add esi,eax
jmp skip_parsing_contents
skip_parsing_block:
mov eax,esp
sub eax,100h
jc stack_overflow
cmp eax,[stack_limit]
jb stack_overflow
push [current_line]
mov ax,bx
shl eax,16
push eax
inc [blocks_stack]
jmp skip_parsing_contents
skip_parsing_end_directive:
cmp byte [esi],1Ah
jne skip_parsing_contents
push edi
inc esi
movzx ecx,byte [esi]
inc esi
call get_instruction
pop edi
jnc skip_parsing_end_block
add esi,ecx
jmp skip_parsing_contents
skip_parsing_end_block:
lods byte [esi]
or al,al
jnz extra_characters_on_line
cmp bx,if_directive-instruction_handler
je close_skip_parsing_block
cmp bx,repeat_directive-instruction_handler
je close_skip_parsing_block
cmp bx,while_directive-instruction_handler
je close_skip_parsing_block
jmp skip_parsing
close_skip_parsing_block:
cmp [blocks_stack],0
je unexpected_instruction
cmp bx,[esp+2]
jne unexpected_instruction
dec [blocks_stack]
pop eax edx
test al,1
jz skip_parsing
cmp bx,if_directive-instruction_handler
jne parse_next_line
test al,10000b
jz parse_next_line
mov al,0Fh
stos byte [edi]
mov eax,[current_line]
stos dword [edi]
inc [parsed_lines]
mov eax,1 + (end_directive-instruction_handler) shl 8
stos dword [edi]
mov eax,1 + (if_directive-instruction_handler) shl 8
stos dword [edi]
jmp parse_next_line
skip_parsing_else:
cmp [blocks_stack],0
je unexpected_instruction
cmp word [esp+2],if_directive-instruction_handler
jne unexpected_instruction
lods byte [esi]
or al,al
jz skip_parsing_pure_else
cmp al,1Ah
jne extra_characters_on_line
push edi
movzx ecx,byte [esi]
inc esi
call get_instruction
jc extra_characters_on_line
pop edi
cmp bx,if_directive-instruction_handler
jne extra_characters_on_line
mov al,[esp]
test al,1
jz skip_parsing_contents
test al,100b
jnz skip_parsing_contents
test al,10000b
jnz parse_else_if
xor al,al
mov [esp],al
mov al,0Fh
stos byte [edi]
mov eax,[current_line]
stos dword [edi]
inc [parsed_lines]
parse_else_if:
mov eax,1 + (if_directive-instruction_handler) shl 8
stos dword [edi]
jmp parse_if
skip_parsing_pure_else:
bts dword [esp],1
jc unexpected_instruction
mov al,[esp]
test al,1
jz skip_parsing
test al,100b
jnz skip_parsing
and al,not 1
or al,1000b
mov [esp],al
jmp parse_next_line
 
parse_line_contents:
mov [parenthesis_stack],0
parse_instruction_arguments:
cmp bx,prefix_instruction-instruction_handler
je allow_embedded_instruction
cmp bx,times_directive-instruction_handler
je parse_times_directive
cmp bx,end_directive-instruction_handler
je allow_embedded_instruction
cmp bx,label_directive-instruction_handler
je parse_label_directive
cmp bx,segment_directive-instruction_handler
je parse_segment_directive
cmp bx,load_directive-instruction_handler
je parse_load_directive
cmp bx,extrn_directive-instruction_handler
je parse_extrn_directive
cmp bx,public_directive-instruction_handler
je parse_public_directive
cmp bx,section_directive-instruction_handler
je parse_formatter_argument
cmp bx,format_directive-instruction_handler
je parse_formatter_argument
cmp bx,data_directive-instruction_handler
je parse_formatter_argument
jmp parse_argument
parse_formatter_argument:
or [formatter_symbols_allowed],-1
parse_argument:
lea eax,[edi+100h]
cmp eax,[labels_list]
jae out_of_memory
lods byte [esi]
cmp al,':'
je instruction_separator
cmp al,','
je separator
cmp al,'='
je expression_comparator
cmp al,'|'
je separator
cmp al,'&'
je separator
cmp al,'~'
je separator
cmp al,'>'
je greater
cmp al,'<'
je less
cmp al,')'
je close_parenthesis
or al,al
jz contents_parsed
cmp al,'['
je address_argument
cmp al,']'
je separator
cmp al,'{'
je open_decorator
cmp al,'}'
je close_decorator
cmp al,'#'
je unallowed_character
cmp al,'`'
je unallowed_character
cmp al,3Bh
je foreign_argument
cmp [decorator_symbols_allowed],0
je not_a_separator
cmp al,'-'
je separator
not_a_separator:
dec esi
cmp al,1Ah
jne expression_argument
push edi
mov edi,directive_operators
call get_operator
or al,al
jnz operator_argument
inc esi
movzx ecx,byte [esi]
inc esi
call get_symbol
jnc symbol_argument
cmp ecx,1
jne check_argument
cmp byte [esi],'?'
jne check_argument
pop edi
movs byte [edi],[esi]
jmp argument_parsed
foreign_argument:
dec esi
call skip_foreign_line
jmp contents_parsed
symbol_argument:
pop edi
stos word [edi]
jmp argument_parsed
operator_argument:
pop edi
cmp al,85h
je ptr_argument
stos byte [edi]
cmp al,80h
je forced_multipart_expression
cmp al,8Ch
je forced_expression
cmp al,81h
je forced_parenthesis
cmp al,82h
je parse_from_operator
cmp al,89h
je parse_label_operator
cmp al,0F8h
je forced_expression
jmp argument_parsed
instruction_separator:
stos byte [edi]
allow_embedded_instruction:
cmp byte [esi],1Ah
jne parse_argument
push edi
inc esi
movzx ecx,byte [esi]
inc esi
call get_instruction
jnc embedded_instruction
call get_data_directive
jnc embedded_instruction
pop edi
sub esi,2
jmp parse_argument
embedded_instruction:
pop edi
mov dl,al
mov al,1
stos byte [edi]
mov ax,bx
stos word [edi]
mov al,dl
stos byte [edi]
jmp parse_instruction_arguments
parse_times_directive:
mov al,'('
stos byte [edi]
call convert_expression
mov al,')'
stos byte [edi]
cmp byte [esi],':'
jne allow_embedded_instruction
movs byte [edi],[esi]
jmp allow_embedded_instruction
parse_segment_directive:
or [formatter_symbols_allowed],-1
parse_label_directive:
cmp byte [esi],1Ah
jne argument_parsed
push esi
inc esi
movzx ecx,byte [esi]
inc esi
call identify_label
pop ebx
cmp eax,0Fh
je non_label_identified
mov byte [edi],2
inc edi
stos dword [edi]
xor al,al
stos byte [edi]
jmp argument_parsed
non_label_identified:
mov esi,ebx
jmp argument_parsed
parse_load_directive:
cmp byte [esi],1Ah
jne argument_parsed
push esi
inc esi
movzx ecx,byte [esi]
inc esi
call get_label_id
pop ebx
cmp eax,0Fh
je non_label_identified
mov byte [edi],2
inc edi
stos dword [edi]
xor al,al
stos byte [edi]
jmp argument_parsed
parse_public_directive:
cmp byte [esi],1Ah
jne parse_argument
inc esi
push esi
movzx ecx,byte [esi]
inc esi
push esi ecx
push edi
or [formatter_symbols_allowed],-1
call get_symbol
mov [formatter_symbols_allowed],0
pop edi
jc parse_public_label
cmp al,1Dh
jne parse_public_label
add esp,12
stos word [edi]
jmp parse_public_directive
parse_public_label:
pop ecx esi
mov al,2
stos byte [edi]
call get_label_id
stos dword [edi]
mov ax,8600h
stos word [edi]
pop ebx
push ebx esi edi
mov edi,directive_operators
call get_operator
pop edi edx ebx
cmp al,86h
je argument_parsed
mov esi,edx
xchg esi,ebx
movzx ecx,byte [esi]
inc esi
mov ax,'('
stos word [edi]
mov eax,ecx
stos dword [edi]
rep movs byte [edi],[esi]
xor al,al
stos byte [edi]
xchg esi,ebx
jmp argument_parsed
parse_extrn_directive:
cmp byte [esi],22h
je parse_quoted_extrn
cmp byte [esi],1Ah
jne parse_argument
push esi
movzx ecx,byte [esi+1]
add esi,2
mov ax,'('
stos word [edi]
mov eax,ecx
stos dword [edi]
rep movs byte [edi],[esi]
mov ax,8600h
stos word [edi]
pop esi
parse_label_operator:
cmp byte [esi],1Ah
jne argument_parsed
inc esi
movzx ecx,byte [esi]
inc esi
mov al,2
stos byte [edi]
call get_label_id
stos dword [edi]
xor al,al
stos byte [edi]
jmp argument_parsed
parse_from_operator:
cmp byte [esi],22h
jne forced_multipart_expression
jmp argument_parsed
parse_quoted_extrn:
inc esi
mov ax,'('
stos word [edi]
lods dword [esi]
mov ecx,eax
stos dword [edi]
rep movs byte [edi],[esi]
xor al,al
stos byte [edi]
push esi edi
mov edi,directive_operators
call get_operator
mov edx,esi
pop edi esi
cmp al,86h
jne argument_parsed
stos byte [edi]
mov esi,edx
jmp parse_label_operator
ptr_argument:
call parse_address
jmp address_parsed
check_argument:
push esi ecx
sub esi,2
mov edi,single_operand_operators
call get_operator
pop ecx esi
or al,al
jnz not_instruction
call get_instruction
jnc embedded_instruction
call get_data_directive
jnc embedded_instruction
not_instruction:
pop edi
sub esi,2
expression_argument:
cmp byte [esi],22h
jne not_string
mov eax,[esi+1]
lea ebx,[esi+5+eax]
push ebx ecx esi edi
call parse_expression
pop eax edx ecx ebx
cmp esi,ebx
jne expression_argument_parsed
mov edi,eax
mov esi,edx
string_argument:
inc esi
mov ax,'('
stos word [edi]
lods dword [esi]
mov ecx,eax
stos dword [edi]
shr ecx,1
jnc string_movsb_ok
movs byte [edi],[esi]
string_movsb_ok:
shr ecx,1
jnc string_movsw_ok
movs word [edi],[esi]
string_movsw_ok:
rep movs dword [edi],[esi]
xor al,al
stos byte [edi]
jmp expression_argument_parsed
parse_expression:
mov al,'('
stos byte [edi]
call convert_expression
mov al,')'
stos byte [edi]
ret
not_string:
cmp byte [esi],'('
jne expression
mov eax,esp
sub eax,100h
jc stack_overflow
cmp eax,[stack_limit]
jb stack_overflow
push esi edi
inc esi
mov al,91h
stos byte [edi]
inc [parenthesis_stack]
jmp parse_argument
expression_comparator:
stos byte [edi]
jmp forced_expression
greater:
cmp byte [esi],'='
jne separator
inc esi
mov al,0F2h
jmp separator
less:
cmp byte [edi-1],0F6h
je separator
cmp byte [esi],'>'
je not_equal
cmp byte [esi],'='
jne separator
inc esi
mov al,0F3h
jmp separator
not_equal:
inc esi
mov al,0F1h
jmp expression_comparator
expression:
call parse_expression
jmp expression_argument_parsed
forced_expression:
xor al,al
xchg al,[formatter_symbols_allowed]
push eax
call parse_expression
forced_expression_parsed:
pop eax
mov [formatter_symbols_allowed],al
jmp argument_parsed
forced_multipart_expression:
xor al,al
xchg al,[formatter_symbols_allowed]
push eax
call parse_expression
cmp byte [esi],':'
jne forced_expression_parsed
movs byte [edi],[esi]
call parse_expression
jmp forced_expression_parsed
address_argument:
call parse_address
lods byte [esi]
cmp al,']'
je address_parsed
cmp al,','
je divided_address
dec esi
mov al,')'
stos byte [edi]
jmp argument_parsed
divided_address:
mov ax,'),'
stos word [edi]
jmp expression
address_parsed:
mov al,']'
stos byte [edi]
jmp argument_parsed
parse_address:
mov al,'['
stos byte [edi]
cmp word [esi],021Ah
jne convert_address
push esi
add esi,4
lea ebx,[esi+1]
cmp byte [esi],':'
pop esi
jne convert_address
add esi,2
mov ecx,2
push ebx edi
call get_symbol
pop edi esi
jc unknown_segment_prefix
cmp al,10h
jne unknown_segment_prefix
mov al,ah
and ah,11110000b
cmp ah,30h
jne unknown_segment_prefix
add al,30h
stos byte [edi]
jmp convert_address
unknown_segment_prefix:
sub esi,5
convert_address:
push edi
mov edi,address_sizes
call get_operator
pop edi
or al,al
jz convert_expression
add al,70h
stos byte [edi]
jmp convert_expression
forced_parenthesis:
cmp byte [esi],'('
jne argument_parsed
inc esi
mov al,91h
jmp separator
unallowed_character:
mov al,0FFh
jmp separator
open_decorator:
inc [decorator_symbols_allowed]
jmp separator
close_decorator:
dec [decorator_symbols_allowed]
jmp separator
close_parenthesis:
mov al,92h
separator:
stos byte [edi]
argument_parsed:
cmp [parenthesis_stack],0
je parse_argument
dec [parenthesis_stack]
add esp,8
jmp argument_parsed
expression_argument_parsed:
cmp [parenthesis_stack],0
je parse_argument
cmp byte [esi],')'
jne argument_parsed
dec [parenthesis_stack]
pop edi esi
jmp expression
contents_parsed:
cmp [parenthesis_stack],0
je contents_ok
dec [parenthesis_stack]
add esp,8
jmp contents_parsed
contents_ok:
ret
 
identify_label:
cmp byte [esi],'.'
je local_label_name
call get_label_id
cmp eax,10h
jb label_identified
or ebx,ebx
jz anonymous_label_name
dec ebx
mov [current_locals_prefix],ebx
label_identified:
ret
anonymous_label_name:
cmp byte [esi-1],'@'
je anonymous_label_name_ok
mov eax,0Fh
anonymous_label_name_ok:
ret
local_label_name:
call get_label_id
ret
 
get_operator:
cmp byte [esi],1Ah
jne get_simple_operator
mov edx,esi
push ebp
inc esi
lods byte [esi]
movzx ebp,al
push edi
mov ecx,ebp
call lower_case
pop edi
check_operator:
mov esi,converted
movzx ecx,byte [edi]
jecxz no_operator
inc edi
mov ebx,edi
add ebx,ecx
cmp ecx,ebp
jne next_operator
repe cmps byte [esi],[edi]
je operator_found
jb no_operator
next_operator:
mov edi,ebx
inc edi
jmp check_operator
no_operator:
mov esi,edx
mov ecx,ebp
pop ebp
no_simple_operator:
xor al,al
ret
operator_found:
lea esi,[edx+2+ebp]
mov ecx,ebp
pop ebp
mov al,[edi]
ret
get_simple_operator:
mov al,[esi]
cmp al,22h
je no_simple_operator
simple_operator:
cmp byte [edi],1
jb no_simple_operator
ja simple_next_operator
cmp al,[edi+1]
je simple_operator_found
simple_next_operator:
movzx ecx,byte [edi]
lea edi,[edi+1+ecx+1]
jmp simple_operator
simple_operator_found:
inc esi
mov al,[edi+2]
ret
 
get_symbol:
push esi
mov ebp,ecx
call lower_case
mov ecx,ebp
cmp cl,11
ja no_symbol
sub cl,1
jc no_symbol
movzx ebx,word [symbols+ecx*4]
add ebx,symbols
movzx edx,word [symbols+ecx*4+2]
scan_symbols:
or edx,edx
jz no_symbol
mov eax,edx
shr eax,1
lea edi,[ebp+2]
imul eax,edi
lea edi,[ebx+eax]
mov esi,converted
mov ecx,ebp
repe cmps byte [esi],[edi]
ja symbols_up
jb symbols_down
mov ax,[edi]
cmp al,18h
jb symbol_ok
cmp al,1Fh
je decorator_symbol
cmp [formatter_symbols_allowed],0
je no_symbol
symbol_ok:
pop esi
add esi,ebp
clc
ret
decorator_symbol:
cmp [decorator_symbols_allowed],0
jne symbol_ok
no_symbol:
pop esi
mov ecx,ebp
stc
ret
symbols_down:
shr edx,1
jmp scan_symbols
symbols_up:
lea ebx,[edi+ecx+2]
shr edx,1
adc edx,-1
jmp scan_symbols
 
get_data_directive:
push esi
mov ebp,ecx
call lower_case
mov ecx,ebp
cmp cl,4
ja no_instruction
sub cl,2
jc no_instruction
movzx ebx,word [data_directives+ecx*4]
add ebx,data_directives
movzx edx,word [data_directives+ecx*4+2]
jmp scan_instructions
 
get_instruction:
push esi
mov ebp,ecx
call lower_case
mov ecx,ebp
cmp cl,16
ja no_instruction
sub cl,2
jc no_instruction
movzx ebx,word [instructions+ecx*4]
add ebx,instructions
movzx edx,word [instructions+ecx*4+2]
scan_instructions:
or edx,edx
jz no_instruction
mov eax,edx
shr eax,1
lea edi,[ebp+3]
imul eax,edi
lea edi,[ebx+eax]
mov esi,converted
mov ecx,ebp
repe cmps byte [esi],[edi]
ja instructions_up
jb instructions_down
pop esi
add esi,ebp
mov al,[edi]
mov bx,[edi+1]
clc
ret
no_instruction:
pop esi
mov ecx,ebp
stc
ret
instructions_down:
shr edx,1
jmp scan_instructions
instructions_up:
lea ebx,[edi+ecx+3]
shr edx,1
adc edx,-1
jmp scan_instructions
 
get_label_id:
cmp ecx,100h
jae name_too_long
cmp byte [esi],'@'
je anonymous_label
cmp byte [esi],'.'
jne standard_label
cmp byte [esi+1],'.'
je standard_label
cmp [current_locals_prefix],0
je standard_label
push edi
mov edi,[additional_memory_end]
sub edi,2
sub edi,ecx
push ecx esi
mov esi,[current_locals_prefix]
lods byte [esi]
movzx ecx,al
sub edi,ecx
cmp edi,[free_additional_memory]
jb out_of_memory
mov word [edi],0
add edi,2
mov ebx,edi
rep movs byte [edi],[esi]
pop esi ecx
add al,cl
jc name_too_long
rep movs byte [edi],[esi]
pop edi
push ebx esi
movzx ecx,al
mov byte [ebx-1],al
mov esi,ebx
call get_label_id
pop esi ebx
cmp ebx,[eax+24]
jne composed_label_id_ok
lea edx,[ebx-2]
mov [additional_memory_end],edx
composed_label_id_ok:
ret
anonymous_label:
cmp ecx,2
jne standard_label
mov al,[esi+1]
mov ebx,characters
xlat byte [ebx]
cmp al,'@'
je new_anonymous
cmp al,'b'
je anonymous_back
cmp al,'r'
je anonymous_back
cmp al,'f'
jne standard_label
add esi,2
mov eax,[anonymous_forward]
or eax,eax
jnz anonymous_ok
mov eax,[current_line]
mov [error_line],eax
call allocate_label
mov [anonymous_forward],eax
anonymous_ok:
xor ebx,ebx
ret
anonymous_back:
mov eax,[anonymous_reverse]
add esi,2
or eax,eax
jz bogus_anonymous
jmp anonymous_ok
bogus_anonymous:
call allocate_label
mov [anonymous_reverse],eax
jmp anonymous_ok
new_anonymous:
add esi,2
mov eax,[anonymous_forward]
or eax,eax
jnz new_anonymous_ok
call allocate_label
new_anonymous_ok:
mov [anonymous_reverse],eax
mov [anonymous_forward],0
jmp anonymous_ok
standard_label:
cmp byte [esi],'%'
je get_predefined_id
cmp byte [esi],'$'
je current_address_label
cmp byte [esi],'?'
jne find_label
cmp ecx,1
jne find_label
inc esi
mov eax,0Fh
ret
current_address_label:
cmp ecx,2
ja find_label
inc esi
jb get_current_offset_id
inc esi
cmp byte [esi-1],'$'
je get_org_origin_id
sub esi,2
jmp find_label
get_current_offset_id:
xor eax,eax
ret
get_counter_id:
mov eax,1
ret
get_timestamp_id:
mov eax,2
ret
get_org_origin_id:
mov eax,3
ret
get_predefined_id:
cmp ecx,2
ja find_label
inc esi
cmp cl,1
je get_counter_id
lods byte [esi]
mov ebx,characters
xlat [ebx]
cmp al,'t'
je get_timestamp_id
sub esi,2
find_label:
xor ebx,ebx
mov eax,2166136261
mov ebp,16777619
hash_label:
xor al,[esi+ebx]
mul ebp
inc bl
cmp bl,cl
jb hash_label
mov ebp,eax
shl eax,8
and ebp,0FFh shl 24
xor ebp,eax
or ebp,ebx
mov [label_hash],ebp
push edi esi
push ecx
mov ecx,32
mov ebx,hash_tree
follow_tree:
mov edx,[ebx]
or edx,edx
jz extend_tree
xor eax,eax
shl ebp,1
adc eax,0
lea ebx,[edx+eax*4]
dec ecx
jnz follow_tree
mov [label_leaf],ebx
pop edx
mov eax,[ebx]
or eax,eax
jz add_label
mov ebx,esi
mov ebp,[label_hash]
compare_labels:
mov esi,ebx
mov ecx,edx
mov edi,[eax+4]
mov edi,[edi+24]
repe cmps byte [esi],[edi]
je label_found
mov eax,[eax]
or eax,eax
jnz compare_labels
jmp add_label
label_found:
add esp,4
pop edi
mov eax,[eax+4]
ret
extend_tree:
mov edx,[free_additional_memory]
lea eax,[edx+8]
cmp eax,[additional_memory_end]
ja out_of_memory
mov [free_additional_memory],eax
xor eax,eax
mov [edx],eax
mov [edx+4],eax
shl ebp,1
adc eax,0
mov [ebx],edx
lea ebx,[edx+eax*4]
dec ecx
jnz extend_tree
mov [label_leaf],ebx
pop edx
add_label:
mov ecx,edx
pop esi
cmp byte [esi-2],0
je label_name_ok
mov al,[esi]
cmp al,30h
jb name_first_char_ok
cmp al,39h
jbe numeric_name
name_first_char_ok:
cmp al,'$'
jne check_for_reserved_word
numeric_name:
add esi,ecx
reserved_word:
mov eax,0Fh
pop edi
ret
check_for_reserved_word:
call get_instruction
jnc reserved_word
call get_data_directive
jnc reserved_word
call get_symbol
jnc reserved_word
sub esi,2
mov edi,operators
call get_operator
or al,al
jnz reserved_word
mov edi,single_operand_operators
call get_operator
or al,al
jnz reserved_word
mov edi,directive_operators
call get_operator
or al,al
jnz reserved_word
inc esi
movzx ecx,byte [esi]
inc esi
label_name_ok:
mov edx,[free_additional_memory]
lea eax,[edx+8]
cmp eax,[additional_memory_end]
ja out_of_memory
mov [free_additional_memory],eax
mov ebx,esi
add esi,ecx
mov eax,[label_leaf]
mov edi,[eax]
mov [edx],edi
mov [eax],edx
call allocate_label
mov [edx+4],eax
mov [eax+24],ebx
pop edi
ret
allocate_label:
mov eax,[labels_list]
mov ecx,LABEL_STRUCTURE_SIZE shr 2
initialize_label:
sub eax,4
mov dword [eax],0
loop initialize_label
mov [labels_list],eax
ret
 
LABEL_STRUCTURE_SIZE = 32
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/preproce.inc
0,0 → 1,2898
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
preprocessor:
mov edi,characters
xor al,al
make_characters_table:
stosb
inc al
jnz make_characters_table
mov esi,characters+'a'
mov edi,characters+'A'
mov ecx,26
rep movsb
mov edi,characters
mov esi,symbol_characters+1
movzx ecx,byte [esi-1]
xor eax,eax
mark_symbol_characters:
lodsb
mov byte [edi+eax],0
loop mark_symbol_characters
mov edi,locals_counter
mov ax,1 + '0' shl 8
stos word [edi]
mov edi,[memory_start]
mov [include_paths],edi
mov esi,include_variable
call get_environment_variable
xor al,al
stos byte [edi]
mov [memory_start],edi
mov eax,[additional_memory]
mov [free_additional_memory],eax
mov eax,[additional_memory_end]
mov [labels_list],eax
xor eax,eax
mov [source_start],eax
mov [tagged_blocks],eax
mov [hash_tree],eax
mov [error],eax
mov [macro_status],al
mov [current_line],eax
mov esi,[initial_definitions]
test esi,esi
jz predefinitions_ok
process_predefinitions:
movzx ecx,byte [esi]
test ecx,ecx
jz predefinitions_ok
inc esi
lea eax,[esi+ecx]
push eax
mov ch,10b
call add_preprocessor_symbol
pop esi
mov edi,[memory_start]
mov [edx+8],edi
convert_predefinition:
cmp edi,[memory_end]
jae out_of_memory
lods byte [esi]
or al,al
jz predefinition_converted
cmp al,20h
je convert_predefinition
mov ah,al
mov ebx,characters
xlat byte [ebx]
or al,al
jz predefinition_separator
cmp ah,27h
je predefinition_string
cmp ah,22h
je predefinition_string
mov byte [edi],1Ah
scas word [edi]
xchg al,ah
stos byte [edi]
mov ebx,characters
xor ecx,ecx
predefinition_symbol:
lods byte [esi]
stos byte [edi]
xlat byte [ebx]
or al,al
loopnzd predefinition_symbol
neg ecx
cmp ecx,255
ja invalid_definition
mov ebx,edi
sub ebx,ecx
mov byte [ebx-2],cl
found_predefinition_separator:
dec edi
mov ah,[esi-1]
predefinition_separator:
xchg al,ah
or al,al
jz predefinition_converted
cmp al,20h
je convert_predefinition
cmp al,3Bh
je invalid_definition
cmp al,5Ch
je predefinition_backslash
stos byte [edi]
jmp convert_predefinition
predefinition_string:
mov al,22h
stos byte [edi]
scas dword [edi]
mov ebx,edi
copy_predefinition_string:
lods byte [esi]
stos byte [edi]
or al,al
jz invalid_definition
cmp al,ah
jne copy_predefinition_string
lods byte [esi]
cmp al,ah
je copy_predefinition_string
dec esi
dec edi
mov eax,edi
sub eax,ebx
mov [ebx-4],eax
jmp convert_predefinition
predefinition_backslash:
mov byte [edi],0
lods byte [esi]
or al,al
jz invalid_definition
cmp al,20h
je invalid_definition
cmp al,3Bh
je invalid_definition
mov al,1Ah
stos byte [edi]
mov ecx,edi
mov ax,5C01h
stos word [edi]
dec esi
group_predefinition_backslashes:
lods byte [esi]
cmp al,5Ch
jne predefinition_backslashed_symbol
stos byte [edi]
inc byte [ecx]
jmp group_predefinition_backslashes
predefinition_backslashed_symbol:
cmp al,20h
je invalid_definition
cmp al,22h
je invalid_definition
cmp al,27h
je invalid_definition
cmp al,3Bh
je invalid_definition
mov ah,al
mov ebx,characters
xlat byte [ebx]
or al,al
jz predefinition_backslashed_symbol_character
mov al,ah
convert_predefinition_backslashed_symbol:
stos byte [edi]
xlat byte [ebx]
or al,al
jz found_predefinition_separator
inc byte [ecx]
jz invalid_definition
lods byte [esi]
jmp convert_predefinition_backslashed_symbol
predefinition_backslashed_symbol_character:
mov al,ah
stos byte [edi]
inc byte [ecx]
jmp convert_predefinition
predefinition_converted:
mov [memory_start],edi
sub edi,[edx+8]
mov [edx+12],edi
jmp process_predefinitions
predefinitions_ok:
mov esi,[input_file]
mov edx,esi
call open
jc main_file_not_found
mov edi,[memory_start]
call preprocess_file
cmp [macro_status],0
je process_postponed
mov eax,[error_line]
mov [current_line],eax
jmp incomplete_macro
process_postponed:
mov edx,hash_tree
mov ecx,32
find_postponed_list:
mov edx,[edx]
or edx,edx
loopnz find_postponed_list
jz preprocessing_finished
process_postponed_list:
mov eax,[edx]
or eax,eax
jz preprocessing_finished
push edx
mov ebx,edx
find_earliest_postponed:
mov eax,[edx]
or eax,eax
jz earliest_postponed_found
mov ebx,edx
mov edx,eax
jmp find_earliest_postponed
earliest_postponed_found:
mov [ebx],eax
call use_postponed_macro
pop edx
cmp [macro_status],0
je process_postponed_list
mov eax,[error_line]
mov [current_line],eax
jmp incomplete_macro
preprocessing_finished:
mov [source_start],edi
ret
use_postponed_macro:
lea esi,[edi-1]
push ecx esi
mov [struc_name],0
jmp use_macro
 
preprocess_file:
push [memory_end]
push esi
mov al,2
xor edx,edx
call lseek
push eax
xor al,al
xor edx,edx
call lseek
pop ecx
mov edx,[memory_end]
dec edx
mov byte [edx],1Ah
sub edx,ecx
jc out_of_memory
mov esi,edx
cmp edx,edi
jbe out_of_memory
mov [memory_end],edx
call read
call close
pop edx
xor ecx,ecx
mov ebx,esi
preprocess_source:
inc ecx
mov [current_line],edi
mov eax,edx
stos dword [edi]
mov eax,ecx
stos dword [edi]
mov eax,esi
sub eax,ebx
stos dword [edi]
xor eax,eax
stos dword [edi]
push ebx edx
call convert_line
call preprocess_line
pop edx ebx
next_line:
cmp byte [esi-1],0
je file_end
cmp byte [esi-1],1Ah
jne preprocess_source
file_end:
pop [memory_end]
clc
ret
 
convert_line:
push ecx
test [macro_status],0Fh
jz convert_line_data
mov ax,3Bh
stos word [edi]
convert_line_data:
cmp edi,[memory_end]
jae out_of_memory
lods byte [esi]
cmp al,20h
je convert_line_data
cmp al,9
je convert_line_data
mov ah,al
mov ebx,characters
xlat byte [ebx]
or al,al
jz convert_separator
cmp ah,27h
je convert_string
cmp ah,22h
je convert_string
mov byte [edi],1Ah
scas word [edi]
xchg al,ah
stos byte [edi]
mov ebx,characters
xor ecx,ecx
convert_symbol:
lods byte [esi]
stos byte [edi]
xlat byte [ebx]
or al,al
loopnzd convert_symbol
neg ecx
cmp ecx,255
ja name_too_long
mov ebx,edi
sub ebx,ecx
mov byte [ebx-2],cl
found_separator:
dec edi
mov ah,[esi-1]
convert_separator:
xchg al,ah
cmp al,20h
jb control_character
je convert_line_data
symbol_character:
cmp al,3Bh
je ignore_comment
cmp al,5Ch
je backslash_character
stos byte [edi]
jmp convert_line_data
control_character:
cmp al,1Ah
je line_end
cmp al,0Dh
je cr_character
cmp al,0Ah
je lf_character
cmp al,9
je convert_line_data
or al,al
jnz symbol_character
jmp line_end
lf_character:
lods byte [esi]
cmp al,0Dh
je line_end
dec esi
jmp line_end
cr_character:
lods byte [esi]
cmp al,0Ah
je line_end
dec esi
jmp line_end
convert_string:
mov al,22h
stos byte [edi]
scas dword [edi]
mov ebx,edi
copy_string:
lods byte [esi]
stos byte [edi]
cmp al,0Ah
je no_end_quote
cmp al,0Dh
je no_end_quote
or al,al
jz no_end_quote
cmp al,1Ah
je no_end_quote
cmp al,ah
jne copy_string
lods byte [esi]
cmp al,ah
je copy_string
dec esi
dec edi
mov eax,edi
sub eax,ebx
mov [ebx-4],eax
jmp convert_line_data
backslash_character:
mov byte [edi],0
lods byte [esi]
cmp al,20h
je concatenate_lines
cmp al,9
je concatenate_lines
cmp al,1Ah
je unexpected_end_of_file
or al,al
jz unexpected_end_of_file
cmp al,0Ah
je concatenate_lf
cmp al,0Dh
je concatenate_cr
cmp al,3Bh
je find_concatenated_line
mov al,1Ah
stos byte [edi]
mov ecx,edi
mov ax,5C01h
stos word [edi]
dec esi
group_backslashes:
lods byte [esi]
cmp al,5Ch
jne backslashed_symbol
stos byte [edi]
inc byte [ecx]
jz name_too_long
jmp group_backslashes
no_end_quote:
mov byte [ebx-5],0
jmp missing_end_quote
backslashed_symbol:
cmp al,1Ah
je unexpected_end_of_file
or al,al
jz unexpected_end_of_file
cmp al,0Ah
je extra_characters_on_line
cmp al,0Dh
je extra_characters_on_line
cmp al,20h
je extra_characters_on_line
cmp al,9
je extra_characters_on_line
cmp al,22h
je extra_characters_on_line
cmp al,27h
je extra_characters_on_line
cmp al,3Bh
je extra_characters_on_line
mov ah,al
mov ebx,characters
xlat byte [ebx]
or al,al
jz backslashed_symbol_character
mov al,ah
convert_backslashed_symbol:
stos byte [edi]
xlat byte [ebx]
or al,al
jz found_separator
inc byte [ecx]
jz name_too_long
lods byte [esi]
jmp convert_backslashed_symbol
backslashed_symbol_character:
mov al,ah
stos byte [edi]
inc byte [ecx]
jmp convert_line_data
concatenate_lines:
lods byte [esi]
cmp al,20h
je concatenate_lines
cmp al,9
je concatenate_lines
cmp al,1Ah
je unexpected_end_of_file
or al,al
jz unexpected_end_of_file
cmp al,0Ah
je concatenate_lf
cmp al,0Dh
je concatenate_cr
cmp al,3Bh
jne extra_characters_on_line
find_concatenated_line:
lods byte [esi]
cmp al,0Ah
je concatenate_lf
cmp al,0Dh
je concatenate_cr
or al,al
jz concatenate_ok
cmp al,1Ah
jne find_concatenated_line
jmp unexpected_end_of_file
concatenate_lf:
lods byte [esi]
cmp al,0Dh
je concatenate_ok
dec esi
jmp concatenate_ok
concatenate_cr:
lods byte [esi]
cmp al,0Ah
je concatenate_ok
dec esi
concatenate_ok:
inc dword [esp]
jmp convert_line_data
ignore_comment:
lods byte [esi]
cmp al,0Ah
je lf_character
cmp al,0Dh
je cr_character
or al,al
jz line_end
cmp al,1Ah
jne ignore_comment
line_end:
xor al,al
stos byte [edi]
pop ecx
ret
 
lower_case:
mov edi,converted
mov ebx,characters
convert_case:
lods byte [esi]
xlat byte [ebx]
stos byte [edi]
loop convert_case
case_ok:
ret
 
get_directive:
push edi
mov edx,esi
mov ebp,ecx
call lower_case
pop edi
scan_directives:
mov esi,converted
movzx eax,byte [edi]
or al,al
jz no_directive
mov ecx,ebp
inc edi
mov ebx,edi
add ebx,eax
mov ah,[esi]
cmp ah,[edi]
jb no_directive
ja next_directive
cmp cl,al
jne next_directive
repe cmps byte [esi],[edi]
jb no_directive
je directive_ok
next_directive:
mov edi,ebx
add edi,2
jmp scan_directives
no_directive:
mov esi,edx
mov ecx,ebp
stc
ret
directive_ok:
lea esi,[edx+ebp]
call directive_handler
directive_handler:
pop ecx
movzx eax,word [ebx]
add eax,ecx
clc
ret
 
preprocess_line:
mov eax,esp
sub eax,100h
jc stack_overflow
cmp eax,[stack_limit]
jb stack_overflow
push ecx esi
preprocess_current_line:
mov esi,[current_line]
add esi,16
cmp word [esi],3Bh
jne line_start_ok
add esi,2
line_start_ok:
test [macro_status],0F0h
jnz macro_preprocessing
cmp byte [esi],1Ah
jne not_fix_constant
movzx edx,byte [esi+1]
lea edx,[esi+2+edx]
cmp word [edx],031Ah
jne not_fix_constant
mov ebx,characters
movzx eax,byte [edx+2]
xlat byte [ebx]
ror eax,8
mov al,[edx+3]
xlat byte [ebx]
ror eax,8
mov al,[edx+4]
xlat byte [ebx]
ror eax,16
cmp eax,'fix'
je define_fix_constant
not_fix_constant:
call process_fix_constants
jmp initial_preprocessing_ok
macro_preprocessing:
call process_macro_operators
initial_preprocessing_ok:
mov esi,[current_line]
add esi,16
mov al,[macro_status]
test al,2
jnz skip_macro_block
test al,1
jnz find_macro_block
preprocess_instruction:
mov [current_offset],esi
lods byte [esi]
movzx ecx,byte [esi]
inc esi
cmp al,1Ah
jne not_preprocessor_symbol
cmp cl,3
jb not_preprocessor_directive
push edi
mov edi,preprocessor_directives
call get_directive
pop edi
jc not_preprocessor_directive
mov byte [edx-2],3Bh
jmp near eax
not_preprocessor_directive:
xor ch,ch
call get_preprocessor_symbol
jc not_macro
mov byte [ebx-2],3Bh
mov [struc_name],0
jmp use_macro
not_macro:
mov [struc_name],esi
add esi,ecx
lods byte [esi]
cmp al,':'
je preprocess_label
cmp al,1Ah
jne not_preprocessor_symbol
lods byte [esi]
cmp al,3
jne not_symbolic_constant
mov ebx,characters
movzx eax,byte [esi]
xlat byte [ebx]
ror eax,8
mov al,[esi+1]
xlat byte [ebx]
ror eax,8
mov al,[esi+2]
xlat byte [ebx]
ror eax,16
cmp eax,'equ'
je define_equ_constant
mov al,3
not_symbolic_constant:
mov ch,1
mov cl,al
call get_preprocessor_symbol
jc not_preprocessor_symbol
push edx esi
mov esi,[struc_name]
mov [struc_label],esi
sub [struc_label],2
mov cl,[esi-1]
mov ch,10b
call get_preprocessor_symbol
jc struc_name_ok
mov ecx,[edx+12]
add ecx,3
lea ebx,[edi+ecx]
mov ecx,edi
sub ecx,[struc_label]
lea esi,[edi-1]
lea edi,[ebx-1]
std
rep movs byte [edi],[esi]
cld
mov edi,[struc_label]
mov esi,[edx+8]
mov ecx,[edx+12]
add [struc_name],ecx
add [struc_name],3
call move_data
mov al,3Ah
stos byte [edi]
mov ax,3Bh
stos word [edi]
mov edi,ebx
pop esi
add esi,[edx+12]
add esi,3
pop edx
jmp use_macro
struc_name_ok:
mov edx,[struc_name]
movzx eax,byte [edx-1]
add edx,eax
push edi
lea esi,[edi-1]
mov ecx,edi
sub ecx,edx
std
rep movs byte [edi],[esi]
cld
pop edi
inc edi
mov al,3Ah
mov [edx],al
inc al
mov [edx+1],al
pop esi edx
inc esi
jmp use_macro
preprocess_label:
dec esi
sub esi,ecx
lea ebp,[esi-2]
mov ch,10b
call get_preprocessor_symbol
jnc symbolic_constant_in_label
lea esi,[esi+ecx+1]
cmp byte [esi],':'
jne preprocess_instruction
inc esi
jmp preprocess_instruction
symbolic_constant_in_label:
mov ebx,[edx+8]
mov ecx,[edx+12]
add ecx,ebx
check_for_broken_label:
cmp ebx,ecx
je label_broken
cmp byte [ebx],1Ah
jne label_broken
movzx eax,byte [ebx+1]
lea ebx,[ebx+2+eax]
cmp ebx,ecx
je label_constant_ok
cmp byte [ebx],':'
jne label_broken
inc ebx
cmp byte [ebx],':'
jne check_for_broken_label
inc ebx
jmp check_for_broken_label
label_broken:
push line_preprocessed
jmp replace_symbolic_constant
label_constant_ok:
mov ecx,edi
sub ecx,esi
mov edi,[edx+12]
add edi,ebp
push edi
lea eax,[edi+ecx]
push eax
cmp esi,edi
je replace_label
jb move_rest_of_line_up
rep movs byte [edi],[esi]
jmp replace_label
move_rest_of_line_up:
lea esi,[esi+ecx-1]
lea edi,[edi+ecx-1]
std
rep movs byte [edi],[esi]
cld
replace_label:
mov ecx,[edx+12]
mov edi,[esp+4]
sub edi,ecx
mov esi,[edx+8]
rep movs byte [edi],[esi]
pop edi esi
inc esi
jmp preprocess_instruction
not_preprocessor_symbol:
mov esi,[current_offset]
call process_equ_constants
line_preprocessed:
pop esi ecx
ret
 
get_preprocessor_symbol:
push ebp edi esi
mov ebp,ecx
shl ebp,22
movzx ecx,cl
mov ebx,hash_tree
mov edi,10
follow_hashes_roots:
mov edx,[ebx]
or edx,edx
jz preprocessor_symbol_not_found
xor eax,eax
shl ebp,1
adc eax,0
lea ebx,[edx+eax*4]
dec edi
jnz follow_hashes_roots
mov edi,ebx
call calculate_hash
mov ebp,eax
and ebp,3FFh
shl ebp,10
xor ebp,eax
mov ebx,edi
mov edi,22
follow_hashes_tree:
mov edx,[ebx]
or edx,edx
jz preprocessor_symbol_not_found
xor eax,eax
shl ebp,1
adc eax,0
lea ebx,[edx+eax*4]
dec edi
jnz follow_hashes_tree
mov al,cl
mov edx,[ebx]
or edx,edx
jz preprocessor_symbol_not_found
compare_with_preprocessor_symbol:
mov edi,[edx+4]
cmp edi,1
jbe next_equal_hash
repe cmps byte [esi],[edi]
je preprocessor_symbol_found
mov cl,al
mov esi,[esp]
next_equal_hash:
mov edx,[edx]
or edx,edx
jnz compare_with_preprocessor_symbol
preprocessor_symbol_not_found:
pop esi edi ebp
stc
ret
preprocessor_symbol_found:
pop ebx edi ebp
clc
ret
calculate_hash:
xor ebx,ebx
mov eax,2166136261
mov ebp,16777619
fnv1a_hash:
xor al,[esi+ebx]
mul ebp
inc bl
cmp bl,cl
jb fnv1a_hash
ret
add_preprocessor_symbol:
push edi esi
xor eax,eax
or cl,cl
jz reshape_hash
cmp ch,11b
je preprocessor_symbol_name_ok
push ecx
movzx ecx,cl
mov edi,preprocessor_directives
call get_directive
jnc reserved_word_used_as_symbol
pop ecx
preprocessor_symbol_name_ok:
call calculate_hash
reshape_hash:
mov ebp,eax
and ebp,3FFh
shr eax,10
xor ebp,eax
shl ecx,22
or ebp,ecx
mov ebx,hash_tree
mov ecx,32
find_leave_for_symbol:
mov edx,[ebx]
or edx,edx
jz extend_hashes_tree
xor eax,eax
rol ebp,1
adc eax,0
lea ebx,[edx+eax*4]
dec ecx
jnz find_leave_for_symbol
mov edx,[ebx]
or edx,edx
jz add_symbol_entry
shr ebp,30
cmp ebp,11b
je reuse_symbol_entry
cmp dword [edx+4],0
jne add_symbol_entry
find_entry_to_reuse:
mov edi,[edx]
or edi,edi
jz reuse_symbol_entry
cmp dword [edi+4],0
jne reuse_symbol_entry
mov edx,edi
jmp find_entry_to_reuse
add_symbol_entry:
mov eax,edx
mov edx,[labels_list]
sub edx,16
cmp edx,[free_additional_memory]
jb out_of_memory
mov [labels_list],edx
mov [edx],eax
mov [ebx],edx
reuse_symbol_entry:
pop esi edi
mov [edx+4],esi
ret
extend_hashes_tree:
mov edx,[labels_list]
sub edx,8
cmp edx,[free_additional_memory]
jb out_of_memory
mov [labels_list],edx
xor eax,eax
mov [edx],eax
mov [edx+4],eax
shl ebp,1
adc eax,0
mov [ebx],edx
lea ebx,[edx+eax*4]
dec ecx
jnz extend_hashes_tree
mov edx,[labels_list]
sub edx,16
cmp edx,[free_additional_memory]
jb out_of_memory
mov [labels_list],edx
mov dword [edx],0
mov [ebx],edx
pop esi edi
mov [edx+4],esi
ret
 
define_fix_constant:
add edx,5
add esi,2
push edx
mov ch,11b
jmp define_preprocessor_constant
define_equ_constant:
add esi,3
push esi
call process_equ_constants
mov esi,[struc_name]
mov ch,10b
define_preprocessor_constant:
mov byte [esi-2],3Bh
mov cl,[esi-1]
call add_preprocessor_symbol
pop ebx
mov ecx,edi
dec ecx
sub ecx,ebx
mov [edx+8],ebx
mov [edx+12],ecx
jmp line_preprocessed
define_symbolic_constant:
lods byte [esi]
cmp al,1Ah
jne invalid_name
lods byte [esi]
mov cl,al
mov ch,10b
call add_preprocessor_symbol
movzx eax,byte [esi-1]
add esi,eax
lea ecx,[edi-1]
sub ecx,esi
mov [edx+8],esi
mov [edx+12],ecx
jmp line_preprocessed
 
define_struc:
mov ch,1
jmp make_macro
define_macro:
xor ch,ch
make_macro:
lods byte [esi]
cmp al,1Ah
jne invalid_name
lods byte [esi]
mov cl,al
call add_preprocessor_symbol
mov eax,[current_line]
mov [edx+12],eax
movzx eax,byte [esi-1]
add esi,eax
mov [edx+8],esi
mov al,[macro_status]
and al,0F0h
or al,1
mov [macro_status],al
mov eax,[current_line]
mov [error_line],eax
xor ebp,ebp
lods byte [esi]
or al,al
jz line_preprocessed
cmp al,'{'
je found_macro_block
dec esi
skip_macro_arguments:
lods byte [esi]
cmp al,1Ah
je skip_macro_argument
cmp al,'['
jne invalid_macro_arguments
or ebp,-1
jz invalid_macro_arguments
lods byte [esi]
cmp al,1Ah
jne invalid_macro_arguments
skip_macro_argument:
movzx eax,byte [esi]
inc esi
add esi,eax
lods byte [esi]
cmp al,':'
je macro_argument_with_default_value
cmp al,'='
je macro_argument_with_default_value
cmp al,'*'
jne macro_argument_end
lods byte [esi]
macro_argument_end:
cmp al,','
je skip_macro_arguments
cmp al,'&'
je macro_arguments_finisher
cmp al,']'
jne end_macro_arguments
not ebp
macro_arguments_finisher:
lods byte [esi]
end_macro_arguments:
or ebp,ebp
jnz invalid_macro_arguments
or al,al
jz line_preprocessed
cmp al,'{'
je found_macro_block
jmp invalid_macro_arguments
macro_argument_with_default_value:
or [skip_default_argument_value],-1
call skip_macro_argument_value
inc esi
jmp macro_argument_end
skip_macro_argument_value:
cmp byte [esi],'<'
jne simple_argument
mov ecx,1
inc esi
enclosed_argument:
lods byte [esi]
or al,al
jz invalid_macro_arguments
cmp al,1Ah
je enclosed_symbol
cmp al,22h
je enclosed_string
cmp al,'>'
je enclosed_argument_end
cmp al,'<'
jne enclosed_argument
inc ecx
jmp enclosed_argument
enclosed_symbol:
movzx eax,byte [esi]
inc esi
add esi,eax
jmp enclosed_argument
enclosed_string:
lods dword [esi]
add esi,eax
jmp enclosed_argument
enclosed_argument_end:
loop enclosed_argument
lods byte [esi]
or al,al
jz argument_value_end
cmp al,','
je argument_value_end
cmp [skip_default_argument_value],0
je invalid_macro_arguments
cmp al,'{'
je argument_value_end
cmp al,'&'
je argument_value_end
or ebp,ebp
jz invalid_macro_arguments
cmp al,']'
je argument_value_end
jmp invalid_macro_arguments
simple_argument:
lods byte [esi]
or al,al
jz argument_value_end
cmp al,','
je argument_value_end
cmp al,22h
je argument_string
cmp al,1Ah
je argument_symbol
cmp [skip_default_argument_value],0
je simple_argument
cmp al,'{'
je argument_value_end
cmp al,'&'
je argument_value_end
or ebp,ebp
jz simple_argument
cmp al,']'
je argument_value_end
argument_symbol:
movzx eax,byte [esi]
inc esi
add esi,eax
jmp simple_argument
argument_string:
lods dword [esi]
add esi,eax
jmp simple_argument
argument_value_end:
dec esi
ret
find_macro_block:
add esi,2
lods byte [esi]
or al,al
jz line_preprocessed
cmp al,'{'
jne unexpected_characters
found_macro_block:
or [macro_status],2
skip_macro_block:
lods byte [esi]
cmp al,1Ah
je skip_macro_symbol
cmp al,3Bh
je skip_macro_symbol
cmp al,22h
je skip_macro_string
or al,al
jz line_preprocessed
cmp al,'}'
jne skip_macro_block
mov al,[macro_status]
and [macro_status],0F0h
test al,8
jnz use_instant_macro
cmp byte [esi],0
je line_preprocessed
mov ecx,edi
sub ecx,esi
mov edx,esi
lea esi,[esi+ecx-1]
lea edi,[edi+1+16]
mov ebx,edi
dec edi
std
rep movs byte [edi],[esi]
cld
mov edi,edx
xor al,al
stos byte [edi]
mov esi,[current_line]
mov [current_line],edi
mov ecx,4
rep movs dword [edi],[esi]
mov edi,ebx
jmp initial_preprocessing_ok
skip_macro_symbol:
movzx eax,byte [esi]
inc esi
add esi,eax
jmp skip_macro_block
skip_macro_string:
lods dword [esi]
add esi,eax
jmp skip_macro_block
postpone_directive:
push esi
mov esi,edx
xor ecx,ecx
call add_preprocessor_symbol
mov eax,[current_line]
mov [error_line],eax
mov [edx+12],eax
pop esi
mov [edx+8],esi
mov al,[macro_status]
and al,0F0h
or al,1
mov [macro_status],al
lods byte [esi]
or al,al
jz line_preprocessed
cmp al,'{'
jne unexpected_characters
jmp found_macro_block
rept_directive:
mov [base_code],0
jmp define_instant_macro
irp_directive:
mov [base_code],1
jmp define_instant_macro
irps_directive:
mov [base_code],2
jmp define_instant_macro
irpv_directive:
mov [base_code],3
jmp define_instant_macro
match_directive:
mov [base_code],10h
define_instant_macro:
mov al,[macro_status]
and al,0F0h
or al,8+1
mov [macro_status],al
mov eax,[current_line]
mov [error_line],eax
mov [instant_macro_start],esi
cmp [base_code],10h
je prepare_match
skip_parameters:
lods byte [esi]
or al,al
jz parameters_skipped
cmp al,'{'
je parameters_skipped
cmp al,22h
je skip_quoted_parameter
cmp al,1Ah
jne skip_parameters
lods byte [esi]
movzx eax,al
add esi,eax
jmp skip_parameters
skip_quoted_parameter:
lods dword [esi]
add esi,eax
jmp skip_parameters
parameters_skipped:
dec esi
mov [parameters_end],esi
lods byte [esi]
cmp al,'{'
je found_macro_block
or al,al
jnz invalid_macro_arguments
jmp line_preprocessed
prepare_match:
call skip_pattern
mov [value_type],80h+10b
call process_symbolic_constants
jmp parameters_skipped
skip_pattern:
lods byte [esi]
or al,al
jz invalid_macro_arguments
cmp al,','
je pattern_skipped
cmp al,22h
je skip_quoted_string_in_pattern
cmp al,1Ah
je skip_symbol_in_pattern
cmp al,'='
jne skip_pattern
mov al,[esi]
cmp al,1Ah
je skip_pattern
cmp al,22h
je skip_pattern
inc esi
jmp skip_pattern
skip_symbol_in_pattern:
lods byte [esi]
movzx eax,al
add esi,eax
jmp skip_pattern
skip_quoted_string_in_pattern:
lods dword [esi]
add esi,eax
jmp skip_pattern
pattern_skipped:
ret
 
purge_macro:
xor ch,ch
jmp restore_preprocessor_symbol
purge_struc:
mov ch,1
jmp restore_preprocessor_symbol
restore_equ_constant:
mov ch,10b
restore_preprocessor_symbol:
push ecx
lods byte [esi]
cmp al,1Ah
jne invalid_name
lods byte [esi]
mov cl,al
call get_preprocessor_symbol
jc no_symbol_to_restore
mov dword [edx+4],0
jmp symbol_restored
no_symbol_to_restore:
add esi,ecx
symbol_restored:
pop ecx
lods byte [esi]
cmp al,','
je restore_preprocessor_symbol
or al,al
jnz extra_characters_on_line
jmp line_preprocessed
 
process_fix_constants:
mov [value_type],11b
jmp process_symbolic_constants
process_equ_constants:
mov [value_type],10b
process_symbolic_constants:
mov ebp,esi
lods byte [esi]
cmp al,1Ah
je check_symbol
cmp al,22h
je ignore_string
cmp al,'{'
je check_brace
or al,al
jnz process_symbolic_constants
ret
ignore_string:
lods dword [esi]
add esi,eax
jmp process_symbolic_constants
check_brace:
test [value_type],80h
jz process_symbolic_constants
ret
no_replacing:
movzx ecx,byte [esi-1]
add esi,ecx
jmp process_symbolic_constants
check_symbol:
mov cl,[esi]
inc esi
mov ch,[value_type]
call get_preprocessor_symbol
jc no_replacing
mov [current_section],edi
replace_symbolic_constant:
mov ecx,[edx+12]
mov edx,[edx+8]
xchg esi,edx
call move_data
mov esi,edx
process_after_replaced:
lods byte [esi]
cmp al,1Ah
je symbol_after_replaced
stos byte [edi]
cmp al,22h
je string_after_replaced
cmp al,'{'
je brace_after_replaced
or al,al
jnz process_after_replaced
mov ecx,edi
sub ecx,esi
mov edi,ebp
call move_data
mov esi,edi
ret
move_data:
lea eax,[edi+ecx]
cmp eax,[memory_end]
jae out_of_memory
shr ecx,1
jnc movsb_ok
movs byte [edi],[esi]
movsb_ok:
shr ecx,1
jnc movsw_ok
movs word [edi],[esi]
movsw_ok:
rep movs dword [edi],[esi]
ret
string_after_replaced:
lods dword [esi]
stos dword [edi]
mov ecx,eax
call move_data
jmp process_after_replaced
brace_after_replaced:
test [value_type],80h
jz process_after_replaced
mov edx,edi
mov ecx,[current_section]
sub edx,ecx
sub ecx,esi
rep movs byte [edi],[esi]
mov ecx,edi
sub ecx,esi
mov edi,ebp
call move_data
lea esi,[ebp+edx]
ret
symbol_after_replaced:
mov cl,[esi]
inc esi
mov ch,[value_type]
call get_preprocessor_symbol
jnc replace_symbolic_constant
movzx ecx,byte [esi-1]
mov al,1Ah
mov ah,cl
stos word [edi]
call move_data
jmp process_after_replaced
process_macro_operators:
xor dl,dl
mov ebp,edi
before_macro_operators:
mov edi,esi
lods byte [esi]
cmp al,'`'
je symbol_conversion
cmp al,'#'
je concatenation
cmp al,1Ah
je symbol_before_macro_operators
cmp al,3Bh
je no_more_macro_operators
cmp al,22h
je string_before_macro_operators
xor dl,dl
or al,al
jnz before_macro_operators
mov edi,esi
ret
no_more_macro_operators:
mov edi,ebp
ret
symbol_before_macro_operators:
mov dl,1Ah
mov ebx,esi
lods byte [esi]
movzx ecx,al
jecxz symbol_before_macro_operators_ok
mov edi,esi
cmp byte [esi],'\'
je escaped_symbol
symbol_before_macro_operators_ok:
add esi,ecx
jmp before_macro_operators
string_before_macro_operators:
mov dl,22h
mov ebx,esi
lods dword [esi]
add esi,eax
jmp before_macro_operators
escaped_symbol:
dec byte [edi-1]
dec ecx
inc esi
cmp ecx,1
rep movs byte [edi],[esi]
jne after_macro_operators
mov al,[esi-1]
mov ecx,ebx
mov ebx,characters
xlat byte [ebx]
mov ebx,ecx
or al,al
jnz after_macro_operators
sub edi,3
mov al,[esi-1]
stos byte [edi]
xor dl,dl
jmp after_macro_operators
reduce_symbol_conversion:
inc esi
symbol_conversion:
mov edx,esi
mov al,[esi]
cmp al,1Ah
jne symbol_character_conversion
lods word [esi]
movzx ecx,ah
lea ebx,[edi+3]
jecxz convert_to_quoted_string
cmp byte [esi],'\'
jne convert_to_quoted_string
inc esi
dec ecx
dec ebx
jmp convert_to_quoted_string
symbol_character_conversion:
cmp al,22h
je after_macro_operators
cmp al,'`'
je reduce_symbol_conversion
lea ebx,[edi+5]
xor ecx,ecx
or al,al
jz convert_to_quoted_string
cmp al,'#'
je convert_to_quoted_string
inc ecx
convert_to_quoted_string:
sub ebx,edx
ja shift_line_data
mov al,22h
mov dl,al
stos byte [edi]
mov ebx,edi
mov eax,ecx
stos dword [edi]
rep movs byte [edi],[esi]
cmp edi,esi
je before_macro_operators
jmp after_macro_operators
shift_line_data:
push ecx
mov edx,esi
lea esi,[ebp-1]
add ebp,ebx
lea edi,[ebp-1]
lea ecx,[esi+1]
sub ecx,edx
std
rep movs byte [edi],[esi]
cld
pop eax
sub edi,3
mov dl,22h
mov [edi-1],dl
mov ebx,edi
mov [edi],eax
lea esi,[edi+4+eax]
jmp before_macro_operators
concatenation:
cmp dl,1Ah
je symbol_concatenation
cmp dl,22h
je string_concatenation
no_concatenation:
cmp esi,edi
je before_macro_operators
jmp after_macro_operators
symbol_concatenation:
cmp byte [esi],1Ah
jne no_concatenation
inc esi
lods byte [esi]
movzx ecx,al
jecxz do_symbol_concatenation
cmp byte [esi],'\'
je concatenate_escaped_symbol
do_symbol_concatenation:
add [ebx],cl
jc name_too_long
rep movs byte [edi],[esi]
jmp after_macro_operators
concatenate_escaped_symbol:
inc esi
dec ecx
jz do_symbol_concatenation
movzx eax,byte [esi]
cmp byte [characters+eax],0
jne do_symbol_concatenation
sub esi,3
jmp no_concatenation
string_concatenation:
cmp byte [esi],22h
je do_string_concatenation
cmp byte [esi],'`'
jne no_concatenation
concatenate_converted_symbol:
inc esi
mov al,[esi]
cmp al,'`'
je concatenate_converted_symbol
cmp al,22h
je do_string_concatenation
cmp al,1Ah
jne concatenate_converted_symbol_character
inc esi
lods byte [esi]
movzx ecx,al
jecxz finish_concatenating_converted_symbol
cmp byte [esi],'\'
jne finish_concatenating_converted_symbol
inc esi
dec ecx
finish_concatenating_converted_symbol:
add [ebx],ecx
rep movs byte [edi],[esi]
jmp after_macro_operators
concatenate_converted_symbol_character:
or al,al
jz after_macro_operators
cmp al,'#'
je after_macro_operators
inc dword [ebx]
movs byte [edi],[esi]
jmp after_macro_operators
do_string_concatenation:
inc esi
lods dword [esi]
mov ecx,eax
add [ebx],eax
rep movs byte [edi],[esi]
after_macro_operators:
lods byte [esi]
cmp al,'`'
je symbol_conversion
cmp al,'#'
je concatenation
stos byte [edi]
cmp al,1Ah
je symbol_after_macro_operators
cmp al,3Bh
je no_more_macro_operators
cmp al,22h
je string_after_macro_operators
xor dl,dl
or al,al
jnz after_macro_operators
ret
symbol_after_macro_operators:
mov dl,1Ah
mov ebx,edi
lods byte [esi]
stos byte [edi]
movzx ecx,al
jecxz symbol_after_macro_operatorss_ok
cmp byte [esi],'\'
je escaped_symbol
symbol_after_macro_operatorss_ok:
rep movs byte [edi],[esi]
jmp after_macro_operators
string_after_macro_operators:
mov dl,22h
mov ebx,edi
lods dword [esi]
stos dword [edi]
mov ecx,eax
rep movs byte [edi],[esi]
jmp after_macro_operators
 
use_macro:
push [free_additional_memory]
push [macro_symbols]
mov [macro_symbols],0
push [counter_limit]
push dword [edx+4]
mov dword [edx+4],1
push edx
mov ebx,esi
mov esi,[edx+8]
mov eax,[edx+12]
mov [macro_line],eax
mov [counter_limit],0
xor ebp,ebp
process_macro_arguments:
mov al,[esi]
or al,al
jz arguments_end
cmp al,'{'
je arguments_end
inc esi
cmp al,'['
jne get_macro_arguments
mov ebp,esi
inc esi
inc [counter_limit]
get_macro_arguments:
call get_macro_argument
lods byte [esi]
cmp al,','
je next_argument
cmp al,']'
je next_arguments_group
cmp al,'&'
je arguments_end
dec esi
jmp arguments_end
next_argument:
cmp byte [ebx],','
jne process_macro_arguments
inc ebx
jmp process_macro_arguments
next_arguments_group:
cmp byte [ebx],','
jne arguments_end
inc ebx
inc [counter_limit]
mov esi,ebp
jmp process_macro_arguments
get_macro_argument:
lods byte [esi]
movzx ecx,al
mov eax,[counter_limit]
call add_macro_symbol
add esi,ecx
xor eax,eax
mov [default_argument_value],eax
cmp byte [esi],'*'
je required_value
cmp byte [esi],':'
je get_default_value
cmp byte [esi],'='
jne default_value_ok
get_default_value:
inc esi
mov [default_argument_value],esi
or [skip_default_argument_value],-1
call skip_macro_argument_value
jmp default_value_ok
required_value:
inc esi
or [default_argument_value],-1
default_value_ok:
xchg esi,ebx
mov [edx+12],esi
mov [skip_default_argument_value],0
cmp byte [ebx],'&'
je greedy_macro_argument
call skip_macro_argument_value
call finish_macro_argument
jmp got_macro_argument
greedy_macro_argument:
call skip_foreign_line
dec esi
mov eax,[edx+12]
mov ecx,esi
sub ecx,eax
mov [edx+8],ecx
got_macro_argument:
xchg esi,ebx
cmp dword [edx+8],0
jne macro_argument_ok
mov eax,[default_argument_value]
or eax,eax
jz macro_argument_ok
cmp eax,-1
je invalid_macro_arguments
mov [edx+12],eax
call finish_macro_argument
macro_argument_ok:
ret
finish_macro_argument:
mov eax,[edx+12]
mov ecx,esi
sub ecx,eax
cmp byte [eax],'<'
jne argument_value_length_ok
inc dword [edx+12]
sub ecx,2
or ecx,80000000h
argument_value_length_ok:
mov [edx+8],ecx
ret
arguments_end:
cmp byte [ebx],0
jne invalid_macro_arguments
mov eax,[esp+4]
dec eax
call process_macro
pop edx
pop dword [edx+4]
pop [counter_limit]
pop [macro_symbols]
pop [free_additional_memory]
jmp line_preprocessed
use_instant_macro:
push edi [current_line] esi
mov eax,[error_line]
mov [current_line],eax
mov [macro_line],eax
mov esi,[instant_macro_start]
cmp [base_code],10h
jae do_match
cmp [base_code],0
jne do_irp
call precalculate_value
cmp eax,0
jl value_out_of_range
push [free_additional_memory]
push [macro_symbols]
mov [macro_symbols],0
push [counter_limit]
mov [struc_name],0
mov [counter_limit],eax
lods byte [esi]
or al,al
jz rept_counters_ok
cmp al,'{'
je rept_counters_ok
cmp al,1Ah
jne invalid_macro_arguments
add_rept_counter:
lods byte [esi]
movzx ecx,al
xor eax,eax
call add_macro_symbol
add esi,ecx
xor eax,eax
mov dword [edx+12],eax
inc eax
mov dword [edx+8],eax
lods byte [esi]
cmp al,':'
jne rept_counter_added
push edx
call precalculate_value
mov edx,eax
add edx,[counter_limit]
jo value_out_of_range
pop edx
mov dword [edx+8],eax
lods byte [esi]
rept_counter_added:
cmp al,','
jne rept_counters_ok
lods byte [esi]
cmp al,1Ah
jne invalid_macro_arguments
jmp add_rept_counter
rept_counters_ok:
dec esi
cmp [counter_limit],0
je instant_macro_finish
instant_macro_parameters_ok:
xor eax,eax
call process_macro
instant_macro_finish:
pop [counter_limit]
pop [macro_symbols]
pop [free_additional_memory]
instant_macro_done:
pop ebx esi edx
cmp byte [ebx],0
je line_preprocessed
mov [current_line],edi
mov ecx,4
rep movs dword [edi],[esi]
test [macro_status],0Fh
jz instant_macro_attached_line
mov ax,3Bh
stos word [edi]
instant_macro_attached_line:
mov esi,ebx
sub edx,ebx
mov ecx,edx
call move_data
jmp initial_preprocessing_ok
precalculate_value:
push edi
call convert_expression
mov al,')'
stosb
push esi
mov esi,[esp+4]
mov [error_line],0
mov [value_size],0
call calculate_expression
cmp [error_line],0
je value_precalculated
jmp [error]
value_precalculated:
mov eax,[edi]
mov ecx,[edi+4]
cdq
cmp edx,ecx
jne value_out_of_range
cmp dl,[edi+13]
jne value_out_of_range
pop esi edi
ret
do_irp:
cmp byte [esi],1Ah
jne invalid_macro_arguments
movzx eax,byte [esi+1]
lea esi,[esi+2+eax]
lods byte [esi]
cmp [base_code],1
ja irps_name_ok
cmp al,':'
je irp_with_default_value
cmp al,'='
je irp_with_default_value
cmp al,'*'
jne irp_name_ok
lods byte [esi]
irp_name_ok:
cmp al,','
jne invalid_macro_arguments
jmp irp_parameters_start
irp_with_default_value:
xor ebp,ebp
or [skip_default_argument_value],-1
call skip_macro_argument_value
cmp byte [esi],','
jne invalid_macro_arguments
inc esi
jmp irp_parameters_start
irps_name_ok:
cmp al,','
jne invalid_macro_arguments
cmp [base_code],3
je irp_parameters_start
mov al,[esi]
or al,al
jz instant_macro_done
cmp al,'{'
je instant_macro_done
irp_parameters_start:
xor eax,eax
push [free_additional_memory]
push [macro_symbols]
mov [macro_symbols],eax
push [counter_limit]
mov [counter_limit],eax
mov [struc_name],eax
cmp [base_code],3
je get_irpv_parameter
mov ebx,esi
cmp [base_code],2
je get_irps_parameter
mov edx,[parameters_end]
mov al,[edx]
push eax
mov byte [edx],0
get_irp_parameter:
inc [counter_limit]
mov esi,[instant_macro_start]
inc esi
call get_macro_argument
cmp byte [ebx],','
jne irp_parameters_end
inc ebx
jmp get_irp_parameter
irp_parameters_end:
mov esi,ebx
pop eax
mov [esi],al
jmp instant_macro_parameters_ok
get_irps_parameter:
mov esi,[instant_macro_start]
inc esi
lods byte [esi]
movzx ecx,al
inc [counter_limit]
mov eax,[counter_limit]
call add_macro_symbol
mov [edx+12],ebx
cmp byte [ebx],1Ah
je irps_symbol
cmp byte [ebx],22h
je irps_quoted_string
mov eax,1
jmp irps_parameter_ok
irps_quoted_string:
mov eax,[ebx+1]
add eax,1+4
jmp irps_parameter_ok
irps_symbol:
movzx eax,byte [ebx+1]
add eax,1+1
irps_parameter_ok:
mov [edx+8],eax
add ebx,eax
cmp byte [ebx],0
je irps_parameters_end
cmp byte [ebx],'{'
jne get_irps_parameter
irps_parameters_end:
mov esi,ebx
jmp instant_macro_parameters_ok
get_irpv_parameter:
lods byte [esi]
cmp al,1Ah
jne invalid_macro_arguments
lods byte [esi]
mov ebp,esi
mov cl,al
mov ch,10b
call get_preprocessor_symbol
jc instant_macro_finish
push edx
mark_variable_value:
inc [counter_limit]
mov [edx+4],ebp
next_variable_value:
mov edx,[edx]
or edx,edx
jz variable_values_marked
mov eax,[edx+4]
cmp eax,1
jbe next_variable_value
mov esi,ebp
movzx ecx,byte [esi-1]
xchg edi,eax
repe cmps byte [esi],[edi]
xchg edi,eax
je mark_variable_value
jmp next_variable_value
variable_values_marked:
pop edx
push [counter_limit]
add_irpv_value:
push edx
mov esi,[instant_macro_start]
inc esi
lods byte [esi]
movzx ecx,al
mov eax,[esp+4]
call add_macro_symbol
mov ebx,edx
pop edx
mov ecx,[edx+12]
mov eax,[edx+8]
mov [ebx+12],eax
mov [ebx+8],ecx
collect_next_variable_value:
mov edx,[edx]
or edx,edx
jz variable_values_collected
cmp ebp,[edx+4]
jne collect_next_variable_value
dec dword [esp]
jnz add_irpv_value
variable_values_collected:
pop eax
mov esi,ebp
movzx ecx,byte [esi-1]
add esi,ecx
cmp byte [esi],0
je instant_macro_parameters_ok
cmp byte [esi],'{'
jne invalid_macro_arguments
jmp instant_macro_parameters_ok
 
do_match:
mov ebx,esi
call skip_pattern
call exact_match
mov edx,edi
mov al,[ebx]
cmp al,1Ah
je free_match
cmp al,','
jne instant_macro_done
cmp esi,[parameters_end]
je matched_pattern
jmp instant_macro_done
free_match:
add edx,12
cmp edx,[memory_end]
ja out_of_memory
mov [edx-12],ebx
mov [edx-8],esi
call skip_match_element
jc try_different_matching
mov [edx-4],esi
movzx eax,byte [ebx+1]
lea ebx,[ebx+2+eax]
cmp byte [ebx],1Ah
je free_match
find_exact_match:
call exact_match
cmp esi,[parameters_end]
je end_matching
cmp byte [ebx],1Ah
je free_match
mov ebx,[edx-12]
movzx eax,byte [ebx+1]
lea ebx,[ebx+2+eax]
mov esi,[edx-4]
jmp match_more_elements
try_different_matching:
sub edx,12
cmp edx,edi
je instant_macro_done
mov ebx,[edx-12]
movzx eax,byte [ebx+1]
lea ebx,[ebx+2+eax]
cmp byte [ebx],1Ah
je try_different_matching
mov esi,[edx-4]
match_more_elements:
call skip_match_element
jc try_different_matching
mov [edx-4],esi
jmp find_exact_match
skip_match_element:
cmp esi,[parameters_end]
je cannot_match
mov al,[esi]
cmp al,1Ah
je skip_match_symbol
cmp al,22h
je skip_match_quoted_string
add esi,1
ret
skip_match_quoted_string:
mov eax,[esi+1]
add esi,5
jmp skip_match_ok
skip_match_symbol:
movzx eax,byte [esi+1]
add esi,2
skip_match_ok:
add esi,eax
ret
cannot_match:
stc
ret
exact_match:
cmp esi,[parameters_end]
je exact_match_complete
mov ah,[esi]
mov al,[ebx]
cmp al,','
je exact_match_complete
cmp al,1Ah
je exact_match_complete
cmp al,'='
je match_verbatim
call match_elements
je exact_match
exact_match_complete:
ret
match_verbatim:
inc ebx
call match_elements
je exact_match
dec ebx
ret
match_elements:
mov al,[ebx]
cmp al,1Ah
je match_symbols
cmp al,22h
je match_quoted_strings
cmp al,ah
je symbol_characters_matched
ret
symbol_characters_matched:
lea ebx,[ebx+1]
lea esi,[esi+1]
ret
match_quoted_strings:
mov ecx,[ebx+1]
add ecx,5
jmp compare_elements
match_symbols:
movzx ecx,byte [ebx+1]
add ecx,2
compare_elements:
mov eax,esi
mov ebp,edi
mov edi,ebx
repe cmps byte [esi],[edi]
jne elements_mismatch
mov ebx,edi
mov edi,ebp
ret
elements_mismatch:
mov esi,eax
mov edi,ebp
ret
end_matching:
cmp byte [ebx],','
jne instant_macro_done
matched_pattern:
xor eax,eax
push [free_additional_memory]
push [macro_symbols]
mov [macro_symbols],eax
push [counter_limit]
mov [counter_limit],eax
mov [struc_name],eax
push esi edi edx
add_matched_symbol:
cmp edi,[esp]
je matched_symbols_ok
mov esi,[edi]
inc esi
lods byte [esi]
movzx ecx,al
xor eax,eax
call add_macro_symbol
mov eax,[edi+4]
mov dword [edx+12],eax
mov ecx,[edi+8]
sub ecx,eax
mov dword [edx+8],ecx
add edi,12
jmp add_matched_symbol
matched_symbols_ok:
pop edx edi esi
jmp instant_macro_parameters_ok
 
process_macro:
push dword [macro_status]
or [macro_status],10h
push [counter]
push [macro_block]
push [macro_block_line]
push [macro_block_line_number]
push [struc_label]
push [struc_name]
push eax
push [current_line]
lods byte [esi]
cmp al,'{'
je macro_instructions_start
or al,al
jnz unexpected_characters
find_macro_instructions:
mov [macro_line],esi
add esi,16+2
lods byte [esi]
or al,al
jz find_macro_instructions
cmp al,'{'
je macro_instructions_start
cmp al,3Bh
jne unexpected_characters
call skip_foreign_symbol
jmp find_macro_instructions
macro_instructions_start:
mov ecx,80000000h
mov [macro_block],esi
mov eax,[macro_line]
mov [macro_block_line],eax
mov [macro_block_line_number],ecx
xor eax,eax
mov [counter],eax
cmp [counter_limit],eax
je process_macro_line
inc [counter]
process_macro_line:
lods byte [esi]
or al,al
jz process_next_line
cmp al,'}'
je macro_block_processed
dec esi
mov [current_line],edi
lea eax,[edi+10h]
cmp eax,[memory_end]
jae out_of_memory
mov eax,[esp+4]
or eax,eax
jz instant_macro_line_header
stos dword [edi]
mov eax,ecx
stos dword [edi]
mov eax,[esp]
stos dword [edi]
mov eax,[macro_line]
stos dword [edi]
jmp macro_line_header_ok
instant_macro_line_header:
mov eax,[esp]
add eax,16
find_defining_directive:
inc eax
cmp byte [eax-1],3Bh
je defining_directive_ok
cmp byte [eax-1],1Ah
jne find_defining_directive
push eax
movzx eax,byte [eax]
inc eax
add [esp],eax
pop eax
jmp find_defining_directive
defining_directive_ok:
stos dword [edi]
mov eax,ecx
stos dword [edi]
mov eax,[macro_line]
stos dword [edi]
stos dword [edi]
macro_line_header_ok:
or [macro_status],20h
push ebx ecx
test [macro_status],0Fh
jz process_macro_line_element
mov ax,3Bh
stos word [edi]
process_macro_line_element:
lea eax,[edi+100h]
cmp eax,[memory_end]
jae out_of_memory
lods byte [esi]
cmp al,'}'
je macro_line_processed
or al,al
jz macro_line_processed
cmp al,1Ah
je process_macro_symbol
cmp al,3Bh
je macro_foreign_line
and [macro_status],not 20h
stos byte [edi]
cmp al,22h
jne process_macro_line_element
copy_macro_string:
mov ecx,[esi]
add ecx,4
call move_data
jmp process_macro_line_element
process_macro_symbol:
push esi edi
test [macro_status],20h
jz not_macro_directive
movzx ecx,byte [esi]
inc esi
mov edi,macro_directives
call get_directive
jnc process_macro_directive
dec esi
jmp not_macro_directive
process_macro_directive:
mov edx,eax
pop edi eax
mov byte [edi],0
inc edi
pop ecx ebx
jmp near edx
not_macro_directive:
and [macro_status],not 20h
movzx ecx,byte [esi]
inc esi
mov eax,[counter]
call get_macro_symbol
jnc group_macro_symbol
xor eax,eax
cmp [counter],eax
je multiple_macro_symbol_values
call get_macro_symbol
jc not_macro_symbol
replace_macro_symbol:
pop edi eax
mov ecx,[edx+8]
mov edx,[edx+12]
or edx,edx
jz replace_macro_counter
and ecx,not 80000000h
xchg esi,edx
call move_data
mov esi,edx
jmp process_macro_line_element
group_macro_symbol:
xor eax,eax
cmp [counter],eax
je replace_macro_symbol
push esi edx
sub esi,ecx
call get_macro_symbol
mov ebx,edx
pop edx esi
jc replace_macro_symbol
cmp edx,ebx
ja replace_macro_symbol
mov edx,ebx
jmp replace_macro_symbol
multiple_macro_symbol_values:
inc eax
push eax
call get_macro_symbol
pop eax
jc not_macro_symbol
pop edi
push ecx
mov ecx,[edx+8]
mov edx,[edx+12]
xchg esi,edx
btr ecx,31
jc enclose_macro_symbol_value
rep movs byte [edi],[esi]
jmp macro_symbol_value_ok
enclose_macro_symbol_value:
mov byte [edi],'<'
inc edi
rep movs byte [edi],[esi]
mov byte [edi],'>'
inc edi
macro_symbol_value_ok:
cmp eax,[counter_limit]
je multiple_macro_symbol_values_ok
mov byte [edi],','
inc edi
mov esi,edx
pop ecx
push edi
sub esi,ecx
jmp multiple_macro_symbol_values
multiple_macro_symbol_values_ok:
pop ecx eax
mov esi,edx
jmp process_macro_line_element
replace_macro_counter:
mov eax,[counter]
and eax,not 80000000h
jz group_macro_counter
add ecx,eax
dec ecx
call store_number_symbol
jmp process_macro_line_element
group_macro_counter:
mov edx,ecx
xor ecx,ecx
multiple_macro_counter_values:
push ecx edx
add ecx,edx
call store_number_symbol
pop edx ecx
inc ecx
cmp ecx,[counter_limit]
je process_macro_line_element
mov byte [edi],','
inc edi
jmp multiple_macro_counter_values
store_number_symbol:
cmp ecx,0
jge numer_symbol_sign_ok
neg ecx
mov al,'-'
stos byte [edi]
numer_symbol_sign_ok:
mov ax,1Ah
stos word [edi]
push edi
mov eax,ecx
mov ecx,1000000000
xor edx,edx
xor bl,bl
store_number_digits:
div ecx
push edx
or bl,bl
jnz store_number_digit
cmp ecx,1
je store_number_digit
or al,al
jz number_digit_ok
not bl
store_number_digit:
add al,30h
stos byte [edi]
number_digit_ok:
mov eax,ecx
xor edx,edx
mov ecx,10
div ecx
mov ecx,eax
pop eax
or ecx,ecx
jnz store_number_digits
pop ebx
mov eax,edi
sub eax,ebx
mov [ebx-1],al
ret
not_macro_symbol:
pop edi esi
mov al,1Ah
stos byte [edi]
mov al,[esi]
inc esi
stos byte [edi]
cmp byte [esi],'.'
jne copy_raw_symbol
mov ebx,[esp+8+8]
or ebx,ebx
jz copy_raw_symbol
cmp al,1
je copy_struc_name
xchg esi,ebx
movzx ecx,byte [esi-1]
add [edi-1],cl
jc name_too_long
rep movs byte [edi],[esi]
xchg esi,ebx
copy_raw_symbol:
movzx ecx,al
rep movs byte [edi],[esi]
jmp process_macro_line_element
copy_struc_name:
inc esi
xchg esi,ebx
movzx ecx,byte [esi-1]
mov [edi-1],cl
rep movs byte [edi],[esi]
xchg esi,ebx
mov eax,[esp+8+12]
cmp byte [eax],3Bh
je process_macro_line_element
cmp byte [eax],1Ah
jne disable_replaced_struc_name
mov byte [eax],3Bh
jmp process_macro_line_element
disable_replaced_struc_name:
mov ebx,[esp+8+8]
push esi edi
lea edi,[ebx-3]
lea esi,[edi-2]
lea ecx,[esi+1]
sub ecx,eax
std
rep movs byte [edi],[esi]
cld
mov word [eax],3Bh
pop edi esi
jmp process_macro_line_element
skip_foreign_symbol:
lods byte [esi]
movzx eax,al
add esi,eax
skip_foreign_line:
lods byte [esi]
cmp al,1Ah
je skip_foreign_symbol
cmp al,3Bh
je skip_foreign_symbol
cmp al,22h
je skip_foreign_string
or al,al
jnz skip_foreign_line
ret
skip_foreign_string:
lods dword [esi]
add esi,eax
jmp skip_foreign_line
macro_foreign_line:
call skip_foreign_symbol
macro_line_processed:
mov byte [edi],0
inc edi
push eax
call preprocess_line
pop eax
pop ecx ebx
cmp al,'}'
je macro_block_processed
process_next_line:
inc ecx
mov [macro_line],esi
add esi,16+2
jmp process_macro_line
macro_block_processed:
call close_macro_block
jc process_macro_line
pop [current_line]
add esp,12
pop [macro_block_line_number]
pop [macro_block_line]
pop [macro_block]
pop [counter]
pop eax
and al,0F0h
and [macro_status],0Fh
or [macro_status],al
ret
 
local_symbols:
lods byte [esi]
cmp al,1Ah
jne invalid_argument
mov byte [edi-1],3Bh
xor al,al
stos byte [edi]
make_local_symbol:
push ecx
lods byte [esi]
movzx ecx,al
mov eax,[counter]
call add_macro_symbol
mov [edx+12],edi
movzx eax,[locals_counter]
add eax,ecx
inc eax
cmp eax,100h
jae name_too_long
lea ebp,[edi+2+eax]
cmp ebp,[memory_end]
jae out_of_memory
mov ah,al
mov al,1Ah
stos word [edi]
rep movs byte [edi],[esi]
mov al,'?'
stos byte [edi]
push esi
mov esi,locals_counter+1
movzx ecx,[locals_counter]
rep movs byte [edi],[esi]
pop esi
mov eax,edi
sub eax,[edx+12]
mov [edx+8],eax
xor al,al
stos byte [edi]
mov eax,locals_counter
movzx ecx,byte [eax]
counter_loop:
inc byte [eax+ecx]
cmp byte [eax+ecx],'9'+1
jb counter_ok
jne letter_digit
mov byte [eax+ecx],'A'
jmp counter_ok
letter_digit:
cmp byte [eax+ecx],'Z'+1
jb counter_ok
jne small_letter_digit
mov byte [eax+ecx],'a'
jmp counter_ok
small_letter_digit:
cmp byte [eax+ecx],'z'+1
jb counter_ok
mov byte [eax+ecx],'0'
loop counter_loop
inc byte [eax]
movzx ecx,byte [eax]
mov byte [eax+ecx],'0'
counter_ok:
pop ecx
lods byte [esi]
cmp al,'}'
je macro_block_processed
or al,al
jz process_next_line
cmp al,','
jne extra_characters_on_line
dec edi
lods byte [esi]
cmp al,1Ah
je make_local_symbol
jmp invalid_argument
common_block:
call close_macro_block
jc process_macro_line
mov [counter],0
jmp new_macro_block
forward_block:
cmp [counter_limit],0
je common_block
call close_macro_block
jc process_macro_line
mov [counter],1
jmp new_macro_block
reverse_block:
cmp [counter_limit],0
je common_block
call close_macro_block
jc process_macro_line
mov eax,[counter_limit]
or eax,80000000h
mov [counter],eax
new_macro_block:
mov [macro_block],esi
mov eax,[macro_line]
mov [macro_block_line],eax
mov [macro_block_line_number],ecx
jmp process_macro_line
close_macro_block:
cmp esi,[macro_block]
je block_closed
cmp [counter],0
je block_closed
jl reverse_counter
mov eax,[counter]
cmp eax,[counter_limit]
je block_closed
inc [counter]
jmp continue_block
reverse_counter:
mov eax,[counter]
dec eax
cmp eax,80000000h
je block_closed
mov [counter],eax
continue_block:
mov esi,[macro_block]
mov eax,[macro_block_line]
mov [macro_line],eax
mov ecx,[macro_block_line_number]
stc
ret
block_closed:
clc
ret
get_macro_symbol:
push ecx
call find_macro_symbol_leaf
jc macro_symbol_not_found
mov edx,[ebx]
mov ebx,esi
try_macro_symbol:
or edx,edx
jz macro_symbol_not_found
mov ecx,[esp]
mov edi,[edx+4]
repe cmps byte [esi],[edi]
je macro_symbol_found
mov esi,ebx
mov edx,[edx]
jmp try_macro_symbol
macro_symbol_found:
pop ecx
clc
ret
macro_symbol_not_found:
pop ecx
stc
ret
find_macro_symbol_leaf:
shl eax,8
mov al,cl
mov ebp,eax
mov ebx,macro_symbols
follow_macro_symbols_tree:
mov edx,[ebx]
or edx,edx
jz no_such_macro_symbol
xor eax,eax
shr ebp,1
adc eax,0
lea ebx,[edx+eax*4]
or ebp,ebp
jnz follow_macro_symbols_tree
add ebx,8
clc
ret
no_such_macro_symbol:
stc
ret
add_macro_symbol:
push ebx ebp
call find_macro_symbol_leaf
jc extend_macro_symbol_tree
mov eax,[ebx]
make_macro_symbol:
mov edx,[free_additional_memory]
add edx,16
cmp edx,[labels_list]
ja out_of_memory
xchg edx,[free_additional_memory]
mov [ebx],edx
mov [edx],eax
mov [edx+4],esi
pop ebp ebx
ret
extend_macro_symbol_tree:
mov edx,[free_additional_memory]
add edx,16
cmp edx,[labels_list]
ja out_of_memory
xchg edx,[free_additional_memory]
xor eax,eax
mov [edx],eax
mov [edx+4],eax
mov [edx+8],eax
mov [edx+12],eax
shr ebp,1
adc eax,0
mov [ebx],edx
lea ebx,[edx+eax*4]
or ebp,ebp
jnz extend_macro_symbol_tree
add ebx,8
xor eax,eax
jmp make_macro_symbol
 
include_file:
lods byte [esi]
cmp al,22h
jne invalid_argument
lods dword [esi]
cmp byte [esi+eax],0
jne extra_characters_on_line
push esi
push edi
mov ebx,[current_line]
find_current_file_path:
mov esi,[ebx]
test byte [ebx+7],80h
jz copy_current_file_path
mov ebx,[ebx+8]
jmp find_current_file_path
copy_current_file_path:
lods byte [esi]
stos byte [edi]
or al,al
jnz copy_current_file_path
cut_current_file_name:
cmp edi,[esp]
je current_file_path_ok
cmp byte [edi-1],'\'
je current_file_path_ok
cmp byte [edi-1],'/'
je current_file_path_ok
dec edi
jmp cut_current_file_name
current_file_path_ok:
mov esi,[esp+4]
call expand_path
pop edx
mov esi,edx
call open
jnc include_path_ok
mov ebp,[include_paths]
try_include_directories:
mov edi,esi
mov esi,ebp
cmp byte [esi],0
je try_in_current_directory
push ebp
push edi
call get_include_directory
mov [esp+4],esi
mov esi,[esp+8]
call expand_path
pop edx
mov esi,edx
call open
pop ebp
jnc include_path_ok
jmp try_include_directories
mov edi,esi
try_in_current_directory:
mov esi,[esp]
push edi
call expand_path
pop edx
mov esi,edx
call open
jc file_not_found
include_path_ok:
mov edi,[esp]
copy_preprocessed_path:
lods byte [esi]
stos byte [edi]
or al,al
jnz copy_preprocessed_path
pop esi
lea ecx,[edi-1]
sub ecx,esi
mov [esi-4],ecx
push dword [macro_status]
and [macro_status],0Fh
call preprocess_file
pop eax
and al,0F0h
and [macro_status],0Fh
or [macro_status],al
jmp line_preprocessed
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/symbdump.inc
0,0 → 1,450
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
dump_symbols:
mov edi,[code_start]
call setup_dump_header
mov esi,[input_file]
call copy_asciiz
cmp edi,[tagged_blocks]
jae out_of_memory
mov eax,edi
sub eax,ebx
mov [ebx-40h+0Ch],eax
mov esi,[output_file]
call copy_asciiz
cmp edi,[tagged_blocks]
jae out_of_memory
mov edx,[symbols_stream]
mov ebp,[free_additional_memory]
and [number_of_sections],0
cmp [output_format],4
je prepare_strings_table
cmp [output_format],5
jne strings_table_ready
bt [format_flags],0
jc strings_table_ready
prepare_strings_table:
cmp edx,ebp
je strings_table_ready
mov al,[edx]
test al,al
jz prepare_string
cmp al,80h
je prepare_string
add edx,0Ch
cmp al,0C0h
jb prepare_strings_table
add edx,4
jmp prepare_strings_table
prepare_string:
mov esi,edi
sub esi,ebx
xchg esi,[edx+4]
test al,al
jz prepare_section_string
or dword [edx+4],1 shl 31
add edx,0Ch
prepare_external_string:
mov ecx,[esi]
add esi,4
rep movs byte [edi],[esi]
mov byte [edi],0
inc edi
cmp edi,[tagged_blocks]
jae out_of_memory
jmp prepare_strings_table
prepare_section_string:
mov ecx,[number_of_sections]
mov eax,ecx
inc eax
mov [number_of_sections],eax
xchg eax,[edx+4]
shl ecx,2
add ecx,[free_additional_memory]
mov [ecx],eax
add edx,20h
test esi,esi
jz prepare_default_section_string
cmp [output_format],5
jne prepare_external_string
bt [format_flags],0
jc prepare_external_string
mov esi,[esi]
add esi,[resource_data]
copy_elf_section_name:
lods byte [esi]
cmp edi,[tagged_blocks]
jae out_of_memory
stos byte [edi]
test al,al
jnz copy_elf_section_name
jmp prepare_strings_table
prepare_default_section_string:
mov eax,'.fla'
stos dword [edi]
mov ax,'t'
stos word [edi]
cmp edi,[tagged_blocks]
jae out_of_memory
jmp prepare_strings_table
strings_table_ready:
mov edx,[tagged_blocks]
mov ebp,[memory_end]
sub ebp,[labels_list]
add ebp,edx
prepare_labels_dump:
cmp edx,ebp
je labels_dump_ok
mov eax,[edx+24]
test eax,eax
jz label_dump_name_ok
cmp eax,[memory_start]
jb label_name_outside_source
cmp eax,[source_start]
ja label_name_outside_source
sub eax,[memory_start]
dec eax
mov [edx+24],eax
jmp label_dump_name_ok
label_name_outside_source:
mov esi,eax
mov eax,edi
sub eax,ebx
or eax,1 shl 31
mov [edx+24],eax
movzx ecx,byte [esi-1]
lea eax,[edi+ecx+1]
cmp edi,[tagged_blocks]
jae out_of_memory
rep movsb
xor al,al
stosb
label_dump_name_ok:
mov eax,[edx+28]
test eax,eax
jz label_dump_line_ok
sub eax,[memory_start]
mov [edx+28],eax
label_dump_line_ok:
test byte [edx+9],4
jz convert_base_symbol_for_label
xor eax,eax
mov [edx],eax
mov [edx+4],eax
jmp base_symbol_for_label_ok
convert_base_symbol_for_label:
mov eax,[edx+20]
test eax,eax
jz base_symbol_for_label_ok
cmp eax,[symbols_stream]
mov eax,[eax+4]
jae base_symbol_for_label_ok
xor eax,eax
base_symbol_for_label_ok:
mov [edx+20],eax
mov ax,[current_pass]
cmp ax,[edx+16]
je label_defined_flag_ok
and byte [edx+8],not 1
label_defined_flag_ok:
cmp ax,[edx+18]
je label_used_flag_ok
and byte [edx+8],not 8
label_used_flag_ok:
add edx,LABEL_STRUCTURE_SIZE
jmp prepare_labels_dump
labels_dump_ok:
mov eax,edi
sub eax,ebx
mov [ebx-40h+14h],eax
add eax,40h
mov [ebx-40h+18h],eax
mov ecx,[memory_end]
sub ecx,[labels_list]
mov [ebx-40h+1Ch],ecx
add eax,ecx
mov [ebx-40h+20h],eax
mov ecx,[source_start]
sub ecx,[memory_start]
mov [ebx-40h+24h],ecx
add eax,ecx
mov [ebx-40h+28h],eax
mov eax,[number_of_sections]
shl eax,2
mov [ebx-40h+34h],eax
call prepare_preprocessed_source
mov esi,[labels_list]
mov ebp,edi
make_lines_dump:
cmp esi,[tagged_blocks]
je lines_dump_ok
mov eax,[esi-4]
mov ecx,[esi-8]
sub esi,8
sub esi,ecx
cmp eax,1
je process_line_dump
cmp eax,2
jne make_lines_dump
add dword [ebx-40h+3Ch],8
jmp make_lines_dump
process_line_dump:
push ebx
mov ebx,[esi+8]
mov eax,[esi+4]
sub eax,[code_start]
add eax,[headers_size]
test byte [ebx+0Ah],1
jz store_offset
xor eax,eax
store_offset:
stos dword [edi]
mov eax,[esi]
sub eax,[memory_start]
stos dword [edi]
mov eax,[esi+4]
xor edx,edx
xor cl,cl
sub eax,[ebx]
sbb edx,[ebx+4]
sbb cl,[ebx+8]
stos dword [edi]
mov eax,edx
stos dword [edi]
mov eax,[ebx+10h]
stos dword [edi]
mov eax,[ebx+14h]
test eax,eax
jz base_symbol_for_line_ok
cmp eax,[symbols_stream]
mov eax,[eax+4]
jae base_symbol_for_line_ok
xor eax,eax
base_symbol_for_line_ok:
stos dword [edi]
mov al,[ebx+9]
stos byte [edi]
mov al,[esi+10h]
stos byte [edi]
mov al,[ebx+0Ah]
and al,1
stos byte [edi]
mov al,cl
stos byte [edi]
pop ebx
cmp edi,[tagged_blocks]
jae out_of_memory
mov eax,edi
sub eax,1Ch
sub eax,ebp
mov [esi],eax
jmp make_lines_dump
lines_dump_ok:
mov edx,edi
mov eax,[current_offset]
sub eax,[code_start]
add eax,[headers_size]
stos dword [edi]
mov ecx,edi
sub ecx,ebx
sub ecx,[ebx-40h+14h]
mov [ebx-40h+2Ch],ecx
add ecx,[ebx-40h+28h]
mov [ebx-40h+30h],ecx
add ecx,[ebx-40h+34h]
mov [ebx-40h+38h],ecx
find_inexisting_offsets:
sub edx,1Ch
cmp edx,ebp
jb write_symbols
test byte [edx+1Ah],1
jnz find_inexisting_offsets
cmp eax,[edx]
jb correct_inexisting_offset
mov eax,[edx]
jmp find_inexisting_offsets
correct_inexisting_offset:
and dword [edx],0
or byte [edx+1Ah],2
jmp find_inexisting_offsets
write_symbols:
mov edx,[symbols_file]
call create
jc write_failed
mov edx,[code_start]
mov ecx,[edx+14h]
add ecx,40h
call write
jc write_failed
mov edx,[tagged_blocks]
mov ecx,[memory_end]
sub ecx,[labels_list]
call write
jc write_failed
mov edx,[memory_start]
mov ecx,[source_start]
sub ecx,edx
call write
jc write_failed
mov edx,ebp
mov ecx,edi
sub ecx,edx
call write
jc write_failed
mov edx,[free_additional_memory]
mov ecx,[number_of_sections]
shl ecx,2
call write
jc write_failed
mov esi,[labels_list]
mov edi,[memory_start]
make_references_dump:
cmp esi,[tagged_blocks]
je references_dump_ok
mov eax,[esi-4]
mov ecx,[esi-8]
sub esi,8
sub esi,ecx
cmp eax,2
je dump_reference
cmp eax,1
jne make_references_dump
mov edx,[esi]
jmp make_references_dump
dump_reference:
mov eax,[memory_end]
sub eax,[esi]
sub eax,LABEL_STRUCTURE_SIZE
stosd
mov eax,edx
stosd
cmp edi,[tagged_blocks]
jb make_references_dump
jmp out_of_memory
references_dump_ok:
mov edx,[memory_start]
mov ecx,edi
sub ecx,edx
call write
jc write_failed
call close
ret
setup_dump_header:
xor eax,eax
mov ecx,40h shr 2
rep stos dword [edi]
mov ebx,edi
mov dword [ebx-40h],'fas'+1Ah shl 24
mov dword [ebx-40h+4],VERSION_MAJOR + VERSION_MINOR shl 8 + 40h shl 16
mov dword [ebx-40h+10h],40h
ret
prepare_preprocessed_source:
mov esi,[memory_start]
mov ebp,[source_start]
test ebp,ebp
jnz prepare_preprocessed_line
mov ebp,[current_line]
inc ebp
prepare_preprocessed_line:
cmp esi,ebp
jae preprocessed_source_ok
mov eax,[memory_start]
mov edx,[input_file]
cmp [esi],edx
jne line_not_from_main_input
mov [esi],eax
line_not_from_main_input:
sub [esi],eax
test byte [esi+7],1 shl 7
jz prepare_next_preprocessed_line
sub [esi+8],eax
sub [esi+12],eax
prepare_next_preprocessed_line:
call skip_preprocessed_line
jmp prepare_preprocessed_line
preprocessed_source_ok:
ret
skip_preprocessed_line:
add esi,16
skip_preprocessed_line_content:
lods byte [esi]
cmp al,1Ah
je skip_preprocessed_symbol
cmp al,3Bh
je skip_preprocessed_symbol
cmp al,22h
je skip_preprocessed_string
or al,al
jnz skip_preprocessed_line_content
ret
skip_preprocessed_string:
lods dword [esi]
add esi,eax
jmp skip_preprocessed_line_content
skip_preprocessed_symbol:
lods byte [esi]
movzx eax,al
add esi,eax
jmp skip_preprocessed_line_content
restore_preprocessed_source:
mov esi,[memory_start]
mov ebp,[source_start]
test ebp,ebp
jnz restore_preprocessed_line
mov ebp,[current_line]
inc ebp
restore_preprocessed_line:
cmp esi,ebp
jae preprocessed_source_restored
mov eax,[memory_start]
add [esi],eax
cmp [esi],eax
jne preprocessed_line_source_restored
mov edx,[input_file]
mov [esi],edx
preprocessed_line_source_restored:
test byte [esi+7],1 shl 7
jz restore_next_preprocessed_line
add [esi+8],eax
add [esi+12],eax
restore_next_preprocessed_line:
call skip_preprocessed_line
jmp restore_preprocessed_line
preprocessed_source_restored:
ret
dump_preprocessed_source:
mov edi,[free_additional_memory]
call setup_dump_header
mov esi,[input_file]
call copy_asciiz
cmp edi,[additional_memory_end]
jae out_of_memory
mov eax,edi
sub eax,ebx
dec eax
mov [ebx-40h+0Ch],eax
mov eax,edi
sub eax,ebx
mov [ebx-40h+14h],eax
add eax,40h
mov [ebx-40h+20h],eax
call prepare_preprocessed_source
sub esi,[memory_start]
mov [ebx-40h+24h],esi
mov edx,[symbols_file]
call create
jc write_failed
mov edx,[free_additional_memory]
mov ecx,[edx+14h]
add ecx,40h
call write
jc write_failed
mov edx,[memory_start]
mov ecx,esi
call write
jc write_failed
call close
ret
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/tables.inc
0,0 → 1,4228
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
include_variable db 'INCLUDE',0
 
symbol_characters db 27
db 9,0Ah,0Dh,1Ah,20h,'+-/*=<>()[]{}:,|&~#`;\'
 
preprocessor_directives:
db 6,'define'
dw define_symbolic_constant-directive_handler
db 7,'include'
dw include_file-directive_handler
db 3,'irp'
dw irp_directive-directive_handler
db 4,'irps'
dw irps_directive-directive_handler
db 4,'irpv'
dw irpv_directive-directive_handler
db 5,'macro'
dw define_macro-directive_handler
db 5,'match'
dw match_directive-directive_handler
db 8,'postpone'
dw postpone_directive-directive_handler
db 5,'purge'
dw purge_macro-directive_handler
db 4,'rept'
dw rept_directive-directive_handler
db 7,'restore'
dw restore_equ_constant-directive_handler
db 7,'restruc'
dw purge_struc-directive_handler
db 5,'struc'
dw define_struc-directive_handler
db 0
 
macro_directives:
db 6,'common'
dw common_block-directive_handler
db 7,'forward'
dw forward_block-directive_handler
db 5,'local'
dw local_symbols-directive_handler
db 7,'reverse'
dw reverse_block-directive_handler
db 0
 
operators:
db 1,'+',80h
db 1,'-',81h
db 1,'*',90h
db 1,'/',91h
db 3,'and',0B0h
db 3,'mod',0A0h
db 2,'or',0B1h
db 3,'shl',0C0h
db 3,'shr',0C1h
db 3,'xor',0B2h
db 0
 
single_operand_operators:
db 1,'+',82h
db 1,'-',83h
db 3,'bsf',0E0h
db 3,'bsr',0E1h
db 3,'not',0D0h
db 3,'plt',0F1h
db 3,'rva',0F0h
db 0
 
directive_operators:
db 5,'align',8Ch
db 2,'as',86h
db 2,'at',80h
db 7,'defined',88h
db 3,'dup',81h
db 2,'eq',0F0h
db 6,'eqtype',0F7h
db 4,'from',82h
db 2,'in',0F6h
db 2,'on',84h
db 3,'ptr',85h
db 10,'relativeto',0F8h
db 4,'used',89h
db 0
 
address_sizes:
db 4,'byte',1
db 5,'dword',4
db 5,'qword',8
db 4,'word',2
db 0
 
symbols:
dw symbols_1-symbols,(symbols_2-symbols_1)/(1+2)
dw symbols_2-symbols,(symbols_3-symbols_2)/(2+2)
dw symbols_3-symbols,(symbols_4-symbols_3)/(3+2)
dw symbols_4-symbols,(symbols_5-symbols_4)/(4+2)
dw symbols_5-symbols,(symbols_6-symbols_5)/(5+2)
dw symbols_6-symbols,(symbols_7-symbols_6)/(6+2)
dw symbols_7-symbols,(symbols_8-symbols_7)/(7+2)
dw symbols_8-symbols,(symbols_9-symbols_8)/(8+2)
dw symbols_9-symbols,(symbols_10-symbols_9)/(9+2)
dw symbols_10-symbols,(symbols_11-symbols_10)/(10+2)
dw symbols_11-symbols,(symbols_end-symbols_11)/(11+2)
 
symbols_1:
db 'z',1Fh,0
symbols_2:
db 'ah',10h,04h
db 'al',10h,10h
db 'ax',10h,20h
db 'bh',10h,07h
db 'bl',10h,13h
db 'bp',10h,25h
db 'bx',10h,23h
db 'ch',10h,05h
db 'cl',10h,11h
db 'cs',10h,32h
db 'cx',10h,21h
db 'dh',10h,06h
db 'di',10h,27h
db 'dl',10h,12h
db 'ds',10h,34h
db 'dx',10h,22h
db 'es',10h,31h
db 'fs',10h,35h
db 'gs',10h,36h
db 'k0',14h,50h
db 'k1',14h,51h
db 'k2',14h,52h
db 'k3',14h,53h
db 'k4',14h,54h
db 'k5',14h,55h
db 'k6',14h,56h
db 'k7',14h,57h
db 'ms',1Ch,41h
db 'mz',18h,20h
db 'nx',1Bh,83h
db 'pe',18h,30h
db 'r8',10h,88h
db 'r9',10h,89h
db 'rd',1Fh,21h
db 'rn',1Fh,20h
db 'ru',1Fh,22h
db 'rz',1Fh,23h
db 'si',10h,26h
db 'sp',10h,24h
db 'ss',10h,33h
db 'st',10h,0A0h
symbols_3:
db 'bpl',10h,15h
db 'cr0',14h,00h
db 'cr1',14h,01h
db 'cr2',14h,02h
db 'cr3',14h,03h
db 'cr4',14h,04h
db 'cr5',14h,05h
db 'cr6',14h,06h
db 'cr7',14h,07h
db 'cr8',14h,08h
db 'cr9',14h,09h
db 'dil',10h,17h
db 'dll',1Bh,80h
db 'dr0',14h,10h
db 'dr1',14h,11h
db 'dr2',14h,12h
db 'dr3',14h,13h
db 'dr4',14h,14h
db 'dr5',14h,15h
db 'dr6',14h,16h
db 'dr7',14h,17h
db 'dr8',14h,18h
db 'dr9',14h,19h
db 'eax',10h,40h
db 'ebp',10h,45h
db 'ebx',10h,43h
db 'ecx',10h,41h
db 'edi',10h,47h
db 'edx',10h,42h
db 'efi',1Bh,10
db 'eip',10h,94h
db 'elf',18h,50h
db 'esi',10h,46h
db 'esp',10h,44h
db 'far',12h,3
db 'gui',1Bh,2
db 'mm0',10h,0B0h
db 'mm1',10h,0B1h
db 'mm2',10h,0B2h
db 'mm3',10h,0B3h
db 'mm4',10h,0B4h
db 'mm5',10h,0B5h
db 'mm6',10h,0B6h
db 'mm7',10h,0B7h
db 'r10',10h,8Ah
db 'r11',10h,8Bh
db 'r12',10h,8Ch
db 'r13',10h,8Dh
db 'r14',10h,8Eh
db 'r15',10h,8Fh
db 'r8b',10h,18h
db 'r8d',10h,48h
db 'r8l',10h,18h
db 'r8w',10h,28h
db 'r9b',10h,19h
db 'r9d',10h,49h
db 'r9l',10h,19h
db 'r9w',10h,29h
db 'rax',10h,80h
db 'rbp',10h,85h
db 'rbx',10h,83h
db 'rcx',10h,81h
db 'rdi',10h,87h
db 'rdx',10h,82h
db 'rip',10h,98h
db 'rsi',10h,86h
db 'rsp',10h,84h
db 'sae',1Fh,30h
db 'sil',10h,16h
db 'spl',10h,14h
db 'st0',10h,0A0h
db 'st1',10h,0A1h
db 'st2',10h,0A2h
db 'st3',10h,0A3h
db 'st4',10h,0A4h
db 'st5',10h,0A5h
db 'st6',10h,0A6h
db 'st7',10h,0A7h
db 'tr0',14h,40h
db 'tr1',14h,41h
db 'tr2',14h,42h
db 'tr3',14h,43h
db 'tr4',14h,44h
db 'tr5',14h,45h
db 'tr6',14h,46h
db 'tr7',14h,47h
db 'wdm',1Bh,81h
symbols_4:
db '1to2',1Fh,11h
db '1to4',1Fh,12h
db '1to8',1Fh,13h
db 'bnd0',14h,60h
db 'bnd1',14h,61h
db 'bnd2',14h,62h
db 'bnd3',14h,63h
db 'byte',11h,1
db 'code',19h,5
db 'coff',18h,40h
db 'cr10',14h,0Ah
db 'cr11',14h,0Bh
db 'cr12',14h,0Ch
db 'cr13',14h,0Dh
db 'cr14',14h,0Eh
db 'cr15',14h,0Fh
db 'data',19h,6
db 'dr10',14h,1Ah
db 'dr11',14h,1Bh
db 'dr12',14h,1Ch
db 'dr13',14h,1Dh
db 'dr14',14h,1Eh
db 'dr15',14h,1Fh
db 'ms64',1Ch,49h
db 'near',12h,2
db 'note',1Eh,4
db 'pe64',18h,3Ch
db 'r10b',10h,1Ah
db 'r10d',10h,4Ah
db 'r10l',10h,1Ah
db 'r10w',10h,2Ah
db 'r11b',10h,1Bh
db 'r11d',10h,4Bh
db 'r11l',10h,1Bh
db 'r11w',10h,2Bh
db 'r12b',10h,1Ch
db 'r12d',10h,4Ch
db 'r12l',10h,1Ch
db 'r12w',10h,2Ch
db 'r13b',10h,1Dh
db 'r13d',10h,4Dh
db 'r13l',10h,1Dh
db 'r13w',10h,2Dh
db 'r14b',10h,1Eh
db 'r14d',10h,4Eh
db 'r14l',10h,1Eh
db 'r14w',10h,2Eh
db 'r15b',10h,1Fh
db 'r15d',10h,4Fh
db 'r15l',10h,1Fh
db 'r15w',10h,2Fh
db 'word',11h,2
db 'xmm0',10h,0C0h
db 'xmm1',10h,0C1h
db 'xmm2',10h,0C2h
db 'xmm3',10h,0C3h
db 'xmm4',10h,0C4h
db 'xmm5',10h,0C5h
db 'xmm6',10h,0C6h
db 'xmm7',10h,0C7h
db 'xmm8',10h,0C8h
db 'xmm9',10h,0C9h
db 'ymm0',10h,0E0h
db 'ymm1',10h,0E1h
db 'ymm2',10h,0E2h
db 'ymm3',10h,0E3h
db 'ymm4',10h,0E4h
db 'ymm5',10h,0E5h
db 'ymm6',10h,0E6h
db 'ymm7',10h,0E7h
db 'ymm8',10h,0E8h
db 'ymm9',10h,0E9h
db 'zmm0',10h,60h
db 'zmm1',10h,61h
db 'zmm2',10h,62h
db 'zmm3',10h,63h
db 'zmm4',10h,64h
db 'zmm5',10h,65h
db 'zmm6',10h,66h
db 'zmm7',10h,67h
db 'zmm8',10h,68h
db 'zmm9',10h,69h
symbols_5:
db '1to16',1Fh,14h
db 'dword',11h,4
db 'elf64',18h,58h
db 'fword',11h,6
db 'large',1Bh,82h
db 'pword',11h,6
db 'qword',11h,8
db 'short',12h,1
db 'tbyte',11h,0Ah
db 'tword',11h,0Ah
db 'use16',13h,16
db 'use32',13h,32
db 'use64',13h,64
db 'xmm10',10h,0CAh
db 'xmm11',10h,0CBh
db 'xmm12',10h,0CCh
db 'xmm13',10h,0CDh
db 'xmm14',10h,0CEh
db 'xmm15',10h,0CFh
db 'xmm16',10h,0D0h
db 'xmm17',10h,0D1h
db 'xmm18',10h,0D2h
db 'xmm19',10h,0D3h
db 'xmm20',10h,0D4h
db 'xmm21',10h,0D5h
db 'xmm22',10h,0D6h
db 'xmm23',10h,0D7h
db 'xmm24',10h,0D8h
db 'xmm25',10h,0D9h
db 'xmm26',10h,0DAh
db 'xmm27',10h,0DBh
db 'xmm28',10h,0DCh
db 'xmm29',10h,0DDh
db 'xmm30',10h,0DEh
db 'xmm31',10h,0DFh
db 'xword',11h,16
db 'ymm10',10h,0EAh
db 'ymm11',10h,0EBh
db 'ymm12',10h,0ECh
db 'ymm13',10h,0EDh
db 'ymm14',10h,0EEh
db 'ymm15',10h,0EFh
db 'ymm16',10h,0F0h
db 'ymm17',10h,0F1h
db 'ymm18',10h,0F2h
db 'ymm19',10h,0F3h
db 'ymm20',10h,0F4h
db 'ymm21',10h,0F5h
db 'ymm22',10h,0F6h
db 'ymm23',10h,0F7h
db 'ymm24',10h,0F8h
db 'ymm25',10h,0F9h
db 'ymm26',10h,0FAh
db 'ymm27',10h,0FBh
db 'ymm28',10h,0FCh
db 'ymm29',10h,0FDh
db 'ymm30',10h,0FEh
db 'ymm31',10h,0FFh
db 'yword',11h,32
db 'zmm10',10h,6Ah
db 'zmm11',10h,6Bh
db 'zmm12',10h,6Ch
db 'zmm13',10h,6Dh
db 'zmm14',10h,6Eh
db 'zmm15',10h,6Fh
db 'zmm16',10h,70h
db 'zmm17',10h,71h
db 'zmm18',10h,72h
db 'zmm19',10h,73h
db 'zmm20',10h,74h
db 'zmm21',10h,75h
db 'zmm22',10h,76h
db 'zmm23',10h,77h
db 'zmm24',10h,78h
db 'zmm25',10h,79h
db 'zmm26',10h,7Ah
db 'zmm27',10h,7Bh
db 'zmm28',10h,7Ch
db 'zmm29',10h,7Dh
db 'zmm30',10h,7Eh
db 'zmm31',10h,7Fh
db 'zword',11h,64
symbols_6:
db 'binary',18h,10h
db 'dqword',11h,16
db 'export',1Ah,0
db 'fixups',1Ah,5
db 'import',1Ah,1
db 'native',1Bh,1
db 'qqword',11h,32
db 'static',1Dh,1
symbols_7:
db 'console',1Bh,3
db 'dqqword',11h,64
db 'dynamic',1Eh,2
db 'efiboot',1Bh,11
symbols_8:
db 'linkinfo',19h,9
db 'readable',19h,30
db 'resource',1Ah,2
db 'writable',19h,31
symbols_9:
db 'shareable',19h,28
db 'writeable',19h,31
symbols_10:
db 'efiruntime',1Bh,12
db 'executable',19h,29
db 'linkremove',19h,11
symbols_11:
db 'discardable',19h,25
db 'interpreter',1Eh,3
db 'notpageable',19h,27
symbols_end:
 
instructions:
dw instructions_2-instructions,(instructions_3-instructions_2)/(2+3)
dw instructions_3-instructions,(instructions_4-instructions_3)/(3+3)
dw instructions_4-instructions,(instructions_5-instructions_4)/(4+3)
dw instructions_5-instructions,(instructions_6-instructions_5)/(5+3)
dw instructions_6-instructions,(instructions_7-instructions_6)/(6+3)
dw instructions_7-instructions,(instructions_8-instructions_7)/(7+3)
dw instructions_8-instructions,(instructions_9-instructions_8)/(8+3)
dw instructions_9-instructions,(instructions_10-instructions_9)/(9+3)
dw instructions_10-instructions,(instructions_11-instructions_10)/(10+3)
dw instructions_11-instructions,(instructions_12-instructions_11)/(11+3)
dw instructions_12-instructions,(instructions_13-instructions_12)/(12+3)
dw instructions_13-instructions,(instructions_14-instructions_13)/(13+3)
dw instructions_14-instructions,(instructions_15-instructions_14)/(14+3)
dw instructions_15-instructions,(instructions_16-instructions_15)/(15+3)
dw instructions_16-instructions,(instructions_end-instructions_16)/(16+3)
 
instructions_2:
db 'bt',4
dw bt_instruction-instruction_handler
db 'if',0
dw if_directive-instruction_handler
db 'in',0
dw in_instruction-instruction_handler
db 'ja',77h
dw conditional_jump-instruction_handler
db 'jb',72h
dw conditional_jump-instruction_handler
db 'jc',72h
dw conditional_jump-instruction_handler
db 'je',74h
dw conditional_jump-instruction_handler
db 'jg',7Fh
dw conditional_jump-instruction_handler
db 'jl',7Ch
dw conditional_jump-instruction_handler
db 'jo',70h
dw conditional_jump-instruction_handler
db 'jp',7Ah
dw conditional_jump-instruction_handler
db 'js',78h
dw conditional_jump-instruction_handler
db 'jz',74h
dw conditional_jump-instruction_handler
db 'or',08h
dw basic_instruction-instruction_handler
instructions_3:
db 'aaa',37h
dw simple_instruction_except64-instruction_handler
db 'aad',0D5h
dw aa_instruction-instruction_handler
db 'aam',0D4h
dw aa_instruction-instruction_handler
db 'aas',3Fh
dw simple_instruction_except64-instruction_handler
db 'adc',10h
dw basic_instruction-instruction_handler
db 'add',00h
dw basic_instruction-instruction_handler
db 'and',20h
dw basic_instruction-instruction_handler
db 'bnd',0F2h
dw bnd_prefix_instruction-instruction_handler
db 'bsf',0BCh
dw bs_instruction-instruction_handler
db 'bsr',0BDh
dw bs_instruction-instruction_handler
db 'btc',7
dw bt_instruction-instruction_handler
db 'btr',6
dw bt_instruction-instruction_handler
db 'bts',5
dw bt_instruction-instruction_handler
db 'cbw',98h
dw simple_instruction_16bit-instruction_handler
db 'cdq',99h
dw simple_instruction_32bit-instruction_handler
db 'clc',0F8h
dw simple_instruction-instruction_handler
db 'cld',0FCh
dw simple_instruction-instruction_handler
db 'cli',0FAh
dw simple_instruction-instruction_handler
db 'cmc',0F5h
dw simple_instruction-instruction_handler
db 'cmp',38h
dw basic_instruction-instruction_handler
db 'cqo',99h
dw simple_instruction_64bit-instruction_handler
db 'cwd',99h
dw simple_instruction_16bit-instruction_handler
db 'daa',27h
dw simple_instruction_except64-instruction_handler
db 'das',2Fh
dw simple_instruction_except64-instruction_handler
db 'dec',1
dw inc_instruction-instruction_handler
db 'div',6
dw single_operand_instruction-instruction_handler
db 'end',0
dw end_directive-instruction_handler
db 'err',0
dw err_directive-instruction_handler
db 'fld',0
dw fld_instruction-instruction_handler
db 'fst',2
dw fld_instruction-instruction_handler
db 'hlt',0F4h
dw simple_instruction-instruction_handler
db 'inc',0
dw inc_instruction-instruction_handler
db 'ins',6Ch
dw ins_instruction-instruction_handler
db 'int',0CDh
dw int_instruction-instruction_handler
db 'jae',73h
dw conditional_jump-instruction_handler
db 'jbe',76h
dw conditional_jump-instruction_handler
db 'jge',7Dh
dw conditional_jump-instruction_handler
db 'jle',7Eh
dw conditional_jump-instruction_handler
db 'jmp',0
dw jmp_instruction-instruction_handler
db 'jna',76h
dw conditional_jump-instruction_handler
db 'jnb',73h
dw conditional_jump-instruction_handler
db 'jnc',73h
dw conditional_jump-instruction_handler
db 'jne',75h
dw conditional_jump-instruction_handler
db 'jng',7Eh
dw conditional_jump-instruction_handler
db 'jnl',7Dh
dw conditional_jump-instruction_handler
db 'jno',71h
dw conditional_jump-instruction_handler
db 'jnp',7Bh
dw conditional_jump-instruction_handler
db 'jns',79h
dw conditional_jump-instruction_handler
db 'jnz',75h
dw conditional_jump-instruction_handler
db 'jpe',7Ah
dw conditional_jump-instruction_handler
db 'jpo',7Bh
dw conditional_jump-instruction_handler
db 'lar',2
dw lar_instruction-instruction_handler
db 'lds',3
dw ls_instruction-instruction_handler
db 'lea',0
dw lea_instruction-instruction_handler
db 'les',0
dw ls_instruction-instruction_handler
db 'lfs',4
dw ls_instruction-instruction_handler
db 'lgs',5
dw ls_instruction-instruction_handler
db 'lsl',3
dw lar_instruction-instruction_handler
db 'lss',2
dw ls_instruction-instruction_handler
db 'ltr',3
dw pm_word_instruction-instruction_handler
db 'mov',0
dw mov_instruction-instruction_handler
db 'mul',4
dw single_operand_instruction-instruction_handler
db 'neg',3
dw single_operand_instruction-instruction_handler
db 'nop',90h
dw nop_instruction-instruction_handler
db 'not',2
dw single_operand_instruction-instruction_handler
db 'org',0
dw org_directive-instruction_handler
db 'out',0
dw out_instruction-instruction_handler
db 'pop',0
dw pop_instruction-instruction_handler
db 'por',0EBh
dw basic_mmx_instruction-instruction_handler
db 'rcl',2
dw sh_instruction-instruction_handler
db 'rcr',3
dw sh_instruction-instruction_handler
db 'rep',0F3h
dw prefix_instruction-instruction_handler
db 'ret',0C2h
dw ret_instruction-instruction_handler
db 'rol',0
dw sh_instruction-instruction_handler
db 'ror',1
dw sh_instruction-instruction_handler
db 'rsm',0AAh
dw simple_extended_instruction-instruction_handler
db 'sal',4
dw sh_instruction-instruction_handler
db 'sar',7
dw sh_instruction-instruction_handler
db 'sbb',18h
dw basic_instruction-instruction_handler
db 'shl',4
dw sh_instruction-instruction_handler
db 'shr',5
dw sh_instruction-instruction_handler
db 'stc',0F9h
dw simple_instruction-instruction_handler
db 'std',0FDh
dw simple_instruction-instruction_handler
db 'sti',0FBh
dw simple_instruction-instruction_handler
db 'str',1
dw pm_store_word_instruction-instruction_handler
db 'sub',28h
dw basic_instruction-instruction_handler
db 'ud2',0Bh
dw simple_extended_instruction-instruction_handler
db 'xor',30h
dw basic_instruction-instruction_handler
instructions_4:
db 'adcx',66h
dw adx_instruction-instruction_handler
db 'adox',0F3h
dw adx_instruction-instruction_handler
db 'andn',0F2h
dw andn_instruction-instruction_handler
db 'arpl',0
dw arpl_instruction-instruction_handler
db 'blci',26h
dw tbm_instruction-instruction_handler
db 'blcs',13h
dw tbm_instruction-instruction_handler
db 'blsi',3
dw bmi_instruction-instruction_handler
db 'blsr',1
dw bmi_instruction-instruction_handler
db 'bzhi',0F5h
dw bzhi_instruction-instruction_handler
db 'call',0
dw call_instruction-instruction_handler
db 'cdqe',98h
dw simple_instruction_64bit-instruction_handler
db 'clac',0CAh
dw simple_instruction_0f_01-instruction_handler
db 'clgi',0DDh
dw simple_instruction_0f_01-instruction_handler
db 'clts',6
dw simple_extended_instruction-instruction_handler
db 'clwb',6
dw clflushopt_instruction-instruction_handler
db 'cmps',0A6h
dw cmps_instruction-instruction_handler
db 'cwde',98h
dw simple_instruction_32bit-instruction_handler
db 'data',0
dw data_directive-instruction_handler
db 'dppd',41h
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'dpps',40h
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'else',0
dw else_directive-instruction_handler
db 'emms',77h
dw simple_extended_instruction-instruction_handler
db 'fabs',100001b
dw simple_fpu_instruction-instruction_handler
db 'fadd',0
dw basic_fpu_instruction-instruction_handler
db 'fbld',4
dw fbld_instruction-instruction_handler
db 'fchs',100000b
dw simple_fpu_instruction-instruction_handler
db 'fcom',2
dw basic_fpu_instruction-instruction_handler
db 'fcos',111111b
dw simple_fpu_instruction-instruction_handler
db 'fdiv',6
dw basic_fpu_instruction-instruction_handler
db 'feni',0E0h
dw finit_instruction-instruction_handler
db 'fild',0
dw fild_instruction-instruction_handler
db 'fist',2
dw fild_instruction-instruction_handler
db 'fld1',101000b
dw simple_fpu_instruction-instruction_handler
db 'fldz',101110b
dw simple_fpu_instruction-instruction_handler
db 'fmul',1
dw basic_fpu_instruction-instruction_handler
db 'fnop',010000b
dw simple_fpu_instruction-instruction_handler
db 'fsin',111110b
dw simple_fpu_instruction-instruction_handler
db 'fstp',3
dw fld_instruction-instruction_handler
db 'fsub',4
dw basic_fpu_instruction-instruction_handler
db 'ftst',100100b
dw simple_fpu_instruction-instruction_handler
db 'fxam',100101b
dw simple_fpu_instruction-instruction_handler
db 'fxch',0
dw fxch_instruction-instruction_handler
db 'heap',0
dw heap_directive-instruction_handler
db 'idiv',7
dw single_operand_instruction-instruction_handler
db 'imul',0
dw imul_instruction-instruction_handler
db 'insb',6Ch
dw simple_instruction-instruction_handler
db 'insd',6Dh
dw simple_instruction_32bit-instruction_handler
db 'insw',6Dh
dw simple_instruction_16bit-instruction_handler
db 'int1',0F1h
dw simple_instruction-instruction_handler
db 'int3',0CCh
dw simple_instruction-instruction_handler
db 'into',0CEh
dw simple_instruction_except64-instruction_handler
db 'invd',8
dw simple_extended_instruction-instruction_handler
db 'iret',0CFh
dw iret_instruction-instruction_handler
db 'jcxz',0E3h
dw loop_instruction_16bit-instruction_handler
db 'jnae',72h
dw conditional_jump-instruction_handler
db 'jnbe',77h
dw conditional_jump-instruction_handler
db 'jnge',7Ch
dw conditional_jump-instruction_handler
db 'jnle',7Fh
dw conditional_jump-instruction_handler
db 'korb',45h
dw mask_instruction_b-instruction_handler
db 'kord',45h
dw mask_instruction_d-instruction_handler
db 'korq',45h
dw mask_instruction_q-instruction_handler
db 'korw',45h
dw mask_instruction_w-instruction_handler
db 'lahf',9Fh
dw simple_instruction-instruction_handler
db 'lgdt',2
dw lgdt_instruction-instruction_handler
db 'lidt',3
dw lgdt_instruction-instruction_handler
db 'lldt',2
dw pm_word_instruction-instruction_handler
db 'lmsw',16h
dw pm_word_instruction-instruction_handler
db 'load',0
dw load_directive-instruction_handler
db 'lock',0F0h
dw prefix_instruction-instruction_handler
db 'lods',0ACh
dw lods_instruction-instruction_handler
db 'loop',0E2h
dw loop_instruction-instruction_handler
db 'movd',0
dw movd_instruction-instruction_handler
db 'movq',0
dw movq_instruction-instruction_handler
db 'movs',0A4h
dw movs_instruction-instruction_handler
db 'mulx',0F6h
dw pdep_instruction-instruction_handler
db 'orpd',56h
dw sse_pd_instruction-instruction_handler
db 'orps',56h
dw sse_ps_instruction-instruction_handler
db 'outs',6Eh
dw outs_instruction-instruction_handler
db 'pand',0DBh
dw basic_mmx_instruction-instruction_handler
db 'pdep',0F5h
dw pdep_instruction-instruction_handler
db 'pext',0F5h
dw pext_instruction-instruction_handler
db 'popa',61h
dw simple_instruction_except64-instruction_handler
db 'popd',4
dw pop_instruction-instruction_handler
db 'popf',9Dh
dw simple_instruction-instruction_handler
db 'popq',8
dw pop_instruction-instruction_handler
db 'popw',2
dw pop_instruction-instruction_handler
db 'push',0
dw push_instruction-instruction_handler
db 'pxor',0EFh
dw basic_mmx_instruction-instruction_handler
db 'repe',0F3h
dw prefix_instruction-instruction_handler
db 'repz',0F3h
dw prefix_instruction-instruction_handler
db 'retd',0C2h
dw ret_instruction_32bit_except64-instruction_handler
db 'retf',0CAh
dw retf_instruction-instruction_handler
db 'retn',0C2h
dw ret_instruction-instruction_handler
db 'retq',0C2h
dw ret_instruction_only64-instruction_handler
db 'retw',0C2h
dw ret_instruction_16bit-instruction_handler
db 'rorx',0F0h
dw rorx_instruction-instruction_handler
db 'sahf',9Eh
dw simple_instruction-instruction_handler
db 'salc',0D6h
dw simple_instruction_except64-instruction_handler
db 'sarx',0F7h
dw sarx_instruction-instruction_handler
db 'scas',0AEh
dw stos_instruction-instruction_handler
db 'seta',97h
dw set_instruction-instruction_handler
db 'setb',92h
dw set_instruction-instruction_handler
db 'setc',92h
dw set_instruction-instruction_handler
db 'sete',94h
dw set_instruction-instruction_handler
db 'setg',9Fh
dw set_instruction-instruction_handler
db 'setl',9Ch
dw set_instruction-instruction_handler
db 'seto',90h
dw set_instruction-instruction_handler
db 'setp',9Ah
dw set_instruction-instruction_handler
db 'sets',98h
dw set_instruction-instruction_handler
db 'setz',94h
dw set_instruction-instruction_handler
db 'sgdt',0
dw lgdt_instruction-instruction_handler
db 'shld',0A4h
dw shd_instruction-instruction_handler
db 'shlx',0F7h
dw shlx_instruction-instruction_handler
db 'shrd',0ACh
dw shd_instruction-instruction_handler
db 'shrx',0F7h
dw shrx_instruction-instruction_handler
db 'sidt',1
dw lgdt_instruction-instruction_handler
db 'sldt',0
dw pm_store_word_instruction-instruction_handler
db 'smsw',14h
dw pm_store_word_instruction-instruction_handler
db 'stac',0CBh
dw simple_instruction_0f_01-instruction_handler
db 'stgi',0DCh
dw simple_instruction_0f_01-instruction_handler
db 'stos',0AAh
dw stos_instruction-instruction_handler
db 'test',0
dw test_instruction-instruction_handler
db 'verr',4
dw pm_word_instruction-instruction_handler
db 'verw',5
dw pm_word_instruction-instruction_handler
db 'vpor',0EBh
dw avx_pd_instruction_noevex-instruction_handler
db 'wait',9Bh
dw simple_instruction-instruction_handler
db 'xadd',0C0h
dw basic_486_instruction-instruction_handler
db 'xchg',0
dw xchg_instruction-instruction_handler
db 'xend',0D5h
dw simple_instruction_0f_01-instruction_handler
db 'xlat',0D7h
dw xlat_instruction-instruction_handler
instructions_5:
db 'addpd',58h
dw sse_pd_instruction-instruction_handler
db 'addps',58h
dw sse_ps_instruction-instruction_handler
db 'addsd',58h
dw sse_sd_instruction-instruction_handler
db 'addss',58h
dw sse_ss_instruction-instruction_handler
db 'align',0
dw align_directive-instruction_handler
db 'andpd',54h
dw sse_pd_instruction-instruction_handler
db 'andps',54h
dw sse_ps_instruction-instruction_handler
db 'bextr',0F7h
dw bextr_instruction-instruction_handler
db 'blcic',15h
dw tbm_instruction-instruction_handler
db 'blsic',16h
dw tbm_instruction-instruction_handler
db 'bndcl',1Ah
dw bndcl_instruction-instruction_handler
db 'bndcn',1Bh
dw bndcu_instruction-instruction_handler
db 'bndcu',1Ah
dw bndcu_instruction-instruction_handler
db 'bndmk',1Bh
dw bndmk_instruction-instruction_handler
db 'bound',0
dw bound_instruction-instruction_handler
db 'break',0
dw break_directive-instruction_handler
db 'bswap',0
dw bswap_instruction-instruction_handler
db 'cmova',47h
dw bs_instruction-instruction_handler
db 'cmovb',42h
dw bs_instruction-instruction_handler
db 'cmovc',42h
dw bs_instruction-instruction_handler
db 'cmove',44h
dw bs_instruction-instruction_handler
db 'cmovg',4Fh
dw bs_instruction-instruction_handler
db 'cmovl',4Ch
dw bs_instruction-instruction_handler
db 'cmovo',40h
dw bs_instruction-instruction_handler
db 'cmovp',4Ah
dw bs_instruction-instruction_handler
db 'cmovs',48h
dw bs_instruction-instruction_handler
db 'cmovz',44h
dw bs_instruction-instruction_handler
db 'cmppd',-1
dw cmp_pd_instruction-instruction_handler
db 'cmpps',-1
dw cmp_ps_instruction-instruction_handler
db 'cmpsb',0A6h
dw simple_instruction-instruction_handler
db 'cmpsd',-1
dw cmpsd_instruction-instruction_handler
db 'cmpsq',0A7h
dw simple_instruction_64bit-instruction_handler
db 'cmpss',-1
dw cmp_ss_instruction-instruction_handler
db 'cmpsw',0A7h
dw simple_instruction_16bit-instruction_handler
db 'cpuid',0A2h
dw simple_extended_instruction-instruction_handler
db 'crc32',0
dw crc32_instruction-instruction_handler
db 'divpd',5Eh
dw sse_pd_instruction-instruction_handler
db 'divps',5Eh
dw sse_ps_instruction-instruction_handler
db 'divsd',5Eh
dw sse_sd_instruction-instruction_handler
db 'divss',5Eh
dw sse_ss_instruction-instruction_handler
db 'enter',0
dw enter_instruction-instruction_handler
db 'entry',0
dw entry_directive-instruction_handler
db 'extrn',0
dw extrn_directive-instruction_handler
db 'extrq',0
dw extrq_instruction-instruction_handler
db 'f2xm1',110000b
dw simple_fpu_instruction-instruction_handler
db 'faddp',0
dw faddp_instruction-instruction_handler
db 'fbstp',6
dw fbld_instruction-instruction_handler
db 'fclex',0E2h
dw finit_instruction-instruction_handler
db 'fcomi',0F0h
dw fcomi_instruction-instruction_handler
db 'fcomp',3
dw basic_fpu_instruction-instruction_handler
db 'fdisi',0E1h
dw finit_instruction-instruction_handler
db 'fdivp',7
dw faddp_instruction-instruction_handler
db 'fdivr',7
dw basic_fpu_instruction-instruction_handler
db 'femms',0Eh
dw simple_extended_instruction-instruction_handler
db 'ffree',0
dw ffree_instruction-instruction_handler
db 'fiadd',0
dw fi_instruction-instruction_handler
db 'ficom',2
dw fi_instruction-instruction_handler
db 'fidiv',6
dw fi_instruction-instruction_handler
db 'fimul',1
dw fi_instruction-instruction_handler
db 'finit',0E3h
dw finit_instruction-instruction_handler
db 'fistp',3
dw fild_instruction-instruction_handler
db 'fisub',4
dw fi_instruction-instruction_handler
db 'fldcw',5
dw fldcw_instruction-instruction_handler
db 'fldpi',101011b
dw simple_fpu_instruction-instruction_handler
db 'fmulp',1
dw faddp_instruction-instruction_handler
db 'fneni',0E0h
dw fninit_instruction-instruction_handler
db 'fprem',111000b
dw simple_fpu_instruction-instruction_handler
db 'fptan',110010b
dw simple_fpu_instruction-instruction_handler
db 'fsave',6
dw fsave_instruction-instruction_handler
db 'fsqrt',111010b
dw simple_fpu_instruction-instruction_handler
db 'fstcw',7
dw fstcw_instruction-instruction_handler
db 'fstsw',0
dw fstsw_instruction-instruction_handler
db 'fsubp',5
dw faddp_instruction-instruction_handler
db 'fsubr',5
dw basic_fpu_instruction-instruction_handler
db 'fucom',4
dw ffree_instruction-instruction_handler
db 'fwait',9Bh
dw simple_instruction-instruction_handler
db 'fyl2x',110001b
dw simple_fpu_instruction-instruction_handler
db 'icebp',0F1h
dw simple_instruction-instruction_handler
db 'iretd',0CFh
dw simple_instruction_32bit-instruction_handler
db 'iretq',0CFh
dw simple_instruction_64bit-instruction_handler
db 'iretw',0CFh
dw simple_instruction_16bit-instruction_handler
db 'jecxz',0E3h
dw loop_instruction_32bit-instruction_handler
db 'jrcxz',0E3h
dw loop_instruction_64bit-instruction_handler
db 'kaddb',4Ah
dw mask_instruction_b-instruction_handler
db 'kaddd',4Ah
dw mask_instruction_d-instruction_handler
db 'kaddq',4Ah
dw mask_instruction_q-instruction_handler
db 'kaddw',4Ah
dw mask_instruction_w-instruction_handler
db 'kandb',41h
dw mask_instruction_b-instruction_handler
db 'kandd',41h
dw mask_instruction_d-instruction_handler
db 'kandq',41h
dw mask_instruction_q-instruction_handler
db 'kandw',41h
dw mask_instruction_w-instruction_handler
db 'kmovb',1
dw kmov_instruction-instruction_handler
db 'kmovd',4
dw kmov_instruction-instruction_handler
db 'kmovq',8
dw kmov_instruction-instruction_handler
db 'kmovw',2
dw kmov_instruction-instruction_handler
db 'knotb',44h
dw mask_instruction_single_source_b-instruction_handler
db 'knotd',44h
dw mask_instruction_single_source_d-instruction_handler
db 'knotq',44h
dw mask_instruction_single_source_q-instruction_handler
db 'knotw',44h
dw mask_instruction_single_source_w-instruction_handler
db 'kxorb',47h
dw mask_instruction_b-instruction_handler
db 'kxord',47h
dw mask_instruction_d-instruction_handler
db 'kxorq',47h
dw mask_instruction_q-instruction_handler
db 'kxorw',47h
dw mask_instruction_w-instruction_handler
db 'label',0
dw label_directive-instruction_handler
db 'lddqu',0
dw lddqu_instruction-instruction_handler
db 'leave',0C9h
dw simple_instruction-instruction_handler
db 'lodsb',0ACh
dw simple_instruction-instruction_handler
db 'lodsd',0ADh
dw simple_instruction_32bit-instruction_handler
db 'lodsq',0ADh
dw simple_instruction_64bit-instruction_handler
db 'lodsw',0ADh
dw simple_instruction_16bit-instruction_handler
db 'loopd',0E2h
dw loop_instruction_32bit-instruction_handler
db 'loope',0E1h
dw loop_instruction-instruction_handler
db 'loopq',0E2h
dw loop_instruction_64bit-instruction_handler
db 'loopw',0E2h
dw loop_instruction_16bit-instruction_handler
db 'loopz',0E1h
dw loop_instruction-instruction_handler
db 'lzcnt',0BDh
dw popcnt_instruction-instruction_handler
db 'maxpd',5Fh
dw sse_pd_instruction-instruction_handler
db 'maxps',5Fh
dw sse_ps_instruction-instruction_handler
db 'maxsd',5Fh
dw sse_sd_instruction-instruction_handler
db 'maxss',5Fh
dw sse_ss_instruction-instruction_handler
db 'minpd',5Dh
dw sse_pd_instruction-instruction_handler
db 'minps',5Dh
dw sse_ps_instruction-instruction_handler
db 'minsd',5Dh
dw sse_sd_instruction-instruction_handler
db 'minss',5Dh
dw sse_ss_instruction-instruction_handler
db 'movbe',0F0h
dw movbe_instruction-instruction_handler
db 'movsb',0A4h
dw simple_instruction-instruction_handler
db 'movsd',0
dw movsd_instruction-instruction_handler
db 'movsq',0A5h
dw simple_instruction_64bit-instruction_handler
db 'movss',0
dw movss_instruction-instruction_handler
db 'movsw',0A5h
dw simple_instruction_16bit-instruction_handler
db 'movsx',0BEh
dw movx_instruction-instruction_handler
db 'movzx',0B6h
dw movx_instruction-instruction_handler
db 'mulpd',59h
dw sse_pd_instruction-instruction_handler
db 'mulps',59h
dw sse_ps_instruction-instruction_handler
db 'mulsd',59h
dw sse_sd_instruction-instruction_handler
db 'mulss',59h
dw sse_ss_instruction-instruction_handler
db 'mwait',0C9h
dw monitor_instruction-instruction_handler
db 'outsb',6Eh
dw simple_instruction-instruction_handler
db 'outsd',6Fh
dw simple_instruction_32bit-instruction_handler
db 'outsw',6Fh
dw simple_instruction_16bit-instruction_handler
db 'pabsb',1Ch
dw ssse3_instruction-instruction_handler
db 'pabsd',1Eh
dw ssse3_instruction-instruction_handler
db 'pabsw',1Dh
dw ssse3_instruction-instruction_handler
db 'paddb',0FCh
dw basic_mmx_instruction-instruction_handler
db 'paddd',0FEh
dw basic_mmx_instruction-instruction_handler
db 'paddq',0D4h
dw basic_mmx_instruction-instruction_handler
db 'paddw',0FDh
dw basic_mmx_instruction-instruction_handler
db 'pandn',0DFh
dw basic_mmx_instruction-instruction_handler
db 'pause',0
dw pause_instruction-instruction_handler
db 'pavgb',0E0h
dw basic_mmx_instruction-instruction_handler
db 'pavgw',0E3h
dw basic_mmx_instruction-instruction_handler
db 'pf2id',1Dh
dw amd3dnow_instruction-instruction_handler
db 'pf2iw',1Ch
dw amd3dnow_instruction-instruction_handler
db 'pfacc',0AEh
dw amd3dnow_instruction-instruction_handler
db 'pfadd',9Eh
dw amd3dnow_instruction-instruction_handler
db 'pfmax',0A4h
dw amd3dnow_instruction-instruction_handler
db 'pfmin',94h
dw amd3dnow_instruction-instruction_handler
db 'pfmul',0B4h
dw amd3dnow_instruction-instruction_handler
db 'pfrcp',96h
dw amd3dnow_instruction-instruction_handler
db 'pfsub',9Ah
dw amd3dnow_instruction-instruction_handler
db 'pi2fd',0Dh
dw amd3dnow_instruction-instruction_handler
db 'pi2fw',0Ch
dw amd3dnow_instruction-instruction_handler
db 'popad',61h
dw simple_instruction_32bit_except64-instruction_handler
db 'popaw',61h
dw simple_instruction_16bit_except64-instruction_handler
db 'popfd',9Dh
dw simple_instruction_32bit_except64-instruction_handler
db 'popfq',9Dh
dw simple_instruction_only64-instruction_handler
db 'popfw',9Dh
dw simple_instruction_16bit-instruction_handler
db 'pslld',0F2h
dw mmx_bit_shift_instruction-instruction_handler
db 'psllq',0F3h
dw mmx_bit_shift_instruction-instruction_handler
db 'psllw',0F1h
dw mmx_bit_shift_instruction-instruction_handler
db 'psrad',0E2h
dw mmx_bit_shift_instruction-instruction_handler
db 'psraw',0E1h
dw mmx_bit_shift_instruction-instruction_handler
db 'psrld',0D2h
dw mmx_bit_shift_instruction-instruction_handler
db 'psrlq',0D3h
dw mmx_bit_shift_instruction-instruction_handler
db 'psrlw',0D1h
dw mmx_bit_shift_instruction-instruction_handler
db 'psubb',0F8h
dw basic_mmx_instruction-instruction_handler
db 'psubd',0FAh
dw basic_mmx_instruction-instruction_handler
db 'psubq',0FBh
dw basic_mmx_instruction-instruction_handler
db 'psubw',0F9h
dw basic_mmx_instruction-instruction_handler
db 'ptest',17h
dw sse4_instruction_66_38-instruction_handler
db 'pusha',60h
dw simple_instruction_except64-instruction_handler
db 'pushd',4
dw push_instruction-instruction_handler
db 'pushf',9Ch
dw simple_instruction-instruction_handler
db 'pushq',8
dw push_instruction-instruction_handler
db 'pushw',2
dw push_instruction-instruction_handler
db 'rcpps',53h
dw sse_ps_instruction-instruction_handler
db 'rcpss',53h
dw sse_ss_instruction-instruction_handler
db 'rdmsr',32h
dw simple_extended_instruction-instruction_handler
db 'rdpmc',33h
dw simple_extended_instruction-instruction_handler
db 'rdtsc',31h
dw simple_extended_instruction-instruction_handler
db 'repne',0F2h
dw prefix_instruction-instruction_handler
db 'repnz',0F2h
dw prefix_instruction-instruction_handler
db 'retfd',0CAh
dw retf_instruction_32bit-instruction_handler
db 'retfq',0CAh
dw retf_instruction_64bit-instruction_handler
db 'retfw',0CAh
dw retf_instruction_16bit-instruction_handler
db 'retnd',0C2h
dw ret_instruction_32bit_except64-instruction_handler
db 'retnq',0C2h
dw ret_instruction_only64-instruction_handler
db 'retnw',0C2h
dw ret_instruction_16bit-instruction_handler
db 'scasb',0AEh
dw simple_instruction-instruction_handler
db 'scasd',0AFh
dw simple_instruction_32bit-instruction_handler
db 'scasq',0AFh
dw simple_instruction_64bit-instruction_handler
db 'scasw',0AFh
dw simple_instruction_16bit-instruction_handler
db 'setae',93h
dw set_instruction-instruction_handler
db 'setbe',96h
dw set_instruction-instruction_handler
db 'setge',9Dh
dw set_instruction-instruction_handler
db 'setle',9Eh
dw set_instruction-instruction_handler
db 'setna',96h
dw set_instruction-instruction_handler
db 'setnb',93h
dw set_instruction-instruction_handler
db 'setnc',93h
dw set_instruction-instruction_handler
db 'setne',95h
dw set_instruction-instruction_handler
db 'setng',9Eh
dw set_instruction-instruction_handler
db 'setnl',9Dh
dw set_instruction-instruction_handler
db 'setno',91h
dw set_instruction-instruction_handler
db 'setnp',9Bh
dw set_instruction-instruction_handler
db 'setns',99h
dw set_instruction-instruction_handler
db 'setnz',95h
dw set_instruction-instruction_handler
db 'setpe',9Ah
dw set_instruction-instruction_handler
db 'setpo',9Bh
dw set_instruction-instruction_handler
db 'stack',0
dw stack_directive-instruction_handler
db 'store',0
dw store_directive-instruction_handler
db 'stosb',0AAh
dw simple_instruction-instruction_handler
db 'stosd',0ABh
dw simple_instruction_32bit-instruction_handler
db 'stosq',0ABh
dw simple_instruction_64bit-instruction_handler
db 'stosw',0ABh
dw simple_instruction_16bit-instruction_handler
db 'subpd',5Ch
dw sse_pd_instruction-instruction_handler
db 'subps',5Ch
dw sse_ps_instruction-instruction_handler
db 'subsd',5Ch
dw sse_sd_instruction-instruction_handler
db 'subss',5Ch
dw sse_ss_instruction-instruction_handler
db 'times',0
dw times_directive-instruction_handler
db 'tzcnt',0BCh
dw popcnt_instruction-instruction_handler
db 'tzmsk',14h
dw tbm_instruction-instruction_handler
db 'vdppd',41h
dw avx_128bit_instruction_3a_imm8_noevex-instruction_handler
db 'vdpps',40h
dw avx_pi_instruction_3a_imm8_noevex-instruction_handler
db 'vmovd',0
dw avx_movd_instruction-instruction_handler
db 'vmovq',0
dw avx_movq_instruction-instruction_handler
db 'vmrun',0D8h
dw simple_svm_instruction-instruction_handler
db 'vmxon',6
dw vmxon_instruction-instruction_handler
db 'vorpd',56h
dw avx_pd_instruction-instruction_handler
db 'vorps',56h
dw avx_ps_instruction-instruction_handler
db 'vpand',0DBh
dw avx_pd_instruction_noevex-instruction_handler
db 'vpord',0EBh
dw avx_d_instruction_evex-instruction_handler
db 'vporq',0EBh
dw avx_q_instruction_evex-instruction_handler
db 'vpxor',0EFh
dw avx_pd_instruction_noevex-instruction_handler
db 'while',0
dw while_directive-instruction_handler
db 'wrmsr',30h
dw simple_extended_instruction-instruction_handler
db 'xlatb',0D7h
dw simple_instruction-instruction_handler
db 'xorpd',57h
dw sse_pd_instruction-instruction_handler
db 'xorps',57h
dw sse_ps_instruction-instruction_handler
db 'xsave',100b
dw fxsave_instruction-instruction_handler
db 'xtest',0D6h
dw simple_instruction_0f_01-instruction_handler
instructions_6:
db 'aesdec',0DEh
dw sse4_instruction_66_38-instruction_handler
db 'aesenc',0DCh
dw sse4_instruction_66_38-instruction_handler
db 'aesimc',0DBh
dw sse4_instruction_66_38-instruction_handler
db 'andnpd',55h
dw sse_pd_instruction-instruction_handler
db 'andnps',55h
dw sse_ps_instruction-instruction_handler
db 'assert',0
dw assert_directive-instruction_handler
db 'blcmsk',21h
dw tbm_instruction-instruction_handler
db 'blsmsk',2
dw bmi_instruction-instruction_handler
db 'bndldx',1Ah
dw bndldx_instruction-instruction_handler
db 'bndmov',1Ah
dw bndmov_instruction-instruction_handler
db 'bndstx',1Bh
dw bndstx_instruction-instruction_handler
db 'cmovae',43h
dw bs_instruction-instruction_handler
db 'cmovbe',46h
dw bs_instruction-instruction_handler
db 'cmovge',4Dh
dw bs_instruction-instruction_handler
db 'cmovle',4Eh
dw bs_instruction-instruction_handler
db 'cmovna',46h
dw bs_instruction-instruction_handler
db 'cmovnb',43h
dw bs_instruction-instruction_handler
db 'cmovnc',43h
dw bs_instruction-instruction_handler
db 'cmovne',45h
dw bs_instruction-instruction_handler
db 'cmovng',4Eh
dw bs_instruction-instruction_handler
db 'cmovnl',4Dh
dw bs_instruction-instruction_handler
db 'cmovno',41h
dw bs_instruction-instruction_handler
db 'cmovnp',4Bh
dw bs_instruction-instruction_handler
db 'cmovns',49h
dw bs_instruction-instruction_handler
db 'cmovnz',45h
dw bs_instruction-instruction_handler
db 'cmovpe',4Ah
dw bs_instruction-instruction_handler
db 'cmovpo',4Bh
dw bs_instruction-instruction_handler
db 'comisd',2Fh
dw comisd_instruction-instruction_handler
db 'comiss',2Fh
dw comiss_instruction-instruction_handler
db 'fcmovb',0C0h
dw fcmov_instruction-instruction_handler
db 'fcmove',0C8h
dw fcmov_instruction-instruction_handler
db 'fcmovu',0D8h
dw fcmov_instruction-instruction_handler
db 'fcomip',0F0h
dw fcomip_instruction-instruction_handler
db 'fcompp',0
dw fcompp_instruction-instruction_handler
db 'fdivrp',6
dw faddp_instruction-instruction_handler
db 'ffreep',0
dw ffreep_instruction-instruction_handler
db 'ficomp',3
dw fi_instruction-instruction_handler
db 'fidivr',7
dw fi_instruction-instruction_handler
db 'fisttp',1
dw fild_instruction-instruction_handler
db 'fisubr',5
dw fi_instruction-instruction_handler
db 'fldenv',4
dw fldenv_instruction-instruction_handler
db 'fldl2e',101010b
dw simple_fpu_instruction-instruction_handler
db 'fldl2t',101001b
dw simple_fpu_instruction-instruction_handler
db 'fldlg2',101100b
dw simple_fpu_instruction-instruction_handler
db 'fldln2',101101b
dw simple_fpu_instruction-instruction_handler
db 'fnclex',0E2h
dw fninit_instruction-instruction_handler
db 'fndisi',0E1h
dw fninit_instruction-instruction_handler
db 'fninit',0E3h
dw fninit_instruction-instruction_handler
db 'fnsave',6
dw fnsave_instruction-instruction_handler
db 'fnstcw',7
dw fldcw_instruction-instruction_handler
db 'fnstsw',0
dw fnstsw_instruction-instruction_handler
db 'format',0
dw format_directive-instruction_handler
db 'fpatan',110011b
dw simple_fpu_instruction-instruction_handler
db 'fprem1',110101b
dw simple_fpu_instruction-instruction_handler
db 'frstor',4
dw fnsave_instruction-instruction_handler
db 'frstpm',0E5h
dw fninit_instruction-instruction_handler
db 'fsaved',6
dw fsave_instruction_32bit-instruction_handler
db 'fsavew',6
dw fsave_instruction_16bit-instruction_handler
db 'fscale',111101b
dw simple_fpu_instruction-instruction_handler
db 'fsetpm',0E4h
dw fninit_instruction-instruction_handler
db 'fstenv',6
dw fstenv_instruction-instruction_handler
db 'fsubrp',4
dw faddp_instruction-instruction_handler
db 'fucomi',0E8h
dw fcomi_instruction-instruction_handler
db 'fucomp',5
dw ffree_instruction-instruction_handler
db 'fxsave',0
dw fxsave_instruction-instruction_handler
db 'getsec',37h
dw simple_extended_instruction-instruction_handler
db 'haddpd',07Ch
dw sse_pd_instruction-instruction_handler
db 'haddps',07Ch
dw cvtpd2dq_instruction-instruction_handler
db 'hsubpd',07Dh
dw sse_pd_instruction-instruction_handler
db 'hsubps',07Dh
dw cvtpd2dq_instruction-instruction_handler
db 'invept',80h
dw vmx_inv_instruction-instruction_handler
db 'invlpg',0
dw invlpg_instruction-instruction_handler
db 'kandnb',42h
dw mask_instruction_b-instruction_handler
db 'kandnd',42h
dw mask_instruction_d-instruction_handler
db 'kandnq',42h
dw mask_instruction_q-instruction_handler
db 'kandnw',42h
dw mask_instruction_w-instruction_handler
db 'ktestb',99h
dw mask_instruction_single_source_b-instruction_handler
db 'ktestd',99h
dw mask_instruction_single_source_d-instruction_handler
db 'ktestq',99h
dw mask_instruction_single_source_q-instruction_handler
db 'ktestw',99h
dw mask_instruction_single_source_w-instruction_handler
db 'kxnorb',46h
dw mask_instruction_b-instruction_handler
db 'kxnord',46h
dw mask_instruction_d-instruction_handler
db 'kxnorq',46h
dw mask_instruction_q-instruction_handler
db 'kxnorw',46h
dw mask_instruction_w-instruction_handler
db 'lfence',0E8h
dw fence_instruction-instruction_handler
db 'llwpcb',0
dw llwpcb_instruction-instruction_handler
db 'looped',0E1h
dw loop_instruction_32bit-instruction_handler
db 'loopeq',0E1h
dw loop_instruction_64bit-instruction_handler
db 'loopew',0E1h
dw loop_instruction_16bit-instruction_handler
db 'loopne',0E0h
dw loop_instruction-instruction_handler
db 'loopnz',0E0h
dw loop_instruction-instruction_handler
db 'loopzd',0E1h
dw loop_instruction_32bit-instruction_handler
db 'loopzq',0E1h
dw loop_instruction_64bit-instruction_handler
db 'loopzw',0E1h
dw loop_instruction_16bit-instruction_handler
db 'lwpins',0
dw lwpins_instruction-instruction_handler
db 'lwpval',1
dw lwpins_instruction-instruction_handler
db 'mfence',0F0h
dw fence_instruction-instruction_handler
db 'movapd',28h
dw movpd_instruction-instruction_handler
db 'movaps',28h
dw movps_instruction-instruction_handler
db 'movdqa',66h
dw movdq_instruction-instruction_handler
db 'movdqu',0F3h
dw movdq_instruction-instruction_handler
db 'movhpd',16h
dw movlpd_instruction-instruction_handler
db 'movhps',16h
dw movlps_instruction-instruction_handler
db 'movlpd',12h
dw movlpd_instruction-instruction_handler
db 'movlps',12h
dw movlps_instruction-instruction_handler
db 'movnti',0C3h
dw movnti_instruction-instruction_handler
db 'movntq',0E7h
dw movntq_instruction-instruction_handler
db 'movsxd',63h
dw movsxd_instruction-instruction_handler
db 'movupd',10h
dw movpd_instruction-instruction_handler
db 'movups',10h
dw movps_instruction-instruction_handler
db 'paddsb',0ECh
dw basic_mmx_instruction-instruction_handler
db 'paddsw',0EDh
dw basic_mmx_instruction-instruction_handler
db 'pextrb',14h
dw pextrb_instruction-instruction_handler
db 'pextrd',16h
dw pextrd_instruction-instruction_handler
db 'pextrq',16h
dw pextrq_instruction-instruction_handler
db 'pextrw',15h
dw pextrw_instruction-instruction_handler
db 'pfnacc',8Ah
dw amd3dnow_instruction-instruction_handler
db 'pfsubr',0AAh
dw amd3dnow_instruction-instruction_handler
db 'phaddd',2
dw ssse3_instruction-instruction_handler
db 'phaddw',1
dw ssse3_instruction-instruction_handler
db 'phsubd',6
dw ssse3_instruction-instruction_handler
db 'phsubw',5
dw ssse3_instruction-instruction_handler
db 'pinsrb',20h
dw pinsrb_instruction-instruction_handler
db 'pinsrd',22h
dw pinsrd_instruction-instruction_handler
db 'pinsrq',22h
dw pinsrq_instruction-instruction_handler
db 'pinsrw',0C4h
dw pinsrw_instruction-instruction_handler
db 'pmaxsb',3Ch
dw sse4_instruction_66_38-instruction_handler
db 'pmaxsd',3Dh
dw sse4_instruction_66_38-instruction_handler
db 'pmaxsw',0EEh
dw basic_mmx_instruction-instruction_handler
db 'pmaxub',0DEh
dw basic_mmx_instruction-instruction_handler
db 'pmaxud',3Fh
dw sse4_instruction_66_38-instruction_handler
db 'pmaxuw',3Eh
dw sse4_instruction_66_38-instruction_handler
db 'pminsb',38h
dw sse4_instruction_66_38-instruction_handler
db 'pminsd',39h
dw sse4_instruction_66_38-instruction_handler
db 'pminsw',0EAh
dw basic_mmx_instruction-instruction_handler
db 'pminub',0DAh
dw basic_mmx_instruction-instruction_handler
db 'pminud',3Bh
dw sse4_instruction_66_38-instruction_handler
db 'pminuw',3Ah
dw sse4_instruction_66_38-instruction_handler
db 'pmuldq',28h
dw sse4_instruction_66_38-instruction_handler
db 'pmulhw',0E5h
dw basic_mmx_instruction-instruction_handler
db 'pmulld',40h
dw sse4_instruction_66_38-instruction_handler
db 'pmullw',0D5h
dw basic_mmx_instruction-instruction_handler
db 'popcnt',0B8h
dw popcnt_instruction-instruction_handler
db 'psadbw',0F6h
dw basic_mmx_instruction-instruction_handler
db 'pshufb',0
dw ssse3_instruction-instruction_handler
db 'pshufd',66h
dw pshufd_instruction-instruction_handler
db 'pshufw',0
dw pshufw_instruction-instruction_handler
db 'psignb',8
dw ssse3_instruction-instruction_handler
db 'psignd',0Ah
dw ssse3_instruction-instruction_handler
db 'psignw',9
dw ssse3_instruction-instruction_handler
db 'pslldq',111b
dw pslldq_instruction-instruction_handler
db 'psrldq',011b
dw pslldq_instruction-instruction_handler
db 'psubsb',0E8h
dw basic_mmx_instruction-instruction_handler
db 'psubsw',0E9h
dw basic_mmx_instruction-instruction_handler
db 'pswapd',0BBh
dw amd3dnow_instruction-instruction_handler
db 'public',0
dw public_directive-instruction_handler
db 'pushad',60h
dw simple_instruction_32bit_except64-instruction_handler
db 'pushaw',60h
dw simple_instruction_16bit_except64-instruction_handler
db 'pushfd',9Ch
dw simple_instruction_32bit_except64-instruction_handler
db 'pushfq',9Ch
dw simple_instruction_only64-instruction_handler
db 'pushfw',9Ch
dw simple_instruction_16bit-instruction_handler
db 'rdmsrq',32h
dw simple_extended_instruction_64bit-instruction_handler
db 'rdpkru',0EEh
dw simple_instruction_0f_01-instruction_handler
db 'rdrand',110b
dw rdrand_instruction-instruction_handler
db 'rdseed',111b
dw rdrand_instruction-instruction_handler
db 'rdtscp',0F9h
dw simple_instruction_0f_01-instruction_handler
db 'repeat',0
dw repeat_directive-instruction_handler
db 'setalc',0D6h
dw simple_instruction_except64-instruction_handler
db 'setnae',92h
dw set_instruction-instruction_handler
db 'setnbe',97h
dw set_instruction-instruction_handler
db 'setnge',9Ch
dw set_instruction-instruction_handler
db 'setnle',9Fh
dw set_instruction-instruction_handler
db 'sfence',0F8h
dw fence_instruction-instruction_handler
db 'shufpd',0C6h
dw sse_pd_instruction_imm8-instruction_handler
db 'shufps',0C6h
dw sse_ps_instruction_imm8-instruction_handler
db 'skinit',0
dw skinit_instruction-instruction_handler
db 'slwpcb',1
dw llwpcb_instruction-instruction_handler
db 'sqrtpd',51h
dw sse_pd_instruction-instruction_handler
db 'sqrtps',51h
dw sse_ps_instruction-instruction_handler
db 'sqrtsd',51h
dw sse_sd_instruction-instruction_handler
db 'sqrtss',51h
dw sse_ss_instruction-instruction_handler
db 'swapgs',0F8h
dw swapgs_instruction-instruction_handler
db 'sysret',07h
dw simple_extended_instruction-instruction_handler
db 't1mskc',17h
dw tbm_instruction-instruction_handler
db 'vaddpd',58h
dw avx_pd_instruction_er-instruction_handler
db 'vaddps',58h
dw avx_ps_instruction_er-instruction_handler
db 'vaddsd',58h
dw avx_sd_instruction_er-instruction_handler
db 'vaddss',58h
dw avx_ss_instruction_er-instruction_handler
db 'vandpd',54h
dw avx_pd_instruction-instruction_handler
db 'vandps',54h
dw avx_ps_instruction-instruction_handler
db 'vcmppd',-1
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpps',-1
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpsd',-1
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpss',-1
dw avx_cmp_ss_instruction-instruction_handler
db 'vdivpd',5Eh
dw avx_pd_instruction_er-instruction_handler
db 'vdivps',5Eh
dw avx_ps_instruction_er-instruction_handler
db 'vdivsd',5Eh
dw avx_sd_instruction_er-instruction_handler
db 'vdivss',5Eh
dw avx_ss_instruction_er-instruction_handler
db 'vlddqu',0F0h
dw avx_lddqu_instruction-instruction_handler
db 'vmaxpd',5Fh
dw avx_pd_instruction_sae-instruction_handler
db 'vmaxps',5Fh
dw avx_ps_instruction_sae-instruction_handler
db 'vmaxsd',5Fh
dw avx_sd_instruction_sae-instruction_handler
db 'vmaxss',5Fh
dw avx_ss_instruction_sae-instruction_handler
db 'vmcall',0C1h
dw simple_instruction_0f_01-instruction_handler
db 'vmfunc',0D4h
dw simple_instruction_0f_01-instruction_handler
db 'vminpd',5Dh
dw avx_pd_instruction_sae-instruction_handler
db 'vminps',5Dh
dw avx_ps_instruction_sae-instruction_handler
db 'vminsd',5Dh
dw avx_sd_instruction_sae-instruction_handler
db 'vminss',5Dh
dw avx_ss_instruction_sae-instruction_handler
db 'vmload',0DAh
dw simple_svm_instruction-instruction_handler
db 'vmovsd',0
dw avx_movsd_instruction-instruction_handler
db 'vmovss',0
dw avx_movss_instruction-instruction_handler
db 'vmread',0
dw vmread_instruction-instruction_handler
db 'vmsave',0DBh
dw simple_svm_instruction-instruction_handler
db 'vmulpd',59h
dw avx_pd_instruction_er-instruction_handler
db 'vmulps',59h
dw avx_ps_instruction_er-instruction_handler
db 'vmulsd',59h
dw avx_sd_instruction_er-instruction_handler
db 'vmulss',59h
dw avx_ss_instruction_er-instruction_handler
db 'vmxoff',0C4h
dw simple_instruction_0f_01-instruction_handler
db 'vpabsb',1Ch
dw avx_single_source_bw_instruction_38-instruction_handler
db 'vpabsd',1Eh
dw avx_single_source_d_instruction_38-instruction_handler
db 'vpabsq',1Fh
dw avx_single_source_q_instruction_38_evex-instruction_handler
db 'vpabsw',1Dh
dw avx_single_source_bw_instruction_38-instruction_handler
db 'vpaddb',0FCh
dw avx_bw_instruction-instruction_handler
db 'vpaddd',0FEh
dw avx_d_instruction-instruction_handler
db 'vpaddq',0D4h
dw avx_q_instruction-instruction_handler
db 'vpaddw',0FDh
dw avx_bw_instruction-instruction_handler
db 'vpandd',0DBh
dw avx_d_instruction_evex-instruction_handler
db 'vpandn',0DFh
dw avx_pd_instruction_noevex-instruction_handler
db 'vpandq',0DBh
dw avx_q_instruction_evex-instruction_handler
db 'vpavgb',0E0h
dw avx_bw_instruction-instruction_handler
db 'vpavgw',0E3h
dw avx_bw_instruction-instruction_handler
db 'vpcmov',0A2h
dw vpcmov_instruction-instruction_handler
db 'vpcmpb',-1
dw avx512_cmp_b_instruction-instruction_handler
db 'vpcmpd',-1
dw avx512_cmp_d_instruction-instruction_handler
db 'vpcmpq',-1
dw avx512_cmp_q_instruction-instruction_handler
db 'vpcmpw',-1
dw avx512_cmp_w_instruction-instruction_handler
db 'vpcomb',-1
dw xop_pcom_b_instruction-instruction_handler
db 'vpcomd',-1
dw xop_pcom_d_instruction-instruction_handler
db 'vpcomq',-1
dw xop_pcom_q_instruction-instruction_handler
db 'vpcomw',-1
dw xop_pcom_w_instruction-instruction_handler
db 'vpermb',8Dh
dw avx_bw_instruction_38_evex-instruction_handler
db 'vpermd',36h
dw avx_permd_instruction-instruction_handler
db 'vpermq',0
dw avx_permq_instruction-instruction_handler
db 'vpermw',8Dh
dw avx_bw_instruction_38_w1_evex-instruction_handler
db 'vpperm',0A3h
dw xop_128bit_instruction-instruction_handler
db 'vprold',1
dw avx512_rotate_d_instruction-instruction_handler
db 'vprolq',1
dw avx512_rotate_q_instruction-instruction_handler
db 'vprord',0
dw avx512_rotate_d_instruction-instruction_handler
db 'vprorq',0
dw avx512_rotate_q_instruction-instruction_handler
db 'vprotb',90h
dw xop_shift_instruction-instruction_handler
db 'vprotd',92h
dw xop_shift_instruction-instruction_handler
db 'vprotq',93h
dw xop_shift_instruction-instruction_handler
db 'vprotw',91h
dw xop_shift_instruction-instruction_handler
db 'vpshab',98h
dw xop_shift_instruction-instruction_handler
db 'vpshad',9Ah
dw xop_shift_instruction-instruction_handler
db 'vpshaq',9Bh
dw xop_shift_instruction-instruction_handler
db 'vpshaw',99h
dw xop_shift_instruction-instruction_handler
db 'vpshlb',94h
dw xop_shift_instruction-instruction_handler
db 'vpshld',96h
dw xop_shift_instruction-instruction_handler
db 'vpshlq',97h
dw xop_shift_instruction-instruction_handler
db 'vpshlw',95h
dw xop_shift_instruction-instruction_handler
db 'vpslld',0F2h
dw avx_shift_d_instruction-instruction_handler
db 'vpsllq',0F3h
dw avx_shift_q_instruction-instruction_handler
db 'vpsllw',0F1h
dw avx_shift_bw_instruction-instruction_handler
db 'vpsrad',0E2h
dw avx_shift_d_instruction-instruction_handler
db 'vpsraq',0E2h
dw avx_shift_q_instruction_evex-instruction_handler
db 'vpsraw',0E1h
dw avx_shift_bw_instruction-instruction_handler
db 'vpsrld',0D2h
dw avx_shift_d_instruction-instruction_handler
db 'vpsrlq',0D3h
dw avx_shift_q_instruction-instruction_handler
db 'vpsrlw',0D1h
dw avx_shift_bw_instruction-instruction_handler
db 'vpsubb',0F8h
dw avx_bw_instruction-instruction_handler
db 'vpsubd',0FAh
dw avx_d_instruction-instruction_handler
db 'vpsubq',0FBh
dw avx_q_instruction-instruction_handler
db 'vpsubw',0F9h
dw avx_bw_instruction-instruction_handler
db 'vptest',17h
dw avx_single_source_instruction_38_noevex-instruction_handler
db 'vpxord',0EFh
dw avx_d_instruction_evex-instruction_handler
db 'vpxorq',0EFh
dw avx_q_instruction_evex-instruction_handler
db 'vrcpps',53h
dw avx_single_source_ps_instruction_noevex-instruction_handler
db 'vrcpss',53h
dw avx_ss_instruction_noevex-instruction_handler
db 'vsubpd',5Ch
dw avx_pd_instruction_er-instruction_handler
db 'vsubps',5Ch
dw avx_ps_instruction_er-instruction_handler
db 'vsubsd',5Ch
dw avx_sd_instruction_er-instruction_handler
db 'vsubss',5Ch
dw avx_ss_instruction_er-instruction_handler
db 'vxorpd',57h
dw avx_pd_instruction-instruction_handler
db 'vxorps',57h
dw avx_ps_instruction-instruction_handler
db 'wbinvd',9
dw simple_extended_instruction-instruction_handler
db 'wrmsrq',30h
dw simple_extended_instruction_64bit-instruction_handler
db 'wrpkru',0EFh
dw simple_instruction_0f_01-instruction_handler
db 'xabort',0
dw xabort_instruction-instruction_handler
db 'xbegin',0
dw xbegin_instruction-instruction_handler
db 'xgetbv',0D0h
dw simple_instruction_0f_01-instruction_handler
db 'xrstor',101b
dw fxsave_instruction-instruction_handler
db 'xsetbv',0D1h
dw simple_instruction_0f_01-instruction_handler
instructions_7:
db 'blcfill',11h
dw tbm_instruction-instruction_handler
db 'blendpd',0Dh
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'blendps',0Ch
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'blsfill',12h
dw tbm_instruction-instruction_handler
db 'clflush',111b
dw fxsave_instruction-instruction_handler
db 'cmovnae',42h
dw bs_instruction-instruction_handler
db 'cmovnbe',47h
dw bs_instruction-instruction_handler
db 'cmovnge',4Ch
dw bs_instruction-instruction_handler
db 'cmovnle',4Fh
dw bs_instruction-instruction_handler
db 'cmpeqpd',0
dw cmp_pd_instruction-instruction_handler
db 'cmpeqps',0
dw cmp_ps_instruction-instruction_handler
db 'cmpeqsd',0
dw cmp_sd_instruction-instruction_handler
db 'cmpeqss',0
dw cmp_ss_instruction-instruction_handler
db 'cmplepd',2
dw cmp_pd_instruction-instruction_handler
db 'cmpleps',2
dw cmp_ps_instruction-instruction_handler
db 'cmplesd',2
dw cmp_sd_instruction-instruction_handler
db 'cmpless',2
dw cmp_ss_instruction-instruction_handler
db 'cmpltpd',1
dw cmp_pd_instruction-instruction_handler
db 'cmpltps',1
dw cmp_ps_instruction-instruction_handler
db 'cmpltsd',1
dw cmp_sd_instruction-instruction_handler
db 'cmpltss',1
dw cmp_ss_instruction-instruction_handler
db 'cmpxchg',0B0h
dw basic_486_instruction-instruction_handler
db 'display',0
dw display_directive-instruction_handler
db 'fcmovbe',0D0h
dw fcmov_instruction-instruction_handler
db 'fcmovnb',0C0h
dw fcomi_instruction-instruction_handler
db 'fcmovne',0C8h
dw fcomi_instruction-instruction_handler
db 'fcmovnu',0D8h
dw fcomi_instruction-instruction_handler
db 'fdecstp',110110b
dw simple_fpu_instruction-instruction_handler
db 'fincstp',110111b
dw simple_fpu_instruction-instruction_handler
db 'fldenvd',4
dw fldenv_instruction_32bit-instruction_handler
db 'fldenvw',4
dw fldenv_instruction_16bit-instruction_handler
db 'fnsaved',6
dw fnsave_instruction_32bit-instruction_handler
db 'fnsavew',6
dw fnsave_instruction_16bit-instruction_handler
db 'fnstenv',6
dw fldenv_instruction-instruction_handler
db 'frndint',111100b
dw simple_fpu_instruction-instruction_handler
db 'frstord',4
dw fnsave_instruction_32bit-instruction_handler
db 'frstorw',4
dw fnsave_instruction_16bit-instruction_handler
db 'fsincos',111011b
dw simple_fpu_instruction-instruction_handler
db 'fstenvd',6
dw fstenv_instruction_32bit-instruction_handler
db 'fstenvw',6
dw fstenv_instruction_16bit-instruction_handler
db 'fucomip',0E8h
dw fcomip_instruction-instruction_handler
db 'fucompp',0
dw fucompp_instruction-instruction_handler
db 'fxrstor',1
dw fxsave_instruction-instruction_handler
db 'fxtract',110100b
dw simple_fpu_instruction-instruction_handler
db 'fyl2xp1',111001b
dw simple_fpu_instruction-instruction_handler
db 'insertq',0
dw insertq_instruction-instruction_handler
db 'invlpga',0DFh
dw invlpga_instruction-instruction_handler
db 'invpcid',82h
dw vmx_inv_instruction-instruction_handler
db 'invvpid',81h
dw vmx_inv_instruction-instruction_handler
db 'ldmxcsr',10b
dw fxsave_instruction-instruction_handler
db 'loopned',0E0h
dw loop_instruction_32bit-instruction_handler
db 'loopneq',0E0h
dw loop_instruction_64bit-instruction_handler
db 'loopnew',0E0h
dw loop_instruction_16bit-instruction_handler
db 'loopnzd',0E0h
dw loop_instruction_32bit-instruction_handler
db 'loopnzq',0E0h
dw loop_instruction_64bit-instruction_handler
db 'loopnzw',0E0h
dw loop_instruction_16bit-instruction_handler
db 'monitor',0C8h
dw monitor_instruction-instruction_handler
db 'movddup',12h
dw sse_sd_instruction-instruction_handler
db 'movdq2q',0
dw movdq2q_instruction-instruction_handler
db 'movhlps',12h
dw movhlps_instruction-instruction_handler
db 'movlhps',16h
dw movhlps_instruction-instruction_handler
db 'movntdq',0E7h
dw movntpd_instruction-instruction_handler
db 'movntpd',2Bh
dw movntpd_instruction-instruction_handler
db 'movntps',2Bh
dw movntps_instruction-instruction_handler
db 'movntsd',2Bh
dw movntsd_instruction-instruction_handler
db 'movntss',2Bh
dw movntss_instruction-instruction_handler
db 'movq2dq',0
dw movq2dq_instruction-instruction_handler
db 'mpsadbw',42h
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'paddusb',0DCh
dw basic_mmx_instruction-instruction_handler
db 'paddusw',0DDh
dw basic_mmx_instruction-instruction_handler
db 'palignr',0
dw palignr_instruction-instruction_handler
db 'pavgusb',0BFh
dw amd3dnow_instruction-instruction_handler
db 'pblendw',0Eh
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'pcmpeqb',74h
dw basic_mmx_instruction-instruction_handler
db 'pcmpeqd',76h
dw basic_mmx_instruction-instruction_handler
db 'pcmpeqq',29h
dw sse4_instruction_66_38-instruction_handler
db 'pcmpeqw',75h
dw basic_mmx_instruction-instruction_handler
db 'pcmpgtb',64h
dw basic_mmx_instruction-instruction_handler
db 'pcmpgtd',66h
dw basic_mmx_instruction-instruction_handler
db 'pcmpgtq',37h
dw sse4_instruction_66_38-instruction_handler
db 'pcmpgtw',65h
dw basic_mmx_instruction-instruction_handler
db 'pcommit',0F8h
dw pcommit_instruction-instruction_handler
db 'pfcmpeq',0B0h
dw amd3dnow_instruction-instruction_handler
db 'pfcmpge',90h
dw amd3dnow_instruction-instruction_handler
db 'pfcmpgt',0A0h
dw amd3dnow_instruction-instruction_handler
db 'pfpnacc',8Eh
dw amd3dnow_instruction-instruction_handler
db 'pfrsqrt',97h
dw amd3dnow_instruction-instruction_handler
db 'phaddsw',3
dw ssse3_instruction-instruction_handler
db 'phsubsw',7
dw ssse3_instruction-instruction_handler
db 'pmaddwd',0F5h
dw basic_mmx_instruction-instruction_handler
db 'pmulhrw',0B7h
dw amd3dnow_instruction-instruction_handler
db 'pmulhuw',0E4h
dw basic_mmx_instruction-instruction_handler
db 'pmuludq',0F4h
dw basic_mmx_instruction-instruction_handler
db 'pshufhw',0F3h
dw pshufd_instruction-instruction_handler
db 'pshuflw',0F2h
dw pshufd_instruction-instruction_handler
db 'psubusb',0D8h
dw basic_mmx_instruction-instruction_handler
db 'psubusw',0D9h
dw basic_mmx_instruction-instruction_handler
db 'roundpd',9
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'roundps',8
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'roundsd',0Bh
dw sse4_sd_instruction_66_3a_imm8-instruction_handler
db 'roundss',0Ah
dw sse4_ss_instruction_66_3a_imm8-instruction_handler
db 'rsqrtps',52h
dw sse_ps_instruction-instruction_handler
db 'rsqrtss',52h
dw sse_ss_instruction-instruction_handler
db 'section',0
dw section_directive-instruction_handler
db 'segment',0
dw segment_directive-instruction_handler
db 'stmxcsr',11b
dw fxsave_instruction-instruction_handler
db 'syscall',05h
dw simple_extended_instruction-instruction_handler
db 'sysexit',35h
dw simple_extended_instruction-instruction_handler
db 'sysretq',07h
dw simple_extended_instruction_64bit-instruction_handler
db 'ucomisd',2Eh
dw comisd_instruction-instruction_handler
db 'ucomiss',2Eh
dw comiss_instruction-instruction_handler
db 'vaesdec',0DEh
dw avx_128bit_instruction_38_noevex-instruction_handler
db 'vaesenc',0DCh
dw avx_128bit_instruction_38_noevex-instruction_handler
db 'vaesimc',0DBh
dw avx_single_source_128bit_instruction_38_noevex-instruction_handler
db 'valignd',3
dw avx_d_instruction_3a_imm8_evex-instruction_handler
db 'valignq',3
dw avx_q_instruction_3a_imm8_evex-instruction_handler
db 'vandnpd',55h
dw avx_pd_instruction-instruction_handler
db 'vandnps',55h
dw avx_ps_instruction-instruction_handler
db 'vcomisd',2Fh
dw avx_comisd_instruction-instruction_handler
db 'vcomiss',2Fh
dw avx_comiss_instruction-instruction_handler
db 'vexp2pd',0C8h
dw avx512_exp2pd_instruction-instruction_handler
db 'vexp2ps',0C8h
dw avx512_exp2ps_instruction-instruction_handler
db 'vfrczpd',81h
dw xop_single_source_instruction-instruction_handler
db 'vfrczps',80h
dw xop_single_source_instruction-instruction_handler
db 'vfrczsd',83h
dw xop_single_source_sd_instruction-instruction_handler
db 'vfrczss',82h
dw xop_single_source_ss_instruction-instruction_handler
db 'vhaddpd',07Ch
dw avx_pd_instruction_noevex-instruction_handler
db 'vhaddps',07Ch
dw avx_ps_instruction_noevex-instruction_handler
db 'vhsubpd',07Dh
dw avx_pd_instruction_noevex-instruction_handler
db 'vhsubps',07Dh
dw avx_ps_instruction_noevex-instruction_handler
db 'virtual',0
dw virtual_directive-instruction_handler
db 'vmclear',6
dw vmclear_instruction-instruction_handler
db 'vmmcall',0D9h
dw simple_instruction_0f_01-instruction_handler
db 'vmovapd',28h
dw avx_movpd_instruction-instruction_handler
db 'vmovaps',28h
dw avx_movps_instruction-instruction_handler
db 'vmovdqa',6Fh
dw avx_movdqa_instruction-instruction_handler
db 'vmovdqu',6Fh
dw avx_movdqu_instruction-instruction_handler
db 'vmovhpd',16h
dw avx_movlpd_instruction-instruction_handler
db 'vmovhps',16h
dw avx_movlps_instruction-instruction_handler
db 'vmovlpd',12h
dw avx_movlpd_instruction-instruction_handler
db 'vmovlps',12h
dw avx_movlps_instruction-instruction_handler
db 'vmovupd',10h
dw avx_movpd_instruction-instruction_handler
db 'vmovups',10h
dw avx_movps_instruction-instruction_handler
db 'vmptrld',6
dw vmx_instruction-instruction_handler
db 'vmptrst',7
dw vmx_instruction-instruction_handler
db 'vmwrite',0
dw vmwrite_instruction-instruction_handler
db 'vpaddsb',0ECh
dw avx_bw_instruction-instruction_handler
db 'vpaddsw',0EDh
dw avx_bw_instruction-instruction_handler
db 'vpandnd',0DFh
dw avx_d_instruction_evex-instruction_handler
db 'vpandnq',0DFh
dw avx_q_instruction_evex-instruction_handler
db 'vpcmpub',-1
dw avx512_cmp_ub_instruction-instruction_handler
db 'vpcmpud',-1
dw avx512_cmp_ud_instruction-instruction_handler
db 'vpcmpuq',-1
dw avx512_cmp_uq_instruction-instruction_handler
db 'vpcmpuw',-1
dw avx512_cmp_uw_instruction-instruction_handler
db 'vpcomub',-1
dw xop_pcom_ub_instruction-instruction_handler
db 'vpcomud',-1
dw xop_pcom_ud_instruction-instruction_handler
db 'vpcomuq',-1
dw xop_pcom_uq_instruction-instruction_handler
db 'vpcomuw',-1
dw xop_pcom_uw_instruction-instruction_handler
db 'vpermpd',1
dw avx_permq_instruction-instruction_handler
db 'vpermps',16h
dw avx_permd_instruction-instruction_handler
db 'vpextrb',14h
dw avx_extract_b_instruction-instruction_handler
db 'vpextrd',16h
dw avx_extract_d_instruction-instruction_handler
db 'vpextrq',16h
dw avx_extract_q_instruction-instruction_handler
db 'vpextrw',15h
dw avx_extract_w_instruction-instruction_handler
db 'vphaddd',2
dw avx_pi_instruction_38_noevex-instruction_handler
db 'vphaddw',1
dw avx_pi_instruction_38_noevex-instruction_handler
db 'vphsubd',6
dw avx_pi_instruction_38_noevex-instruction_handler
db 'vphsubw',5
dw avx_pi_instruction_38_noevex-instruction_handler
db 'vpinsrb',20h
dw avx_pinsrb_instruction-instruction_handler
db 'vpinsrd',22h
dw avx_pinsrd_instruction-instruction_handler
db 'vpinsrq',22h
dw avx_pinsrq_instruction-instruction_handler
db 'vpinsrw',0C4h
dw avx_pinsrw_instruction-instruction_handler
db 'vpmaxsb',3Ch
dw avx_bw_instruction_38-instruction_handler
db 'vpmaxsd',3Dh
dw avx_d_instruction_38-instruction_handler
db 'vpmaxsq',3Dh
dw avx_q_instruction_38_evex-instruction_handler
db 'vpmaxsw',0EEh
dw avx_bw_instruction-instruction_handler
db 'vpmaxub',0DEh
dw avx_bw_instruction-instruction_handler
db 'vpmaxud',3Fh
dw avx_d_instruction_38-instruction_handler
db 'vpmaxuq',3Fh
dw avx_q_instruction_38_evex-instruction_handler
db 'vpmaxuw',3Eh
dw avx_bw_instruction_38-instruction_handler
db 'vpminsb',38h
dw avx_bw_instruction_38-instruction_handler
db 'vpminsd',39h
dw avx_d_instruction_38-instruction_handler
db 'vpminsq',39h
dw avx_q_instruction_38_evex-instruction_handler
db 'vpminsw',0EAh
dw avx_bw_instruction-instruction_handler
db 'vpminub',0DAh
dw avx_bw_instruction-instruction_handler
db 'vpminud',3Bh
dw avx_d_instruction_38-instruction_handler
db 'vpminuq',3Bh
dw avx_q_instruction_38_evex-instruction_handler
db 'vpminuw',3Ah
dw avx_bw_instruction_38-instruction_handler
db 'vpmovdb',31h
dw avx512_pmovdb_instruction-instruction_handler
db 'vpmovdw',33h
dw avx512_pmovwb_instruction-instruction_handler
db 'vpmovqb',32h
dw avx512_pmovqb_instruction-instruction_handler
db 'vpmovqd',35h
dw avx512_pmovwb_instruction-instruction_handler
db 'vpmovqw',34h
dw avx512_pmovdb_instruction-instruction_handler
db 'vpmovwb',30h
dw avx512_pmovwb_instruction-instruction_handler
db 'vpmuldq',28h
dw avx_q_instruction_38-instruction_handler
db 'vpmulhw',0E5h
dw avx_bw_instruction-instruction_handler
db 'vpmulld',40h
dw avx_d_instruction_38-instruction_handler
db 'vpmullq',40h
dw avx_q_instruction_38_evex-instruction_handler
db 'vpmullw',0D5h
dw avx_bw_instruction-instruction_handler
db 'vprolvd',15h
dw avx_d_instruction_38_evex-instruction_handler
db 'vprolvq',15h
dw avx_q_instruction_38_evex-instruction_handler
db 'vprorvd',14h
dw avx_d_instruction_38_evex-instruction_handler
db 'vprorvq',14h
dw avx_q_instruction_38_evex-instruction_handler
db 'vpsadbw',0F6h
dw avx_bw_instruction-instruction_handler
db 'vpshufb',0
dw avx_bw_instruction_38-instruction_handler
db 'vpshufd',70h
dw avx_single_source_d_instruction_imm8-instruction_handler
db 'vpsignb',8
dw avx_pi_instruction_38_noevex-instruction_handler
db 'vpsignd',0Ah
dw avx_pi_instruction_38_noevex-instruction_handler
db 'vpsignw',9
dw avx_pi_instruction_38_noevex-instruction_handler
db 'vpslldq',111b
dw avx_shift_dq_instruction-instruction_handler
db 'vpsllvd',47h
dw avx_d_instruction_38-instruction_handler
db 'vpsllvq',47h
dw avx_q_instruction_38_w1-instruction_handler
db 'vpsllvw',12h
dw avx_bw_instruction_38_w1_evex-instruction_handler
db 'vpsravd',46h
dw avx_d_instruction_38-instruction_handler
db 'vpsravq',46h
dw avx_q_instruction_38_w1_evex-instruction_handler
db 'vpsravw',11h
dw avx_bw_instruction_38_w1_evex-instruction_handler
db 'vpsrldq',011b
dw avx_shift_dq_instruction-instruction_handler
db 'vpsrlvd',45h
dw avx_d_instruction_38-instruction_handler
db 'vpsrlvq',45h
dw avx_q_instruction_38_w1-instruction_handler
db 'vpsrlvw',10h
dw avx_bw_instruction_38_w1_evex-instruction_handler
db 'vpsubsb',0E8h
dw avx_bw_instruction-instruction_handler
db 'vpsubsw',0E9h
dw avx_bw_instruction-instruction_handler
db 'vshufpd',0C6h
dw avx_pd_instruction_imm8-instruction_handler
db 'vshufps',0C6h
dw avx_ps_instruction_imm8-instruction_handler
db 'vsqrtpd',51h
dw avx_single_source_pd_instruction_er-instruction_handler
db 'vsqrtps',51h
dw avx_single_source_ps_instruction_er-instruction_handler
db 'vsqrtsd',51h
dw avx_sd_instruction_er-instruction_handler
db 'vsqrtss',51h
dw avx_ss_instruction_er-instruction_handler
db 'vtestpd',0Fh
dw avx_single_source_instruction_38_noevex-instruction_handler
db 'vtestps',0Eh
dw avx_single_source_instruction_38_noevex-instruction_handler
db 'xsave64',100b
dw fxsave_instruction_64bit-instruction_handler
instructions_8:
db 'addsubpd',0D0h
dw sse_pd_instruction-instruction_handler
db 'addsubps',0D0h
dw cvtpd2dq_instruction-instruction_handler
db 'blendvpd',15h
dw sse4_instruction_66_38_xmm0-instruction_handler
db 'blendvps',14h
dw sse4_instruction_66_38_xmm0-instruction_handler
db 'cmpneqpd',4
dw cmp_pd_instruction-instruction_handler
db 'cmpneqps',4
dw cmp_ps_instruction-instruction_handler
db 'cmpneqsd',4
dw cmp_sd_instruction-instruction_handler
db 'cmpneqss',4
dw cmp_ss_instruction-instruction_handler
db 'cmpnlepd',6
dw cmp_pd_instruction-instruction_handler
db 'cmpnleps',6
dw cmp_ps_instruction-instruction_handler
db 'cmpnlesd',6
dw cmp_sd_instruction-instruction_handler
db 'cmpnless',6
dw cmp_ss_instruction-instruction_handler
db 'cmpnltpd',5
dw cmp_pd_instruction-instruction_handler
db 'cmpnltps',5
dw cmp_ps_instruction-instruction_handler
db 'cmpnltsd',5
dw cmp_sd_instruction-instruction_handler
db 'cmpnltss',5
dw cmp_ss_instruction-instruction_handler
db 'cmpordpd',7
dw cmp_pd_instruction-instruction_handler
db 'cmpordps',7
dw cmp_ps_instruction-instruction_handler
db 'cmpordsd',7
dw cmp_sd_instruction-instruction_handler
db 'cmpordss',7
dw cmp_ss_instruction-instruction_handler
db 'cvtdq2pd',0E6h
dw cvtdq2pd_instruction-instruction_handler
db 'cvtdq2ps',5Bh
dw sse_ps_instruction-instruction_handler
db 'cvtpd2dq',0E6h
dw cvtpd2dq_instruction-instruction_handler
db 'cvtpd2pi',2Dh
dw cvtpd2pi_instruction-instruction_handler
db 'cvtpd2ps',5Ah
dw sse_pd_instruction-instruction_handler
db 'cvtpi2pd',2Ah
dw cvtpi2pd_instruction-instruction_handler
db 'cvtpi2ps',2Ah
dw cvtpi2ps_instruction-instruction_handler
db 'cvtps2dq',5Bh
dw sse_pd_instruction-instruction_handler
db 'cvtps2pd',5Ah
dw cvtps2pd_instruction-instruction_handler
db 'cvtps2pi',2Dh
dw cvtps2pi_instruction-instruction_handler
db 'cvtsd2si',2Dh
dw cvtsd2si_instruction-instruction_handler
db 'cvtsd2ss',5Ah
dw sse_sd_instruction-instruction_handler
db 'cvtsi2sd',2Ah
dw cvtsi2sd_instruction-instruction_handler
db 'cvtsi2ss',2Ah
dw cvtsi2ss_instruction-instruction_handler
db 'cvtss2sd',5Ah
dw sse_ss_instruction-instruction_handler
db 'cvtss2si',2Dh
dw cvtss2si_instruction-instruction_handler
db 'fcmovnbe',0D0h
dw fcomi_instruction-instruction_handler
db 'fnstenvd',6
dw fldenv_instruction_32bit-instruction_handler
db 'fnstenvw',6
dw fldenv_instruction_16bit-instruction_handler
db 'fxsave64',0
dw fxsave_instruction_64bit-instruction_handler
db 'insertps',21h
dw insertps_instruction-instruction_handler
db 'kortestb',98h
dw mask_instruction_single_source_b-instruction_handler
db 'kortestd',98h
dw mask_instruction_single_source_d-instruction_handler
db 'kortestq',98h
dw mask_instruction_single_source_q-instruction_handler
db 'kortestw',98h
dw mask_instruction_single_source_w-instruction_handler
db 'kshiftlb',32h
dw mask_shift_instruction_d-instruction_handler
db 'kshiftld',33h
dw mask_shift_instruction_d-instruction_handler
db 'kshiftlq',33h
dw mask_shift_instruction_q-instruction_handler
db 'kshiftlw',32h
dw mask_shift_instruction_q-instruction_handler
db 'kshiftrb',30h
dw mask_shift_instruction_d-instruction_handler
db 'kshiftrd',31h
dw mask_shift_instruction_d-instruction_handler
db 'kshiftrq',31h
dw mask_shift_instruction_q-instruction_handler
db 'kshiftrw',30h
dw mask_shift_instruction_q-instruction_handler
db 'kunpckbw',4Bh
dw mask_instruction_b-instruction_handler
db 'kunpckdq',4Bh
dw mask_instruction_q-instruction_handler
db 'kunpckwd',4Bh
dw mask_instruction_w-instruction_handler
db 'maskmovq',0
dw maskmovq_instruction-instruction_handler
db 'movmskpd',0
dw movmskpd_instruction-instruction_handler
db 'movmskps',0
dw movmskps_instruction-instruction_handler
db 'movntdqa',2Ah
dw movntdqa_instruction-instruction_handler
db 'movshdup',16h
dw movshdup_instruction-instruction_handler
db 'movsldup',12h
dw movshdup_instruction-instruction_handler
db 'packssdw',6Bh
dw basic_mmx_instruction-instruction_handler
db 'packsswb',63h
dw basic_mmx_instruction-instruction_handler
db 'packusdw',2Bh
dw sse4_instruction_66_38-instruction_handler
db 'packuswb',67h
dw basic_mmx_instruction-instruction_handler
db 'pblendvb',10h
dw sse4_instruction_66_38_xmm0-instruction_handler
db 'pfrcpit1',0A6h
dw amd3dnow_instruction-instruction_handler
db 'pfrcpit2',0B6h
dw amd3dnow_instruction-instruction_handler
db 'pfrsqit1',0A7h
dw amd3dnow_instruction-instruction_handler
db 'pmovmskb',0D7h
dw pmovmskb_instruction-instruction_handler
db 'pmovsxbd',21h
dw pmovsxbd_instruction-instruction_handler
db 'pmovsxbq',22h
dw pmovsxbq_instruction-instruction_handler
db 'pmovsxbw',20h
dw pmovsxbw_instruction-instruction_handler
db 'pmovsxdq',25h
dw pmovsxdq_instruction-instruction_handler
db 'pmovsxwd',23h
dw pmovsxwd_instruction-instruction_handler
db 'pmovsxwq',24h
dw pmovsxwq_instruction-instruction_handler
db 'pmovzxbd',31h
dw pmovsxbd_instruction-instruction_handler
db 'pmovzxbq',32h
dw pmovsxbq_instruction-instruction_handler
db 'pmovzxbw',30h
dw pmovsxbw_instruction-instruction_handler
db 'pmovzxdq',35h
dw pmovsxdq_instruction-instruction_handler
db 'pmovzxwd',33h
dw pmovsxwd_instruction-instruction_handler
db 'pmovzxwq',34h
dw pmovsxwq_instruction-instruction_handler
db 'pmulhrsw',0Bh
dw ssse3_instruction-instruction_handler
db 'prefetch',0
dw amd_prefetch_instruction-instruction_handler
db 'rdfsbase',0
dw rdfsbase_instruction-instruction_handler
db 'rdgsbase',1
dw rdfsbase_instruction-instruction_handler
db 'sha1msg1',0C9h
dw sse4_instruction_38-instruction_handler
db 'sha1msg2',0CAh
dw sse4_instruction_38-instruction_handler
db 'sysenter',34h
dw simple_extended_instruction-instruction_handler
db 'sysexitq',35h
dw simple_extended_instruction_64bit-instruction_handler
db 'unpckhpd',15h
dw sse_pd_instruction-instruction_handler
db 'unpckhps',15h
dw sse_ps_instruction-instruction_handler
db 'unpcklpd',14h
dw sse_pd_instruction-instruction_handler
db 'unpcklps',14h
dw sse_ps_instruction-instruction_handler
db 'vblendpd',0Dh
dw avx_pi_instruction_3a_imm8_noevex-instruction_handler
db 'vblendps',0Ch
dw avx_pi_instruction_3a_imm8_noevex-instruction_handler
db 'vcmpeqpd',0
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpeqps',0
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpeqsd',0
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpeqss',0
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpgepd',0Dh
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpgeps',0Dh
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpgesd',0Dh
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpgess',0Dh
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpgtpd',0Eh
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpgtps',0Eh
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpgtsd',0Eh
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpgtss',0Eh
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmplepd',2
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpleps',2
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmplesd',2
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpless',2
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpltpd',1
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpltps',1
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpltsd',1
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpltss',1
dw avx_cmp_ss_instruction-instruction_handler
db 'vfmaddpd',69h
dw fma4_instruction_p-instruction_handler
db 'vfmaddps',68h
dw fma4_instruction_p-instruction_handler
db 'vfmaddsd',6Bh
dw fma4_instruction_sd-instruction_handler
db 'vfmaddss',6Ah
dw fma4_instruction_ss-instruction_handler
db 'vfmsubpd',6Dh
dw fma4_instruction_p-instruction_handler
db 'vfmsubps',6Ch
dw fma4_instruction_p-instruction_handler
db 'vfmsubsd',6Fh
dw fma4_instruction_sd-instruction_handler
db 'vfmsubss',6Eh
dw fma4_instruction_ss-instruction_handler
db 'vldmxcsr',10b
dw vldmxcsr_instruction-instruction_handler
db 'vmlaunch',0C2h
dw simple_instruction_0f_01-instruction_handler
db 'vmovddup',12h
dw avx_movddup_instruction-instruction_handler
db 'vmovdqu8',6Fh
dw avx512_movdqu8_instruction-instruction_handler
db 'vmovhlps',12h
dw avx_movhlps_instruction-instruction_handler
db 'vmovlhps',16h
dw avx_movhlps_instruction-instruction_handler
db 'vmovntdq',0E7h
dw avx_movntdq_instruction-instruction_handler
db 'vmovntpd',2Bh
dw avx_movntpd_instruction-instruction_handler
db 'vmovntps',2Bh
dw avx_movntps_instruction-instruction_handler
db 'vmpsadbw',42h
dw avx_pi_instruction_3a_imm8_noevex-instruction_handler
db 'vmresume',0C3h
dw simple_instruction_0f_01-instruction_handler
db 'vpaddusb',0DCh
dw avx_bw_instruction-instruction_handler
db 'vpaddusw',0DDh
dw avx_bw_instruction-instruction_handler
db 'vpalignr',0Fh
dw avx_pi_instruction_3a_imm8-instruction_handler
db 'vpblendd',2
dw avx_pi_instruction_3a_imm8_noevex-instruction_handler
db 'vpblendw',0Eh
dw avx_pi_instruction_3a_imm8_noevex-instruction_handler
db 'vpcmpeqb',74h
dw avx_cmpeqb_instruction-instruction_handler
db 'vpcmpeqd',76h
dw avx_cmpeqd_instruction-instruction_handler
db 'vpcmpeqq',29h
dw avx_cmpeqq_instruction-instruction_handler
db 'vpcmpeqw',75h
dw avx_cmpeqb_instruction-instruction_handler
db 'vpcmpgtb',64h
dw avx_cmpeqb_instruction-instruction_handler
db 'vpcmpgtd',66h
dw avx_cmpeqd_instruction-instruction_handler
db 'vpcmpgtq',37h
dw avx_cmpeqq_instruction-instruction_handler
db 'vpcmpgtw',65h
dw avx_cmpeqb_instruction-instruction_handler
db 'vpcmpleb',2
dw avx512_cmp_b_instruction-instruction_handler
db 'vpcmpled',2
dw avx512_cmp_d_instruction-instruction_handler
db 'vpcmpleq',2
dw avx512_cmp_q_instruction-instruction_handler
db 'vpcmplew',2
dw avx512_cmp_w_instruction-instruction_handler
db 'vpcmpltb',1
dw avx512_cmp_b_instruction-instruction_handler
db 'vpcmpltd',1
dw avx512_cmp_d_instruction-instruction_handler
db 'vpcmpltq',1
dw avx512_cmp_q_instruction-instruction_handler
db 'vpcmpltw',1
dw avx512_cmp_w_instruction-instruction_handler
db 'vpcomeqb',4
dw xop_pcom_b_instruction-instruction_handler
db 'vpcomeqd',4
dw xop_pcom_d_instruction-instruction_handler
db 'vpcomeqq',4
dw xop_pcom_q_instruction-instruction_handler
db 'vpcomeqw',4
dw xop_pcom_w_instruction-instruction_handler
db 'vpcomgeb',3
dw xop_pcom_b_instruction-instruction_handler
db 'vpcomged',3
dw xop_pcom_d_instruction-instruction_handler
db 'vpcomgeq',3
dw xop_pcom_q_instruction-instruction_handler
db 'vpcomgew',3
dw xop_pcom_w_instruction-instruction_handler
db 'vpcomgtb',2
dw xop_pcom_b_instruction-instruction_handler
db 'vpcomgtd',2
dw xop_pcom_d_instruction-instruction_handler
db 'vpcomgtq',2
dw xop_pcom_q_instruction-instruction_handler
db 'vpcomgtw',2
dw xop_pcom_w_instruction-instruction_handler
db 'vpcomleb',1
dw xop_pcom_b_instruction-instruction_handler
db 'vpcomled',1
dw xop_pcom_d_instruction-instruction_handler
db 'vpcomleq',1
dw xop_pcom_q_instruction-instruction_handler
db 'vpcomlew',1
dw xop_pcom_w_instruction-instruction_handler
db 'vpcomltb',0
dw xop_pcom_b_instruction-instruction_handler
db 'vpcomltd',0
dw xop_pcom_d_instruction-instruction_handler
db 'vpcomltq',0
dw xop_pcom_q_instruction-instruction_handler
db 'vpcomltw',0
dw xop_pcom_w_instruction-instruction_handler
db 'vpermi2b',75h
dw avx_bw_instruction_38_evex-instruction_handler
db 'vpermi2d',76h
dw avx_d_instruction_38_evex-instruction_handler
db 'vpermi2q',76h
dw avx_q_instruction_38_evex-instruction_handler
db 'vpermi2w',75h
dw avx_bw_instruction_38_w1_evex-instruction_handler
db 'vpermt2b',7Dh
dw avx_bw_instruction_38_evex-instruction_handler
db 'vpermt2d',7Eh
dw avx_d_instruction_38_evex-instruction_handler
db 'vpermt2q',7Eh
dw avx_q_instruction_38_evex-instruction_handler
db 'vpermt2w',7Dh
dw avx_bw_instruction_38_w1_evex-instruction_handler
db 'vphaddbd',0C2h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphaddbq',0C3h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphaddbw',0C1h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphadddq',0CBh
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphaddsw',3
dw avx_pi_instruction_38_noevex-instruction_handler
db 'vphaddwd',0C6h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphaddwq',0C7h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphsubbw',0E1h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphsubdq',0E3h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphsubsw',7
dw avx_pi_instruction_38_noevex-instruction_handler
db 'vphsubwd',0E2h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vplzcntd',44h
dw avx_single_source_d_instruction_38_evex-instruction_handler
db 'vplzcntq',44h
dw avx_single_source_q_instruction_38_evex-instruction_handler
db 'vpmacsdd',9Eh
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmacswd',96h
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmacsww',95h
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmaddwd',0F5h
dw avx_bw_instruction-instruction_handler
db 'vpmovb2m',29h
dw avx512_pmov_2m_instruction-instruction_handler
db 'vpmovd2m',39h
dw avx512_pmov_2m_instruction-instruction_handler
db 'vpmovm2b',28h
dw avx512_pmov_m2_instruction-instruction_handler
db 'vpmovm2d',38h
dw avx512_pmov_m2_instruction-instruction_handler
db 'vpmovm2q',38h
dw avx512_pmov_m2_instruction_w1-instruction_handler
db 'vpmovm2w',28h
dw avx512_pmov_m2_instruction_w1-instruction_handler
db 'vpmovq2m',39h
dw avx512_pmov_2m_instruction_w1-instruction_handler
db 'vpmovsdb',21h
dw avx512_pmovdb_instruction-instruction_handler
db 'vpmovsdw',23h
dw avx512_pmovwb_instruction-instruction_handler
db 'vpmovsqb',22h
dw avx512_pmovqb_instruction-instruction_handler
db 'vpmovsqd',25h
dw avx512_pmovwb_instruction-instruction_handler
db 'vpmovsqw',24h
dw avx512_pmovdb_instruction-instruction_handler
db 'vpmovswb',20h
dw avx512_pmovwb_instruction-instruction_handler
db 'vpmovw2m',29h
dw avx512_pmov_2m_instruction_w1-instruction_handler
db 'vpmulhuw',0E4h
dw avx_bw_instruction-instruction_handler
db 'vpmuludq',0F4h
dw avx_q_instruction-instruction_handler
db 'vpshufhw',0F3h
dw avx_pshuf_w_instruction-instruction_handler
db 'vpshuflw',0F2h
dw avx_pshuf_w_instruction-instruction_handler
db 'vpsubusb',0D8h
dw avx_bw_instruction-instruction_handler
db 'vpsubusw',0D9h
dw avx_bw_instruction-instruction_handler
db 'vptestmb',26h
dw avx512_ptestmb_instruction-instruction_handler
db 'vptestmd',27h
dw avx512_ptestmd_instruction-instruction_handler
db 'vptestmq',27h
dw avx512_ptestmq_instruction-instruction_handler
db 'vptestmw',26h
dw avx512_ptestmw_instruction-instruction_handler
db 'vrangepd',50h
dw avx512_pd_instruction_sae_imm8-instruction_handler
db 'vrangeps',50h
dw avx512_ps_instruction_sae_imm8-instruction_handler
db 'vrangesd',51h
dw avx512_sd_instruction_sae_imm8-instruction_handler
db 'vrangess',51h
dw avx512_ss_instruction_sae_imm8-instruction_handler
db 'vrcp14pd',4Ch
dw avx512_single_source_pd_instruction-instruction_handler
db 'vrcp14ps',4Ch
dw avx512_single_source_ps_instruction-instruction_handler
db 'vrcp14sd',4Dh
dw avx512_sd_instruction-instruction_handler
db 'vrcp14ss',4Dh
dw avx512_ss_instruction-instruction_handler
db 'vrcp28pd',0CAh
dw avx512_exp2pd_instruction-instruction_handler
db 'vrcp28ps',0CAh
dw avx512_exp2ps_instruction-instruction_handler
db 'vrcp28sd',0CBh
dw avx512_sd_instruction_sae-instruction_handler
db 'vrcp28ss',0CBh
dw avx512_ss_instruction_sae-instruction_handler
db 'vroundpd',9
dw avx_single_source_instruction_3a_imm8_noevex-instruction_handler
db 'vroundps',8
dw avx_single_source_instruction_3a_imm8_noevex-instruction_handler
db 'vroundsd',0Bh
dw avx_sd_instruction_3a_imm8_noevex-instruction_handler
db 'vroundss',0Ah
dw avx_ss_instruction_3a_imm8_noevex-instruction_handler
db 'vrsqrtps',52h
dw avx_single_source_ps_instruction_noevex-instruction_handler
db 'vrsqrtss',52h
dw avx_ss_instruction_noevex-instruction_handler
db 'vstmxcsr',11b
dw vldmxcsr_instruction-instruction_handler
db 'vucomisd',2Eh
dw avx_comisd_instruction-instruction_handler
db 'vucomiss',2Eh
dw avx_comiss_instruction-instruction_handler
db 'vzeroall',77h
dw vzeroall_instruction-instruction_handler
db 'wrfsbase',2
dw rdfsbase_instruction-instruction_handler
db 'wrgsbase',3
dw rdfsbase_instruction-instruction_handler
db 'xacquire',0F2h
dw prefix_instruction-instruction_handler
db 'xrelease',0F3h
dw prefix_instruction-instruction_handler
db 'xrstor64',101b
dw fxsave_instruction_64bit-instruction_handler
db 'xsaveopt',110b
dw fxsave_instruction-instruction_handler
instructions_9:
db 'cmpxchg8b',8
dw cmpxchgx_instruction-instruction_handler
db 'cvttpd2dq',0E6h
dw sse_pd_instruction-instruction_handler
db 'cvttpd2pi',2Ch
dw cvtpd2pi_instruction-instruction_handler
db 'cvttps2dq',5Bh
dw movshdup_instruction-instruction_handler
db 'cvttps2pi',2Ch
dw cvtps2pi_instruction-instruction_handler
db 'cvttsd2si',2Ch
dw cvtsd2si_instruction-instruction_handler
db 'cvttss2si',2Ch
dw cvtss2si_instruction-instruction_handler
db 'extractps',17h
dw extractps_instruction-instruction_handler
db 'fxrstor64',1
dw fxsave_instruction_64bit-instruction_handler
db 'pclmulqdq',-1
dw pclmulqdq_instruction-instruction_handler
db 'pcmpestri',61h
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'pcmpestrm',60h
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'pcmpistri',63h
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'pcmpistrm',62h
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'pmaddubsw',4
dw ssse3_instruction-instruction_handler
db 'prefetchw',1
dw amd_prefetch_instruction-instruction_handler
db 'punpckhbw',68h
dw basic_mmx_instruction-instruction_handler
db 'punpckhdq',6Ah
dw basic_mmx_instruction-instruction_handler
db 'punpckhwd',69h
dw basic_mmx_instruction-instruction_handler
db 'punpcklbw',60h
dw basic_mmx_instruction-instruction_handler
db 'punpckldq',62h
dw basic_mmx_instruction-instruction_handler
db 'punpcklwd',61h
dw basic_mmx_instruction-instruction_handler
db 'sha1nexte',0C8h
dw sse4_instruction_38-instruction_handler
db 'sha1rnds4',0CCh
dw sse4_instruction_3a_imm8-instruction_handler
db 'useavx256',0
dw set_evex_mode-instruction_handler
db 'useavx512',1
dw set_evex_mode-instruction_handler
db 'vaddsubpd',0D0h
dw avx_pd_instruction_noevex-instruction_handler
db 'vaddsubps',0D0h
dw avx_ps_instruction_noevex-instruction_handler
db 'vblendmpd',65h
dw avx_pd_instruction_38_evex-instruction_handler
db 'vblendmps',65h
dw avx_ps_instruction_66_38_evex-instruction_handler
db 'vblendvpd',4Bh
dw avx_triple_source_instruction_3a_noevex-instruction_handler
db 'vblendvps',4Ah
dw avx_triple_source_instruction_3a_noevex-instruction_handler
db 'vcmpneqpd',4
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpneqps',4
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpneqsd',4
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpneqss',4
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpngepd',9
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpngeps',9
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpngesd',9
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpngess',9
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpngtpd',0Ah
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpngtps',0Ah
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpngtsd',0Ah
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpngtss',0Ah
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpnlepd',6
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpnleps',6
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpnlesd',6
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpnless',6
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpnltpd',5
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpnltps',5
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpnltsd',5
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpnltss',5
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpordpd',7
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpordps',7
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpordsd',7
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpordss',7
dw avx_cmp_ss_instruction-instruction_handler
db 'vcvtdq2pd',0E6h
dw avx_cvtdq2pd_instruction-instruction_handler
db 'vcvtdq2ps',5Bh
dw avx_single_source_ps_instruction_er-instruction_handler
db 'vcvtpd2dq',0E6h
dw avx_cvtpd2dq_instruction-instruction_handler
db 'vcvtpd2ps',5Ah
dw avx_cvtpd2ps_instruction-instruction_handler
db 'vcvtpd2qq',7Bh
dw avx_single_source_pd_instruction_er_evex-instruction_handler
db 'vcvtph2ps',13h
dw avx_cvtph2ps_instruction-instruction_handler
db 'vcvtps2dq',5Bh
dw avx_cvtps2dq_instruction-instruction_handler
db 'vcvtps2pd',5Ah
dw avx_cvtps2pd_instruction-instruction_handler
db 'vcvtps2ph',1Dh
dw avx_cvtps2ph_instruction-instruction_handler
db 'vcvtps2qq',7Bh
dw avx_cvtps2qq_instruction-instruction_handler
db 'vcvtqq2pd',0E6h
dw avx_cvtqq2pd_instruction-instruction_handler
db 'vcvtqq2ps',5Bh
dw avx_cvtpd2udq_instruction-instruction_handler
db 'vcvtsd2si',2Dh
dw avx_cvtsd2si_instruction-instruction_handler
db 'vcvtsd2ss',5Ah
dw avx_sd_instruction_er-instruction_handler
db 'vcvtsi2sd',2Ah
dw avx_cvtsi2sd_instruction-instruction_handler
db 'vcvtsi2ss',2Ah
dw avx_cvtsi2ss_instruction-instruction_handler
db 'vcvtss2sd',5Ah
dw avx_ss_instruction_sae-instruction_handler
db 'vcvtss2si',2Dh
dw avx_cvtss2si_instruction-instruction_handler
db 'vdbpsadbw',42h
dw avx_d_instruction_3a_imm8_evex-instruction_handler
db 'vexpandpd',88h
dw avx_single_source_q_instruction_38_evex-instruction_handler
db 'vexpandps',88h
dw avx_single_source_d_instruction_38_evex-instruction_handler
db 'vfnmaddpd',79h
dw fma4_instruction_p-instruction_handler
db 'vfnmaddps',78h
dw fma4_instruction_p-instruction_handler
db 'vfnmaddsd',7Bh
dw fma4_instruction_sd-instruction_handler
db 'vfnmaddss',7Ah
dw fma4_instruction_ss-instruction_handler
db 'vfnmsubpd',7Dh
dw fma4_instruction_p-instruction_handler
db 'vfnmsubps',7Ch
dw fma4_instruction_p-instruction_handler
db 'vfnmsubsd',7Fh
dw fma4_instruction_sd-instruction_handler
db 'vfnmsubss',7Eh
dw fma4_instruction_ss-instruction_handler
db 'vgetexppd',42h
dw avx512_single_source_pd_instruction_sae-instruction_handler
db 'vgetexpps',42h
dw avx512_single_source_ps_instruction_sae-instruction_handler
db 'vgetexpsd',43h
dw avx512_sd_instruction_sae-instruction_handler
db 'vgetexpss',43h
dw avx512_ss_instruction_sae-instruction_handler
db 'vinsertps',21h
dw avx_insertps_instruction-instruction_handler
db 'vmovdqa32',6Fh
dw avx512_movdqa32_instruction-instruction_handler
db 'vmovdqa64',6Fh
dw avx512_movdqa64_instruction-instruction_handler
db 'vmovdqu16',6Fh
dw avx512_movdqu16_instruction-instruction_handler
db 'vmovdqu32',6Fh
dw avx512_movdqu32_instruction-instruction_handler
db 'vmovdqu64',6Fh
dw avx512_movdqu64_instruction-instruction_handler
db 'vmovmskpd',0
dw avx_movmskpd_instruction-instruction_handler
db 'vmovmskps',0
dw avx_movmskps_instruction-instruction_handler
db 'vmovntdqa',2Ah
dw avx_movntdqa_instruction-instruction_handler
db 'vmovshdup',16h
dw avx_movshdup_instruction-instruction_handler
db 'vmovsldup',12h
dw avx_movshdup_instruction-instruction_handler
db 'vpackssdw',6Bh
dw avx_d_instruction-instruction_handler
db 'vpacksswb',63h
dw avx_bw_instruction-instruction_handler
db 'vpackusdw',2Bh
dw avx_d_instruction_38-instruction_handler
db 'vpackuswb',67h
dw avx_bw_instruction-instruction_handler
db 'vpblendmb',66h
dw avx_bw_instruction_38_evex-instruction_handler
db 'vpblendmd',64h
dw avx_d_instruction_38_evex-instruction_handler
db 'vpblendmq',64h
dw avx_q_instruction_38_evex-instruction_handler
db 'vpblendmw',66h
dw avx_bw_instruction_38_w1_evex-instruction_handler
db 'vpblendvb',4Ch
dw avx_triple_source_instruction_3a_noevex-instruction_handler
db 'vpcmpleub',2
dw avx512_cmp_ub_instruction-instruction_handler
db 'vpcmpleud',2
dw avx512_cmp_ud_instruction-instruction_handler
db 'vpcmpleuq',2
dw avx512_cmp_uq_instruction-instruction_handler
db 'vpcmpleuw',2
dw avx512_cmp_uw_instruction-instruction_handler
db 'vpcmpltub',1
dw avx512_cmp_ub_instruction-instruction_handler
db 'vpcmpltud',1
dw avx512_cmp_ud_instruction-instruction_handler
db 'vpcmpltuq',1
dw avx512_cmp_uq_instruction-instruction_handler
db 'vpcmpltuw',1
dw avx512_cmp_uw_instruction-instruction_handler
db 'vpcmpneqb',4
dw avx512_cmp_b_instruction-instruction_handler
db 'vpcmpneqd',4
dw avx512_cmp_d_instruction-instruction_handler
db 'vpcmpneqq',4
dw avx512_cmp_q_instruction-instruction_handler
db 'vpcmpneqw',4
dw avx512_cmp_b_instruction-instruction_handler
db 'vpcmpnleb',6
dw avx512_cmp_b_instruction-instruction_handler
db 'vpcmpnled',6
dw avx512_cmp_d_instruction-instruction_handler
db 'vpcmpnleq',6
dw avx512_cmp_q_instruction-instruction_handler
db 'vpcmpnlew',6
dw avx512_cmp_b_instruction-instruction_handler
db 'vpcmpnltb',5
dw avx512_cmp_b_instruction-instruction_handler
db 'vpcmpnltd',5
dw avx512_cmp_d_instruction-instruction_handler
db 'vpcmpnltq',5
dw avx512_cmp_q_instruction-instruction_handler
db 'vpcmpnltw',5
dw avx512_cmp_b_instruction-instruction_handler
db 'vpcomequb',4
dw xop_pcom_ub_instruction-instruction_handler
db 'vpcomequd',4
dw xop_pcom_ud_instruction-instruction_handler
db 'vpcomequq',4
dw xop_pcom_uq_instruction-instruction_handler
db 'vpcomequw',4
dw xop_pcom_uw_instruction-instruction_handler
db 'vpcomgeub',3
dw xop_pcom_ub_instruction-instruction_handler
db 'vpcomgeud',3
dw xop_pcom_ud_instruction-instruction_handler
db 'vpcomgeuq',3
dw xop_pcom_uq_instruction-instruction_handler
db 'vpcomgeuw',3
dw xop_pcom_uw_instruction-instruction_handler
db 'vpcomgtub',2
dw xop_pcom_ub_instruction-instruction_handler
db 'vpcomgtud',2
dw xop_pcom_ud_instruction-instruction_handler
db 'vpcomgtuq',2
dw xop_pcom_uq_instruction-instruction_handler
db 'vpcomgtuw',2
dw xop_pcom_uw_instruction-instruction_handler
db 'vpcomleub',1
dw xop_pcom_ub_instruction-instruction_handler
db 'vpcomleud',1
dw xop_pcom_ud_instruction-instruction_handler
db 'vpcomleuq',1
dw xop_pcom_uq_instruction-instruction_handler
db 'vpcomleuw',1
dw xop_pcom_uw_instruction-instruction_handler
db 'vpcomltub',0
dw xop_pcom_ub_instruction-instruction_handler
db 'vpcomltud',0
dw xop_pcom_ud_instruction-instruction_handler
db 'vpcomltuq',0
dw xop_pcom_uq_instruction-instruction_handler
db 'vpcomltuw',0
dw xop_pcom_uw_instruction-instruction_handler
db 'vpcomneqb',5
dw xop_pcom_b_instruction-instruction_handler
db 'vpcomneqd',5
dw xop_pcom_d_instruction-instruction_handler
db 'vpcomneqq',5
dw xop_pcom_q_instruction-instruction_handler
db 'vpcomneqw',5
dw xop_pcom_w_instruction-instruction_handler
db 'vpermi2pd',77h
dw avx_q_instruction_38_evex-instruction_handler
db 'vpermi2ps',77h
dw avx_d_instruction_38_evex-instruction_handler
db 'vpermilpd',5
dw avx_permilpd_instruction-instruction_handler
db 'vpermilps',4
dw avx_permilps_instruction-instruction_handler
db 'vpermt2pd',7Fh
dw avx_q_instruction_38_evex-instruction_handler
db 'vpermt2ps',7Fh
dw avx_d_instruction_38_evex-instruction_handler
db 'vpexpandd',89h
dw avx_single_source_d_instruction_38_evex-instruction_handler
db 'vpexpandq',89h
dw avx_single_source_q_instruction_38_evex-instruction_handler
db 'vphaddubd',0D2h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphaddubq',0D3h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphaddubw',0D1h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphaddudq',0DBh
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphadduwd',0D6h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vphadduwq',0D7h
dw xop_single_source_128bit_instruction-instruction_handler
db 'vpmacsdqh',9Fh
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmacsdql',97h
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmacssdd',8Eh
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmacsswd',86h
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmacssww',85h
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmadcswd',0B6h
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmovmskb',0D7h
dw avx_pmovmskb_instruction-instruction_handler
db 'vpmovsxbd',21h
dw avx_pmovsxbd_instruction-instruction_handler
db 'vpmovsxbq',22h
dw avx_pmovsxbq_instruction-instruction_handler
db 'vpmovsxbw',20h
dw avx_pmovsxbw_instruction-instruction_handler
db 'vpmovsxdq',25h
dw avx_pmovsxbw_instruction-instruction_handler
db 'vpmovsxwd',23h
dw avx_pmovsxbw_instruction-instruction_handler
db 'vpmovsxwq',24h
dw avx_pmovsxbd_instruction-instruction_handler
db 'vpmovusdb',11h
dw avx512_pmovdb_instruction-instruction_handler
db 'vpmovusdw',13h
dw avx512_pmovwb_instruction-instruction_handler
db 'vpmovusqb',12h
dw avx512_pmovqb_instruction-instruction_handler
db 'vpmovusqd',15h
dw avx512_pmovwb_instruction-instruction_handler
db 'vpmovusqw',14h
dw avx512_pmovdb_instruction-instruction_handler
db 'vpmovuswb',10h
dw avx512_pmovwb_instruction-instruction_handler
db 'vpmovzxbd',31h
dw avx_pmovsxbd_instruction-instruction_handler
db 'vpmovzxbq',32h
dw avx_pmovsxbq_instruction-instruction_handler
db 'vpmovzxbw',30h
dw avx_pmovsxbw_instruction-instruction_handler
db 'vpmovzxdq',35h
dw avx_pmovsxbw_instruction-instruction_handler
db 'vpmovzxwd',33h
dw avx_pmovsxbw_instruction-instruction_handler
db 'vpmovzxwq',34h
dw avx_pmovsxbd_instruction-instruction_handler
db 'vpmulhrsw',0Bh
dw avx_bw_instruction_38-instruction_handler
db 'vptestnmb',26h
dw avx512_ptestnmb_instruction-instruction_handler
db 'vptestnmd',27h
dw avx512_ptestnmd_instruction-instruction_handler
db 'vptestnmq',27h
dw avx512_ptestnmq_instruction-instruction_handler
db 'vptestnmw',26h
dw avx512_ptestnmw_instruction-instruction_handler
db 'vreducepd',56h
dw avx512_single_source_pd_instruction_sae_imm8-instruction_handler
db 'vreduceps',56h
dw avx512_single_source_ps_instruction_sae_imm8-instruction_handler
db 'vreducesd',57h
dw avx512_sd_instruction_sae_imm8-instruction_handler
db 'vreducess',57h
dw avx512_ss_instruction_sae_imm8-instruction_handler
db 'vscalefpd',2Ch
dw avx512_pd_instruction_er-instruction_handler
db 'vscalefps',2Ch
dw avx512_ps_instruction_er-instruction_handler
db 'vscalefsd',2Dh
dw avx512_sd_instruction_er-instruction_handler
db 'vscalefss',2Dh
dw avx512_ss_instruction_er-instruction_handler
db 'vunpckhpd',15h
dw avx_pd_instruction-instruction_handler
db 'vunpckhps',15h
dw avx_ps_instruction-instruction_handler
db 'vunpcklpd',14h
dw avx_pd_instruction-instruction_handler
db 'vunpcklps',14h
dw avx_ps_instruction-instruction_handler
instructions_10:
db 'aesdeclast',0DFh
dw sse4_instruction_66_38-instruction_handler
db 'aesenclast',0DDh
dw sse4_instruction_66_38-instruction_handler
db 'clflushopt',7
dw clflushopt_instruction-instruction_handler
db 'cmpunordpd',3
dw cmp_pd_instruction-instruction_handler
db 'cmpunordps',3
dw cmp_ps_instruction-instruction_handler
db 'cmpunordsd',3
dw cmp_sd_instruction-instruction_handler
db 'cmpunordss',3
dw cmp_ss_instruction-instruction_handler
db 'cmpxchg16b',16
dw cmpxchgx_instruction-instruction_handler
db 'loadall286',5
dw simple_extended_instruction-instruction_handler
db 'loadall386',7
dw simple_extended_instruction-instruction_handler
db 'maskmovdqu',0
dw maskmovdqu_instruction-instruction_handler
db 'phminposuw',41h
dw sse4_instruction_66_38-instruction_handler
db 'prefetcht0',1
dw prefetch_instruction-instruction_handler
db 'prefetcht1',2
dw prefetch_instruction-instruction_handler
db 'prefetcht2',3
dw prefetch_instruction-instruction_handler
db 'punpckhqdq',6Dh
dw sse_pd_instruction-instruction_handler
db 'punpcklqdq',6Ch
dw sse_pd_instruction-instruction_handler
db 'sha256msg1',0CCh
dw sse4_instruction_38-instruction_handler
db 'sha256msg2',0CDh
dw sse4_instruction_38-instruction_handler
db 'vcmptruepd',0Fh
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmptrueps',0Fh
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmptruesd',0Fh
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmptruess',0Fh
dw avx_cmp_ss_instruction-instruction_handler
db 'vcvtpd2udq',79h
dw avx_cvtpd2udq_instruction-instruction_handler
db 'vcvtpd2uqq',79h
dw avx_single_source_pd_instruction_er_evex-instruction_handler
db 'vcvtps2udq',79h
dw avx_single_source_ps_instruction_er_evex-instruction_handler
db 'vcvtps2uqq',79h
dw avx_cvtps2qq_instruction-instruction_handler
db 'vcvtsd2usi',79h
dw avx_cvtsd2usi_instruction-instruction_handler
db 'vcvtss2usi',79h
dw avx_cvtss2usi_instruction-instruction_handler
db 'vcvttpd2dq',0E6h
dw avx_cvttpd2dq_instruction-instruction_handler
db 'vcvttpd2qq',7Ah
dw avx_single_source_pd_instruction_sae_evex-instruction_handler
db 'vcvttps2dq',5Bh
dw avx_cvttps2dq_instruction-instruction_handler
db 'vcvttps2qq',7Ah
dw avx_cvttps2qq_instruction-instruction_handler
db 'vcvttsd2si',2Ch
dw avx_cvttsd2si_instruction-instruction_handler
db 'vcvttss2si',2Ch
dw avx_cvttss2si_instruction-instruction_handler
db 'vcvtudq2pd',7Ah
dw avx_cvtudq2pd_instruction-instruction_handler
db 'vcvtudq2ps',7Ah
dw avx_cvtudq2ps_instruction-instruction_handler
db 'vcvtuqq2pd',7Ah
dw avx_cvtqq2pd_instruction-instruction_handler
db 'vcvtuqq2ps',7Ah
dw avx_cvtuqq2ps_instruction-instruction_handler
db 'vcvtusi2sd',7Bh
dw avx_cvtusi2sd_instruction-instruction_handler
db 'vcvtusi2ss',7Bh
dw avx_cvtusi2ss_instruction-instruction_handler
db 'vextractps',17h
dw avx_extract_d_instruction-instruction_handler
db 'vfpclasspd',66h
dw avx512_fpclasspd_instruction-instruction_handler
db 'vfpclassps',66h
dw avx512_fpclassps_instruction-instruction_handler
db 'vfpclasssd',67h
dw avx512_fpclasssd_instruction-instruction_handler
db 'vfpclassss',67h
dw avx512_fpclassss_instruction-instruction_handler
db 'vgatherdpd',92h
dw gather_pd_instruction-instruction_handler
db 'vgatherdps',92h
dw gather_ps_instruction-instruction_handler
db 'vgatherqpd',93h
dw gather_pd_instruction-instruction_handler
db 'vgatherqps',93h
dw gather_ps_instruction-instruction_handler
db 'vgetmantpd',26h
dw avx512_single_source_pd_instruction_sae_imm8-instruction_handler
db 'vgetmantps',26h
dw avx512_single_source_ps_instruction_sae_imm8-instruction_handler
db 'vgetmantsd',27h
dw avx512_sd_instruction_sae_imm8-instruction_handler
db 'vgetmantss',27h
dw avx512_ss_instruction_sae_imm8-instruction_handler
db 'vmaskmovpd',2Dh
dw avx_maskmov_instruction-instruction_handler
db 'vmaskmovps',2Ch
dw avx_maskmov_instruction-instruction_handler
db 'vpclmulqdq',-1
dw avx_pclmulqdq_instruction-instruction_handler
db 'vpcmpestri',61h
dw avx_single_source_128bit_instruction_3a_imm8_noevex-instruction_handler
db 'vpcmpestrm',60h
dw avx_single_source_128bit_instruction_3a_imm8_noevex-instruction_handler
db 'vpcmpistri',63h
dw avx_single_source_128bit_instruction_3a_imm8_noevex-instruction_handler
db 'vpcmpistrm',62h
dw avx_single_source_128bit_instruction_3a_imm8_noevex-instruction_handler
db 'vpcmpnequb',4
dw avx512_cmp_ub_instruction-instruction_handler
db 'vpcmpnequd',4
dw avx512_cmp_ud_instruction-instruction_handler
db 'vpcmpnequq',4
dw avx512_cmp_uq_instruction-instruction_handler
db 'vpcmpnequw',4
dw avx512_cmp_uw_instruction-instruction_handler
db 'vpcmpnleub',6
dw avx512_cmp_ub_instruction-instruction_handler
db 'vpcmpnleud',6
dw avx512_cmp_ud_instruction-instruction_handler
db 'vpcmpnleuq',6
dw avx512_cmp_uq_instruction-instruction_handler
db 'vpcmpnleuw',6
dw avx512_cmp_uw_instruction-instruction_handler
db 'vpcmpnltub',5
dw avx512_cmp_ub_instruction-instruction_handler
db 'vpcmpnltud',5
dw avx512_cmp_ud_instruction-instruction_handler
db 'vpcmpnltuq',5
dw avx512_cmp_uq_instruction-instruction_handler
db 'vpcmpnltuw',5
dw avx512_cmp_uw_instruction-instruction_handler
db 'vpcomnequb',5
dw xop_pcom_ub_instruction-instruction_handler
db 'vpcomnequd',5
dw xop_pcom_ud_instruction-instruction_handler
db 'vpcomnequq',5
dw xop_pcom_uq_instruction-instruction_handler
db 'vpcomnequw',5
dw xop_pcom_uw_instruction-instruction_handler
db 'vpcomtrueb',7
dw xop_pcom_b_instruction-instruction_handler
db 'vpcomtrued',7
dw xop_pcom_d_instruction-instruction_handler
db 'vpcomtrueq',7
dw xop_pcom_q_instruction-instruction_handler
db 'vpcomtruew',7
dw xop_pcom_w_instruction-instruction_handler
db 'vperm2f128',6
dw avx_perm2f128_instruction-instruction_handler
db 'vperm2i128',46h
dw avx_perm2f128_instruction-instruction_handler
db 'vpermil2pd',49h
dw vpermil2_instruction-instruction_handler
db 'vpermil2ps',48h
dw vpermil2_instruction-instruction_handler
db 'vpgatherdd',90h
dw gather_ps_instruction-instruction_handler
db 'vpgatherdq',90h
dw gather_pd_instruction-instruction_handler
db 'vpgatherqd',91h
dw gather_ps_instruction-instruction_handler
db 'vpgatherqq',91h
dw gather_pd_instruction-instruction_handler
db 'vpmacssdqh',8Fh
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmacssdql',87h
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmadcsswd',0A6h
dw xop_triple_source_128bit_instruction-instruction_handler
db 'vpmaddubsw',4
dw avx_bw_instruction_38-instruction_handler
db 'vpmaskmovd',8Ch
dw avx_maskmov_instruction-instruction_handler
db 'vpmaskmovq',8Ch
dw avx_maskmov_w1_instruction-instruction_handler
db 'vpternlogd',25h
dw avx_d_instruction_3a_imm8_evex-instruction_handler
db 'vpternlogq',25h
dw avx_q_instruction_3a_imm8_evex-instruction_handler
db 'vpunpckhbw',68h
dw avx_bw_instruction-instruction_handler
db 'vpunpckhdq',6Ah
dw avx_d_instruction-instruction_handler
db 'vpunpckhwd',69h
dw avx_bw_instruction-instruction_handler
db 'vpunpcklbw',60h
dw avx_bw_instruction-instruction_handler
db 'vpunpckldq',62h
dw avx_d_instruction-instruction_handler
db 'vpunpcklwd',61h
dw avx_bw_instruction-instruction_handler
db 'vrsqrt14pd',4Eh
dw avx512_single_source_pd_instruction-instruction_handler
db 'vrsqrt14ps',4Eh
dw avx512_single_source_ps_instruction-instruction_handler
db 'vrsqrt14sd',4Fh
dw avx512_sd_instruction-instruction_handler
db 'vrsqrt14ss',4Fh
dw avx512_ss_instruction-instruction_handler
db 'vrsqrt28pd',0CCh
dw avx512_exp2pd_instruction-instruction_handler
db 'vrsqrt28ps',0CCh
dw avx512_exp2ps_instruction-instruction_handler
db 'vrsqrt28sd',0CDh
dw avx512_sd_instruction_sae-instruction_handler
db 'vrsqrt28ss',0CDh
dw avx512_ss_instruction_sae-instruction_handler
db 'vshuff32x4',23h
dw avx512_shuf_d_instruction-instruction_handler
db 'vshuff64x2',23h
dw avx512_shuf_q_instruction-instruction_handler
db 'vshufi32x4',43h
dw avx512_shuf_d_instruction-instruction_handler
db 'vshufi64x2',43h
dw avx512_shuf_q_instruction-instruction_handler
db 'vzeroupper',77h
dw vzeroupper_instruction-instruction_handler
db 'xsaveopt64',110b
dw fxsave_instruction_64bit-instruction_handler
instructions_11:
db 'pclmulhqhdq',10001b
dw pclmulqdq_instruction-instruction_handler
db 'pclmullqhdq',10000b
dw pclmulqdq_instruction-instruction_handler
db 'prefetchnta',0
dw prefetch_instruction-instruction_handler
db 'prefetchwt1',2
dw amd_prefetch_instruction-instruction_handler
db 'sha256rnds2',0CBh
dw sse4_instruction_38_xmm0-instruction_handler
db 'vaesdeclast',0DFh
dw avx_128bit_instruction_38_noevex-instruction_handler
db 'vaesenclast',0DDh
dw avx_128bit_instruction_38_noevex-instruction_handler
db 'vcmpeq_ospd',10h
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpeq_osps',10h
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpeq_ossd',10h
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpeq_osss',10h
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpeq_uqpd',8
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpeq_uqps',8
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpeq_uqsd',8
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpeq_uqss',8
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpeq_uspd',18h
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpeq_usps',18h
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpeq_ussd',18h
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpeq_usss',18h
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpfalsepd',0Bh
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpfalseps',0Bh
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpfalsesd',0Bh
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpfalsess',0Bh
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpge_oqpd',1Dh
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpge_oqps',1Dh
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpge_oqsd',1Dh
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpge_oqss',1Dh
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpgt_oqpd',1Eh
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpgt_oqps',1Eh
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpgt_oqsd',1Eh
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpgt_oqss',1Eh
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmple_oqpd',12h
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmple_oqps',12h
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmple_oqsd',12h
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmple_oqss',12h
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmplt_oqpd',11h
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmplt_oqps',11h
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmplt_oqsd',11h
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmplt_oqss',11h
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpord_spd',17h
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpord_sps',17h
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpord_ssd',17h
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpord_sss',17h
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpunordpd',3
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpunordps',3
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpunordsd',3
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpunordss',3
dw avx_cmp_ss_instruction-instruction_handler
db 'vcompresspd',8Ah
dw avx_compress_q_instruction-instruction_handler
db 'vcompressps',8Ah
dw avx_compress_d_instruction-instruction_handler
db 'vcvttpd2udq',78h
dw avx_cvttpd2udq_instruction-instruction_handler
db 'vcvttpd2uqq',78h
dw avx_single_source_pd_instruction_sae_evex-instruction_handler
db 'vcvttps2udq',78h
dw avx_cvttps2udq_instruction-instruction_handler
db 'vcvttps2uqq',78h
dw avx_cvttps2qq_instruction-instruction_handler
db 'vcvttsd2usi',78h
dw avx_cvttsd2usi_instruction-instruction_handler
db 'vcvttss2usi',78h
dw avx_cvttss2usi_instruction-instruction_handler
db 'vfixupimmpd',54h
dw avx512_pd_instruction_sae_imm8-instruction_handler
db 'vfixupimmps',54h
dw avx512_ps_instruction_sae_imm8-instruction_handler
db 'vfixupimmsd',55h
dw avx512_sd_instruction_sae_imm8-instruction_handler
db 'vfixupimmss',55h
dw avx512_ss_instruction_sae_imm8-instruction_handler
db 'vfmadd132pd',98h
dw fma_instruction_pd-instruction_handler
db 'vfmadd132ps',98h
dw fma_instruction_ps-instruction_handler
db 'vfmadd132sd',99h
dw fma_instruction_sd-instruction_handler
db 'vfmadd132ss',99h
dw fma_instruction_ss-instruction_handler
db 'vfmadd213pd',0A8h
dw fma_instruction_pd-instruction_handler
db 'vfmadd213ps',0A8h
dw fma_instruction_ps-instruction_handler
db 'vfmadd213sd',0A9h
dw fma_instruction_sd-instruction_handler
db 'vfmadd213ss',0A9h
dw fma_instruction_ss-instruction_handler
db 'vfmadd231pd',0B8h
dw fma_instruction_pd-instruction_handler
db 'vfmadd231ps',0B8h
dw fma_instruction_ps-instruction_handler
db 'vfmadd231sd',0B9h
dw fma_instruction_sd-instruction_handler
db 'vfmadd231ss',0B9h
dw fma_instruction_ss-instruction_handler
db 'vfmaddsubpd',5Dh
dw fma4_instruction_p-instruction_handler
db 'vfmaddsubps',5Ch
dw fma4_instruction_p-instruction_handler
db 'vfmsub132pd',9Ah
dw fma_instruction_pd-instruction_handler
db 'vfmsub132ps',9Ah
dw fma_instruction_ps-instruction_handler
db 'vfmsub132sd',9Bh
dw fma_instruction_sd-instruction_handler
db 'vfmsub132ss',9Bh
dw fma_instruction_ss-instruction_handler
db 'vfmsub213pd',0AAh
dw fma_instruction_pd-instruction_handler
db 'vfmsub213ps',0AAh
dw fma_instruction_ps-instruction_handler
db 'vfmsub213sd',0ABh
dw fma_instruction_sd-instruction_handler
db 'vfmsub213ss',0ABh
dw fma_instruction_ss-instruction_handler
db 'vfmsub231pd',0BAh
dw fma_instruction_pd-instruction_handler
db 'vfmsub231ps',0BAh
dw fma_instruction_ps-instruction_handler
db 'vfmsub231sd',0BBh
dw fma_instruction_sd-instruction_handler
db 'vfmsub231ss',0BBh
dw fma_instruction_ss-instruction_handler
db 'vfmsubaddpd',5Fh
dw fma4_instruction_p-instruction_handler
db 'vfmsubaddps',5Eh
dw fma4_instruction_p-instruction_handler
db 'vinsertf128',18h
dw avx_insertf128_instruction-instruction_handler
db 'vinserti128',38h
dw avx_insertf128_instruction-instruction_handler
db 'vmaskmovdqu',0
dw avx_maskmovdqu_instruction-instruction_handler
db 'vpcomfalseb',6
dw xop_pcom_b_instruction-instruction_handler
db 'vpcomfalsed',6
dw xop_pcom_d_instruction-instruction_handler
db 'vpcomfalseq',6
dw xop_pcom_q_instruction-instruction_handler
db 'vpcomfalsew',6
dw xop_pcom_w_instruction-instruction_handler
db 'vpcompressd',8Bh
dw avx_compress_d_instruction-instruction_handler
db 'vpcompressq',8Bh
dw avx_compress_q_instruction-instruction_handler
db 'vpcomtrueub',7
dw xop_pcom_ub_instruction-instruction_handler
db 'vpcomtrueud',7
dw xop_pcom_ud_instruction-instruction_handler
db 'vpcomtrueuq',7
dw xop_pcom_uq_instruction-instruction_handler
db 'vpcomtrueuw',7
dw xop_pcom_uw_instruction-instruction_handler
db 'vpconflictd',0C4h
dw avx_single_source_d_instruction_38_evex-instruction_handler
db 'vpconflictq',0C4h
dw avx_single_source_q_instruction_38_evex-instruction_handler
db 'vphminposuw',41h
dw avx_single_source_instruction_38_noevex-instruction_handler
db 'vpmadd52huq',0B5h
dw avx_q_instruction_38_evex-instruction_handler
db 'vpmadd52luq',0B4h
dw avx_q_instruction_38_evex-instruction_handler
db 'vpscatterdd',0A0h
dw scatter_ps_instruction-instruction_handler
db 'vpscatterdq',0A0h
dw scatter_pd_instruction-instruction_handler
db 'vpscatterqd',0A1h
dw scatter_ps_instruction-instruction_handler
db 'vpscatterqq',0A1h
dw scatter_pd_instruction-instruction_handler
db 'vpunpckhqdq',6Dh
dw avx_q_instruction-instruction_handler
db 'vpunpcklqdq',6Ch
dw avx_q_instruction-instruction_handler
db 'vrndscalepd',9
dw avx512_single_source_pd_instruction_sae_imm8-instruction_handler
db 'vrndscaleps',8
dw avx512_single_source_ps_instruction_sae_imm8-instruction_handler
db 'vrndscalesd',0Bh
dw avx512_sd_instruction_sae_imm8-instruction_handler
db 'vrndscaless',0Ah
dw avx512_ss_instruction_sae_imm8-instruction_handler
db 'vscatterdpd',0A2h
dw scatter_pd_instruction-instruction_handler
db 'vscatterdps',0A2h
dw scatter_ps_instruction-instruction_handler
db 'vscatterqpd',0A3h
dw scatter_pd_instruction-instruction_handler
db 'vscatterqps',0A3h
dw scatter_ps_instruction-instruction_handler
instructions_12:
db 'pclmulhqhqdq',10001b
dw pclmulqdq_instruction-instruction_handler
db 'pclmulhqlqdq',1
dw pclmulqdq_instruction-instruction_handler
db 'pclmullqhqdq',10000b
dw pclmulqdq_instruction-instruction_handler
db 'pclmullqlqdq',0
dw pclmulqdq_instruction-instruction_handler
db 'vbroadcastsd',19h
dw avx_broadcastsd_instruction-instruction_handler
db 'vbroadcastss',18h
dw avx_broadcastss_instruction-instruction_handler
db 'vcmpneq_oqpd',0Ch
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpneq_oqps',0Ch
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpneq_oqsd',0Ch
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpneq_oqss',0Ch
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpneq_ospd',1Ch
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpneq_osps',1Ch
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpneq_ossd',1Ch
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpneq_osss',1Ch
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpneq_uspd',14h
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpneq_usps',14h
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpneq_ussd',14h
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpneq_usss',14h
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpnge_uqpd',19h
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpnge_uqps',19h
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpnge_uqsd',19h
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpnge_uqss',19h
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpngt_uqpd',1Ah
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpngt_uqps',1Ah
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpngt_uqsd',1Ah
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpngt_uqss',1Ah
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpnle_uqpd',16h
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpnle_uqps',16h
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpnle_uqsd',16h
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpnle_uqss',16h
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpnlt_uqpd',15h
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpnlt_uqps',15h
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpnlt_uqsd',15h
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpnlt_uqss',15h
dw avx_cmp_ss_instruction-instruction_handler
db 'vextractf128',19h
dw avx_extractf128_instruction-instruction_handler
db 'vextracti128',39h
dw avx_extractf128_instruction-instruction_handler
db 'vfnmadd132pd',9Ch
dw fma_instruction_pd-instruction_handler
db 'vfnmadd132ps',9Ch
dw fma_instruction_ps-instruction_handler
db 'vfnmadd132sd',9Dh
dw fma_instruction_sd-instruction_handler
db 'vfnmadd132ss',9Dh
dw fma_instruction_ss-instruction_handler
db 'vfnmadd213pd',0ACh
dw fma_instruction_pd-instruction_handler
db 'vfnmadd213ps',0ACh
dw fma_instruction_ps-instruction_handler
db 'vfnmadd213sd',0ADh
dw fma_instruction_sd-instruction_handler
db 'vfnmadd213ss',0ADh
dw fma_instruction_ss-instruction_handler
db 'vfnmadd231pd',0BCh
dw fma_instruction_pd-instruction_handler
db 'vfnmadd231ps',0BCh
dw fma_instruction_ps-instruction_handler
db 'vfnmadd231sd',0BDh
dw fma_instruction_sd-instruction_handler
db 'vfnmadd231ss',0BDh
dw fma_instruction_ss-instruction_handler
db 'vfnmsub132pd',9Eh
dw fma_instruction_pd-instruction_handler
db 'vfnmsub132ps',9Eh
dw fma_instruction_ps-instruction_handler
db 'vfnmsub132sd',9Fh
dw fma_instruction_sd-instruction_handler
db 'vfnmsub132ss',9Fh
dw fma_instruction_ss-instruction_handler
db 'vfnmsub213pd',0AEh
dw fma_instruction_pd-instruction_handler
db 'vfnmsub213ps',0AEh
dw fma_instruction_ps-instruction_handler
db 'vfnmsub213sd',0AFh
dw fma_instruction_sd-instruction_handler
db 'vfnmsub213ss',0AFh
dw fma_instruction_ss-instruction_handler
db 'vfnmsub231pd',0BEh
dw fma_instruction_pd-instruction_handler
db 'vfnmsub231ps',0BEh
dw fma_instruction_ps-instruction_handler
db 'vfnmsub231sd',0BFh
dw fma_instruction_sd-instruction_handler
db 'vfnmsub231ss',0BFh
dw fma_instruction_ss-instruction_handler
db 'vinsertf32x4',18h
dw avx512_insert_32x4_instruction-instruction_handler
db 'vinsertf32x8',1Ah
dw avx512_insert_32x8_instruction-instruction_handler
db 'vinsertf64x2',18h
dw avx512_insert_64x2_instruction-instruction_handler
db 'vinsertf64x4',1Ah
dw avx512_insert_64x4_instruction-instruction_handler
db 'vinserti32x4',38h
dw avx512_insert_32x4_instruction-instruction_handler
db 'vinserti32x8',3Ah
dw avx512_insert_32x8_instruction-instruction_handler
db 'vinserti64x2',38h
dw avx512_insert_64x2_instruction-instruction_handler
db 'vinserti64x4',3Ah
dw avx512_insert_64x4_instruction-instruction_handler
db 'vpbroadcastb',78h
dw avx_pbroadcastb_instruction-instruction_handler
db 'vpbroadcastd',58h
dw avx_pbroadcastd_instruction-instruction_handler
db 'vpbroadcastq',59h
dw avx_pbroadcastq_instruction-instruction_handler
db 'vpbroadcastw',79h
dw avx_pbroadcastw_instruction-instruction_handler
db 'vpclmulhqhdq',10001b
dw avx_pclmulqdq_instruction-instruction_handler
db 'vpclmullqhdq',10000b
dw avx_pclmulqdq_instruction-instruction_handler
db 'vpcomfalseub',6
dw xop_pcom_ub_instruction-instruction_handler
db 'vpcomfalseud',6
dw xop_pcom_ud_instruction-instruction_handler
db 'vpcomfalseuq',6
dw xop_pcom_uq_instruction-instruction_handler
db 'vpcomfalseuw',6
dw xop_pcom_uw_instruction-instruction_handler
db 'vpermilmo2pd',10b
dw vpermil_2pd_instruction-instruction_handler
db 'vpermilmo2ps',10b
dw vpermil_2ps_instruction-instruction_handler
db 'vpermilmz2pd',11b
dw vpermil_2pd_instruction-instruction_handler
db 'vpermilmz2ps',11b
dw vpermil_2ps_instruction-instruction_handler
db 'vpermiltd2pd',0
dw vpermil_2pd_instruction-instruction_handler
db 'vpermiltd2ps',0
dw vpermil_2ps_instruction-instruction_handler
instructions_13:
db 'vcmptrue_uspd',1Fh
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmptrue_usps',1Fh
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmptrue_ussd',1Fh
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmptrue_usss',1Fh
dw avx_cmp_ss_instruction-instruction_handler
db 'vcmpunord_spd',13h
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpunord_sps',13h
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpunord_ssd',13h
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpunord_sss',13h
dw avx_cmp_ss_instruction-instruction_handler
db 'vextractf32x4',19h
dw avx512_extract_32x4_instruction-instruction_handler
db 'vextractf32x8',1Bh
dw avx512_extract_32x8_instruction-instruction_handler
db 'vextractf64x2',19h
dw avx512_extract_64x2_instruction-instruction_handler
db 'vextractf64x4',1Bh
dw avx512_extract_64x4_instruction-instruction_handler
db 'vextracti32x4',39h
dw avx512_extract_32x4_instruction-instruction_handler
db 'vextracti32x8',3Bh
dw avx512_extract_32x8_instruction-instruction_handler
db 'vextracti64x2',39h
dw avx512_extract_64x2_instruction-instruction_handler
db 'vextracti64x4',3Bh
dw avx512_extract_64x4_instruction-instruction_handler
db 'vgatherpf0dpd',1
dw gatherpf_dpd_instruction-instruction_handler
db 'vgatherpf0dps',1
dw gatherpf_dps_instruction-instruction_handler
db 'vgatherpf0qpd',1
dw gatherpf_qpd_instruction-instruction_handler
db 'vgatherpf0qps',1
dw gatherpf_qps_instruction-instruction_handler
db 'vgatherpf1dpd',2
dw gatherpf_dpd_instruction-instruction_handler
db 'vgatherpf1dps',2
dw gatherpf_dps_instruction-instruction_handler
db 'vgatherpf1qpd',2
dw gatherpf_qpd_instruction-instruction_handler
db 'vgatherpf1qps',2
dw gatherpf_qps_instruction-instruction_handler
db 'vpclmulhqlqdq',1
dw avx_pclmulqdq_instruction-instruction_handler
db 'vpclmullqlqdq',0
dw avx_pclmulqdq_instruction-instruction_handler
instructions_14:
db 'vbroadcastf128',1Ah
dw avx_broadcast_128_instruction_noevex-instruction_handler
db 'vbroadcasti128',5Ah
dw avx_broadcast_128_instruction_noevex-instruction_handler
db 'vcmpfalse_ospd',1Bh
dw avx_cmp_pd_instruction-instruction_handler
db 'vcmpfalse_osps',1Bh
dw avx_cmp_ps_instruction-instruction_handler
db 'vcmpfalse_ossd',1Bh
dw avx_cmp_sd_instruction-instruction_handler
db 'vcmpfalse_osss',1Bh
dw avx_cmp_ss_instruction-instruction_handler
db 'vfmaddsub132pd',96h
dw fma_instruction_pd-instruction_handler
db 'vfmaddsub132ps',96h
dw fma_instruction_ps-instruction_handler
db 'vfmaddsub213pd',0A6h
dw fma_instruction_pd-instruction_handler
db 'vfmaddsub213ps',0A6h
dw fma_instruction_ps-instruction_handler
db 'vfmaddsub231pd',0B6h
dw fma_instruction_pd-instruction_handler
db 'vfmaddsub231ps',0B6h
dw fma_instruction_ps-instruction_handler
db 'vfmsubadd132pd',97h
dw fma_instruction_pd-instruction_handler
db 'vfmsubadd132ps',97h
dw fma_instruction_ps-instruction_handler
db 'vfmsubadd213pd',0A7h
dw fma_instruction_pd-instruction_handler
db 'vfmsubadd213ps',0A7h
dw fma_instruction_ps-instruction_handler
db 'vfmsubadd231pd',0B7h
dw fma_instruction_pd-instruction_handler
db 'vfmsubadd231ps',0B7h
dw fma_instruction_ps-instruction_handler
db 'vpmultishiftqb',83h
dw avx_q_instruction_38_evex-instruction_handler
db 'vscatterpf0dpd',5
dw gatherpf_dpd_instruction-instruction_handler
db 'vscatterpf0dps',5
dw gatherpf_dps_instruction-instruction_handler
db 'vscatterpf0qpd',5
dw gatherpf_qpd_instruction-instruction_handler
db 'vscatterpf0qps',5
dw gatherpf_qps_instruction-instruction_handler
db 'vscatterpf1dpd',6
dw gatherpf_dpd_instruction-instruction_handler
db 'vscatterpf1dps',6
dw gatherpf_dps_instruction-instruction_handler
db 'vscatterpf1qpd',6
dw gatherpf_qpd_instruction-instruction_handler
db 'vscatterpf1qps',6
dw gatherpf_qps_instruction-instruction_handler
instructions_15:
db 'aeskeygenassist',0DFh
dw sse4_instruction_66_3a_imm8-instruction_handler
db 'vbroadcastf32x2',19h
dw avx512_broadcast_32x2_instruction-instruction_handler
db 'vbroadcastf32x4',1Ah
dw avx512_broadcast_32x4_instruction-instruction_handler
db 'vbroadcastf32x8',1Bh
dw avx512_broadcast_32x8_instruction-instruction_handler
db 'vbroadcastf64x2',1Ah
dw avx512_broadcast_64x2_instruction-instruction_handler
db 'vbroadcastf64x4',1Bh
dw avx512_broadcast_64x4_instruction-instruction_handler
db 'vbroadcasti32x2',59h
dw avx512_broadcast_32x2_instruction-instruction_handler
db 'vbroadcasti32x4',5Ah
dw avx512_broadcast_32x4_instruction-instruction_handler
db 'vbroadcasti32x8',5Bh
dw avx512_broadcast_32x8_instruction-instruction_handler
db 'vbroadcasti64x2',5Ah
dw avx512_broadcast_64x2_instruction-instruction_handler
db 'vbroadcasti64x4',5Bh
dw avx512_broadcast_64x4_instruction-instruction_handler
db 'vpbroadcastmb2q',2Ah
dw avx512_pmov_m2_instruction_w1-instruction_handler
db 'vpbroadcastmw2d',3Ah
dw avx512_pmov_m2_instruction-instruction_handler
instructions_16:
db 'vaeskeygenassist',0DFh
dw avx_single_source_128bit_instruction_3a_imm8_noevex-instruction_handler
instructions_end:
 
data_directives:
dw data_directives_2-data_directives,(data_directives_3-data_directives_2)/(2+3)
dw data_directives_3-data_directives,(data_directives_4-data_directives_3)/(3+3)
dw data_directives_4-data_directives,(data_directives_end-data_directives_4)/(4+3)
 
data_directives_2:
db 'db',1
dw data_bytes-instruction_handler
db 'dd',4
dw data_dwords-instruction_handler
db 'df',6
dw data_pwords-instruction_handler
db 'dp',6
dw data_pwords-instruction_handler
db 'dq',8
dw data_qwords-instruction_handler
db 'dt',10
dw data_twords-instruction_handler
db 'du',2
dw data_unicode-instruction_handler
db 'dw',2
dw data_words-instruction_handler
db 'rb',1
dw reserve_bytes-instruction_handler
db 'rd',4
dw reserve_dwords-instruction_handler
db 'rf',6
dw reserve_pwords-instruction_handler
db 'rp',6
dw reserve_pwords-instruction_handler
db 'rq',8
dw reserve_qwords-instruction_handler
db 'rt',10
dw reserve_twords-instruction_handler
db 'rw',2
dw reserve_words-instruction_handler
data_directives_3:
data_directives_4:
db 'file',1
dw data_file-instruction_handler
data_directives_end:
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/variable.inc
0,0 → 1,155
 
; flat assembler core variables
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
; Variables which have to be set up by interface:
 
memory_start dd ?
memory_end dd ?
 
additional_memory dd ?
additional_memory_end dd ?
 
stack_limit dd ?
 
initial_definitions dd ?
input_file dd ?
output_file dd ?
symbols_file dd ?
 
passes_limit dw ?
 
; Internal core variables:
 
current_pass dw ?
 
include_paths dd ?
free_additional_memory dd ?
source_start dd ?
code_start dd ?
code_size dd ?
real_code_size dd ?
written_size dd ?
headers_size dd ?
 
current_line dd ?
macro_line dd ?
macro_block dd ?
macro_block_line dd ?
macro_block_line_number dd ?
macro_symbols dd ?
struc_name dd ?
struc_label dd ?
instant_macro_start dd ?
parameters_end dd ?
default_argument_value dd ?
locals_counter rb 8
current_locals_prefix dd ?
anonymous_reverse dd ?
anonymous_forward dd ?
labels_list dd ?
label_hash dd ?
label_leaf dd ?
hash_tree dd ?
addressing_space dd ?
undefined_data_start dd ?
undefined_data_end dd ?
counter dd ?
counter_limit dd ?
error_info dd ?
error_line dd ?
error dd ?
tagged_blocks dd ?
structures_buffer dd ?
number_start dd ?
current_offset dd ?
value dq ?
fp_value rd 8
adjustment dq ?
symbol_identifier dd ?
address_symbol dd ?
address_high dd ?
uncompressed_displacement dd ?
format_flags dd ?
resolver_flags dd ?
symbols_stream dd ?
number_of_relocations dd ?
number_of_sections dd ?
stub_size dd ?
stub_file dd ?
current_section dd ?
machine dw ?
subsystem dw ?
subsystem_version dd ?
image_base dd ?
image_base_high dd ?
resource_data dd ?
resource_size dd ?
actual_fixups_size dd ?
reserved_fixups dd ?
reserved_fixups_size dd ?
last_fixup_base dd ?
last_fixup_header dd ?
parenthesis_stack dd ?
blocks_stack dd ?
parsed_lines dd ?
logical_value_parentheses dd ?
file_extension dd ?
 
operand_size db ?
operand_flags db ?
operand_prefix db ?
rex_prefix db ?
opcode_prefix db ?
vex_required db ?
vex_register db ?
immediate_size db ?
mask_register db ?
broadcast_size db ?
rounding_mode db ?
 
base_code db ?
extended_code db ?
supplemental_code db ?
postbyte_register db ?
segment_register db ?
xop_opcode_map db ?
 
mmx_size db ?
jump_type db ?
push_size db ?
value_size db ?
address_size db ?
label_size db ?
size_declared db ?
address_size_declared db ?
displacement_compression db ?
 
value_undefined db ?
value_constant db ?
value_type db ?
value_sign db ?
fp_sign db ?
fp_format db ?
address_sign db ?
address_register db ?
compare_type db ?
logical_value_wrapping db ?
next_pass_needed db ?
output_format db ?
code_type db ?
adjustment_sign db ?
evex_mode db ?
 
macro_status db ?
skip_default_argument_value db ?
prefix_flags db ?
formatter_symbols_allowed db ?
decorator_symbols_allowed db ?
free_address_range db ?
 
 
characters rb 100h
converted rb 100h
message rb 200h
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/version.inc
0,0 → 1,39
 
; flat assembler version 1.71
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
;
; This programs is free for commercial and non-commercial use as long as
; the following conditions are adhered to.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are
; met:
;
; 1. Redistributions of source code must retain the above copyright notice,
; this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
; The licence and distribution terms for any publically available
; version or derivative of this code cannot be changed. i.e. this code
; cannot simply be copied and put under another distribution licence
; (including the GNU Public Licence).
 
VERSION_STRING equ "1.71.54"
 
VERSION_MAJOR = 1
VERSION_MINOR = 71
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/x86_64.inc
0,0 → 1,7076
 
; flat assembler core
; Copyright (c) 1999-2016, Tomasz Grysztar.
; All rights reserved.
 
simple_instruction_except64:
cmp [code_type],64
je illegal_instruction
simple_instruction:
stos byte [edi]
jmp instruction_assembled
simple_instruction_only64:
cmp [code_type],64
jne illegal_instruction
jmp simple_instruction
simple_instruction_16bit_except64:
cmp [code_type],64
je illegal_instruction
simple_instruction_16bit:
cmp [code_type],16
jne size_prefix
stos byte [edi]
jmp instruction_assembled
size_prefix:
mov ah,al
mov al,66h
stos word [edi]
jmp instruction_assembled
simple_instruction_32bit_except64:
cmp [code_type],64
je illegal_instruction
simple_instruction_32bit:
cmp [code_type],16
je size_prefix
stos byte [edi]
jmp instruction_assembled
iret_instruction:
cmp [code_type],64
jne simple_instruction
simple_instruction_64bit:
cmp [code_type],64
jne illegal_instruction
mov ah,al
mov al,48h
stos word [edi]
jmp instruction_assembled
simple_extended_instruction_64bit:
cmp [code_type],64
jne illegal_instruction
mov byte [edi],48h
inc edi
simple_extended_instruction:
mov ah,al
mov al,0Fh
stos word [edi]
jmp instruction_assembled
prefix_instruction:
stos byte [edi]
or [prefix_flags],1
jmp continue_line
segment_prefix:
mov ah,al
shr ah,4
cmp ah,3
jne illegal_instruction
and al,1111b
mov [segment_register],al
call store_segment_prefix
or [prefix_flags],1
jmp continue_line
bnd_prefix_instruction:
stos byte [edi]
or [prefix_flags],1 + 10h
jmp continue_line
int_instruction:
lods byte [esi]
call get_size_operator
cmp ah,1
ja invalid_operand_size
cmp al,'('
jne invalid_operand
call get_byte_value
test eax,eax
jns int_imm_ok
call recoverable_overflow
int_imm_ok:
mov ah,al
mov al,0CDh
stos word [edi]
jmp instruction_assembled
aa_instruction:
cmp [code_type],64
je illegal_instruction
push eax
mov bl,10
cmp byte [esi],'('
jne aa_store
inc esi
xor al,al
xchg al,[operand_size]
cmp al,1
ja invalid_operand_size
call get_byte_value
mov bl,al
aa_store:
cmp [operand_size],0
jne invalid_operand
pop eax
mov ah,bl
stos word [edi]
jmp instruction_assembled
 
basic_instruction:
mov [base_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
je basic_reg
cmp al,'['
jne invalid_operand
basic_mem:
call get_address
push edx ebx ecx
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'('
je basic_mem_imm
cmp al,10h
jne invalid_operand
basic_mem_reg:
lods byte [esi]
call convert_register
mov [postbyte_register],al
pop ecx ebx edx
mov al,ah
cmp al,1
je instruction_ready
call operand_autodetect
inc [base_code]
instruction_ready:
call store_instruction
jmp instruction_assembled
basic_mem_imm:
mov al,[operand_size]
cmp al,1
jb basic_mem_imm_nosize
je basic_mem_imm_8bit
cmp al,2
je basic_mem_imm_16bit
cmp al,4
je basic_mem_imm_32bit
cmp al,8
jne invalid_operand_size
basic_mem_imm_64bit:
cmp [size_declared],0
jne long_immediate_not_encodable
call operand_64bit
call get_simm32
cmp [value_type],4
jae long_immediate_not_encodable
jmp basic_mem_imm_32bit_ok
basic_mem_imm_nosize:
call recoverable_unknown_size
basic_mem_imm_8bit:
call get_byte_value
mov byte [value],al
mov al,[base_code]
shr al,3
mov [postbyte_register],al
pop ecx ebx edx
mov [base_code],80h
call store_instruction_with_imm8
jmp instruction_assembled
basic_mem_imm_16bit:
call operand_16bit
call get_word_value
mov word [value],ax
mov al,[base_code]
shr al,3
mov [postbyte_register],al
pop ecx ebx edx
cmp [value_type],0
jne basic_mem_imm_16bit_store
cmp [size_declared],0
jne basic_mem_imm_16bit_store
cmp word [value],80h
jb basic_mem_simm_8bit
cmp word [value],-80h
jae basic_mem_simm_8bit
basic_mem_imm_16bit_store:
mov [base_code],81h
call store_instruction_with_imm16
jmp instruction_assembled
basic_mem_simm_8bit:
mov [base_code],83h
call store_instruction_with_imm8
jmp instruction_assembled
basic_mem_imm_32bit:
call operand_32bit
call get_dword_value
basic_mem_imm_32bit_ok:
mov dword [value],eax
mov al,[base_code]
shr al,3
mov [postbyte_register],al
pop ecx ebx edx
cmp [value_type],0
jne basic_mem_imm_32bit_store
cmp [size_declared],0
jne basic_mem_imm_32bit_store
cmp dword [value],80h
jb basic_mem_simm_8bit
cmp dword [value],-80h
jae basic_mem_simm_8bit
basic_mem_imm_32bit_store:
mov [base_code],81h
call store_instruction_with_imm32
jmp instruction_assembled
get_simm32:
call get_qword_value
mov ecx,edx
cdq
cmp ecx,edx
jne value_out_of_range
cmp [value_type],4
jne get_simm32_ok
mov [value_type],2
get_simm32_ok:
ret
basic_reg:
lods byte [esi]
call convert_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je basic_reg_reg
cmp al,'('
je basic_reg_imm
cmp al,'['
jne invalid_operand
basic_reg_mem:
call get_address
mov al,[operand_size]
cmp al,1
je basic_reg_mem_8bit
call operand_autodetect
add [base_code],3
jmp instruction_ready
basic_reg_mem_8bit:
add [base_code],2
jmp instruction_ready
basic_reg_reg:
lods byte [esi]
call convert_register
mov bl,[postbyte_register]
mov [postbyte_register],al
mov al,ah
cmp al,1
je nomem_instruction_ready
call operand_autodetect
inc [base_code]
nomem_instruction_ready:
call store_nomem_instruction
jmp instruction_assembled
basic_reg_imm:
mov al,[operand_size]
cmp al,1
je basic_reg_imm_8bit
cmp al,2
je basic_reg_imm_16bit
cmp al,4
je basic_reg_imm_32bit
cmp al,8
jne invalid_operand_size
basic_reg_imm_64bit:
cmp [size_declared],0
jne long_immediate_not_encodable
call operand_64bit
call get_simm32
cmp [value_type],4
jae long_immediate_not_encodable
jmp basic_reg_imm_32bit_ok
basic_reg_imm_8bit:
call get_byte_value
mov dl,al
mov bl,[base_code]
shr bl,3
xchg bl,[postbyte_register]
or bl,bl
jz basic_al_imm
mov [base_code],80h
call store_nomem_instruction
mov al,dl
stos byte [edi]
jmp instruction_assembled
basic_al_imm:
mov al,[base_code]
add al,4
stos byte [edi]
mov al,dl
stos byte [edi]
jmp instruction_assembled
basic_reg_imm_16bit:
call operand_16bit
call get_word_value
mov dx,ax
mov bl,[base_code]
shr bl,3
xchg bl,[postbyte_register]
cmp [value_type],0
jne basic_reg_imm_16bit_store
cmp [size_declared],0
jne basic_reg_imm_16bit_store
cmp dx,80h
jb basic_reg_simm_8bit
cmp dx,-80h
jae basic_reg_simm_8bit
basic_reg_imm_16bit_store:
or bl,bl
jz basic_ax_imm
mov [base_code],81h
call store_nomem_instruction
basic_store_imm_16bit:
mov ax,dx
call mark_relocation
stos word [edi]
jmp instruction_assembled
basic_reg_simm_8bit:
mov [base_code],83h
call store_nomem_instruction
mov al,dl
stos byte [edi]
jmp instruction_assembled
basic_ax_imm:
add [base_code],5
call store_classic_instruction_code
jmp basic_store_imm_16bit
basic_reg_imm_32bit:
call operand_32bit
call get_dword_value
basic_reg_imm_32bit_ok:
mov edx,eax
mov bl,[base_code]
shr bl,3
xchg bl,[postbyte_register]
cmp [value_type],0
jne basic_reg_imm_32bit_store
cmp [size_declared],0
jne basic_reg_imm_32bit_store
cmp edx,80h
jb basic_reg_simm_8bit
cmp edx,-80h
jae basic_reg_simm_8bit
basic_reg_imm_32bit_store:
or bl,bl
jz basic_eax_imm
mov [base_code],81h
call store_nomem_instruction
basic_store_imm_32bit:
mov eax,edx
call mark_relocation
stos dword [edi]
jmp instruction_assembled
basic_eax_imm:
add [base_code],5
call store_classic_instruction_code
jmp basic_store_imm_32bit
recoverable_unknown_size:
cmp [error_line],0
jne ignore_unknown_size
push [current_line]
pop [error_line]
mov [error],operand_size_not_specified
ignore_unknown_size:
ret
single_operand_instruction:
mov [base_code],0F6h
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,10h
je single_reg
cmp al,'['
jne invalid_operand
single_mem:
call get_address
mov al,[operand_size]
cmp al,1
je single_mem_8bit
jb single_mem_nosize
call operand_autodetect
inc [base_code]
jmp instruction_ready
single_mem_nosize:
call recoverable_unknown_size
single_mem_8bit:
jmp instruction_ready
single_reg:
lods byte [esi]
call convert_register
mov bl,al
mov al,ah
cmp al,1
je single_reg_8bit
call operand_autodetect
inc [base_code]
single_reg_8bit:
jmp nomem_instruction_ready
mov_instruction:
mov [base_code],88h
lods byte [esi]
call get_size_operator
cmp al,10h
je mov_reg
cmp al,14h
je mov_creg
cmp al,'['
jne invalid_operand
mov_mem:
call get_address
push edx ebx ecx
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'('
je mov_mem_imm
cmp al,10h
jne invalid_operand
mov_mem_reg:
lods byte [esi]
cmp al,30h
jb mov_mem_general_reg
cmp al,40h
jb mov_mem_sreg
mov_mem_general_reg:
call convert_register
mov [postbyte_register],al
pop ecx ebx edx
cmp ah,1
je mov_mem_reg_8bit
mov al,ah
call operand_autodetect
mov al,[postbyte_register]
or al,bl
or al,bh
jz mov_mem_ax
inc [base_code]
jmp instruction_ready
mov_mem_reg_8bit:
or al,bl
or al,bh
jnz instruction_ready
mov_mem_al:
test ch,22h
jnz mov_mem_address16_al
test ch,44h
jnz mov_mem_address32_al
test ch,88h
jnz mov_mem_address64_al
or ch,ch
jnz invalid_address_size
cmp [code_type],64
je mov_mem_address64_al
cmp [code_type],32
je mov_mem_address32_al
cmp edx,10000h
jb mov_mem_address16_al
mov_mem_address32_al:
call store_segment_prefix_if_necessary
call address_32bit_prefix
mov [base_code],0A2h
store_mov_address32:
call store_classic_instruction_code
call store_address_32bit_value
jmp instruction_assembled
mov_mem_address16_al:
call store_segment_prefix_if_necessary
call address_16bit_prefix
mov [base_code],0A2h
store_mov_address16:
cmp [code_type],64
je invalid_address
call store_classic_instruction_code
mov eax,edx
stos word [edi]
cmp edx,10000h
jge value_out_of_range
jmp instruction_assembled
mov_mem_address64_al:
call store_segment_prefix_if_necessary
mov [base_code],0A2h
store_mov_address64:
call store_classic_instruction_code
call store_address_64bit_value
jmp instruction_assembled
mov_mem_ax:
test ch,22h
jnz mov_mem_address16_ax
test ch,44h
jnz mov_mem_address32_ax
test ch,88h
jnz mov_mem_address64_ax
or ch,ch
jnz invalid_address_size
cmp [code_type],64
je mov_mem_address64_ax
cmp [code_type],32
je mov_mem_address32_ax
cmp edx,10000h
jb mov_mem_address16_ax
mov_mem_address32_ax:
call store_segment_prefix_if_necessary
call address_32bit_prefix
mov [base_code],0A3h
jmp store_mov_address32
mov_mem_address16_ax:
call store_segment_prefix_if_necessary
call address_16bit_prefix
mov [base_code],0A3h
jmp store_mov_address16
mov_mem_address64_ax:
call store_segment_prefix_if_necessary
mov [base_code],0A3h
jmp store_mov_address64
mov_mem_sreg:
sub al,31h
mov [postbyte_register],al
pop ecx ebx edx
mov ah,[operand_size]
or ah,ah
jz mov_mem_sreg_store
cmp ah,2
jne invalid_operand_size
mov_mem_sreg_store:
mov [base_code],8Ch
jmp instruction_ready
mov_mem_imm:
mov al,[operand_size]
cmp al,1
jb mov_mem_imm_nosize
je mov_mem_imm_8bit
cmp al,2
je mov_mem_imm_16bit
cmp al,4
je mov_mem_imm_32bit
cmp al,8
jne invalid_operand_size
mov_mem_imm_64bit:
cmp [size_declared],0
jne long_immediate_not_encodable
call operand_64bit
call get_simm32
cmp [value_type],4
jae long_immediate_not_encodable
jmp mov_mem_imm_32bit_store
mov_mem_imm_nosize:
call recoverable_unknown_size
mov_mem_imm_8bit:
call get_byte_value
mov byte [value],al
mov [postbyte_register],0
mov [base_code],0C6h
pop ecx ebx edx
call store_instruction_with_imm8
jmp instruction_assembled
mov_mem_imm_16bit:
call operand_16bit
call get_word_value
mov word [value],ax
mov [postbyte_register],0
mov [base_code],0C7h
pop ecx ebx edx
call store_instruction_with_imm16
jmp instruction_assembled
mov_mem_imm_32bit:
call operand_32bit
call get_dword_value
mov_mem_imm_32bit_store:
mov dword [value],eax
mov [postbyte_register],0
mov [base_code],0C7h
pop ecx ebx edx
call store_instruction_with_imm32
jmp instruction_assembled
mov_reg:
lods byte [esi]
mov ah,al
sub ah,10h
and ah,al
test ah,0F0h
jnz mov_sreg
call convert_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
je mov_reg_mem
cmp al,'('
je mov_reg_imm
cmp al,14h
je mov_reg_creg
cmp al,10h
jne invalid_operand
mov_reg_reg:
lods byte [esi]
mov ah,al
sub ah,10h
and ah,al
test ah,0F0h
jnz mov_reg_sreg
call convert_register
mov bl,[postbyte_register]
mov [postbyte_register],al
mov al,ah
cmp al,1
je mov_reg_reg_8bit
call operand_autodetect
inc [base_code]
mov_reg_reg_8bit:
jmp nomem_instruction_ready
mov_reg_sreg:
mov bl,[postbyte_register]
mov ah,al
and al,1111b
mov [postbyte_register],al
shr ah,4
cmp ah,3
jne invalid_operand
dec [postbyte_register]
cmp [operand_size],8
je mov_reg_sreg64
cmp [operand_size],4
je mov_reg_sreg32
cmp [operand_size],2
jne invalid_operand_size
call operand_16bit
jmp mov_reg_sreg_store
mov_reg_sreg64:
call operand_64bit
jmp mov_reg_sreg_store
mov_reg_sreg32:
call operand_32bit
mov_reg_sreg_store:
mov [base_code],8Ch
jmp nomem_instruction_ready
mov_reg_creg:
lods byte [esi]
mov bl,al
shr al,4
cmp al,4
ja invalid_operand
add al,20h
mov [extended_code],al
and bl,1111b
xchg bl,[postbyte_register]
mov [base_code],0Fh
cmp [code_type],64
je mov_reg_creg_64bit
cmp [operand_size],4
jne invalid_operand_size
cmp [postbyte_register],8
jb mov_reg_creg_store
cmp [extended_code],20h
jne mov_reg_creg_store
mov al,0F0h
stos byte [edi]
mov [postbyte_register],0
mov_reg_creg_store:
jmp nomem_instruction_ready
mov_reg_creg_64bit:
cmp [operand_size],8
jne invalid_operand_size
jmp nomem_instruction_ready
mov_reg_mem:
call get_address
mov al,[operand_size]
cmp al,1
je mov_reg_mem_8bit
call operand_autodetect
mov al,[postbyte_register]
or al,bl
or al,bh
jz mov_ax_mem
add [base_code],3
jmp instruction_ready
mov_reg_mem_8bit:
mov al,[postbyte_register]
or al,bl
or al,bh
jz mov_al_mem
add [base_code],2
jmp instruction_ready
mov_al_mem:
test ch,22h
jnz mov_al_mem_address16
test ch,44h
jnz mov_al_mem_address32
test ch,88h
jnz mov_al_mem_address64
or ch,ch
jnz invalid_address_size
cmp [code_type],64
je mov_al_mem_address64
cmp [code_type],32
je mov_al_mem_address32
cmp edx,10000h
jb mov_al_mem_address16
mov_al_mem_address32:
call store_segment_prefix_if_necessary
call address_32bit_prefix
mov [base_code],0A0h
jmp store_mov_address32
mov_al_mem_address16:
call store_segment_prefix_if_necessary
call address_16bit_prefix
mov [base_code],0A0h
jmp store_mov_address16
mov_al_mem_address64:
call store_segment_prefix_if_necessary
mov [base_code],0A0h
jmp store_mov_address64
mov_ax_mem:
test ch,22h
jnz mov_ax_mem_address16
test ch,44h
jnz mov_ax_mem_address32
test ch,88h
jnz mov_ax_mem_address64
or ch,ch
jnz invalid_address_size
cmp [code_type],64
je mov_ax_mem_address64
cmp [code_type],32
je mov_ax_mem_address32
cmp edx,10000h
jb mov_ax_mem_address16
mov_ax_mem_address32:
call store_segment_prefix_if_necessary
call address_32bit_prefix
mov [base_code],0A1h
jmp store_mov_address32
mov_ax_mem_address16:
call store_segment_prefix_if_necessary
call address_16bit_prefix
mov [base_code],0A1h
jmp store_mov_address16
mov_ax_mem_address64:
call store_segment_prefix_if_necessary
mov [base_code],0A1h
jmp store_mov_address64
mov_reg_imm:
mov al,[operand_size]
cmp al,1
je mov_reg_imm_8bit
cmp al,2
je mov_reg_imm_16bit
cmp al,4
je mov_reg_imm_32bit
cmp al,8
jne invalid_operand_size
mov_reg_imm_64bit:
call operand_64bit
call get_qword_value
mov ecx,edx
cmp [size_declared],0
jne mov_reg_imm_64bit_store
cmp [value_type],4
jae mov_reg_imm_64bit_store
cdq
cmp ecx,edx
je mov_reg_64bit_imm_32bit
mov_reg_imm_64bit_store:
push eax ecx
mov al,0B8h
call store_mov_reg_imm_code
pop edx eax
call mark_relocation
stos dword [edi]
mov eax,edx
stos dword [edi]
jmp instruction_assembled
mov_reg_imm_8bit:
call get_byte_value
mov dl,al
mov al,0B0h
call store_mov_reg_imm_code
mov al,dl
stos byte [edi]
jmp instruction_assembled
mov_reg_imm_16bit:
call get_word_value
mov dx,ax
call operand_16bit
mov al,0B8h
call store_mov_reg_imm_code
mov ax,dx
call mark_relocation
stos word [edi]
jmp instruction_assembled
mov_reg_imm_32bit:
call operand_32bit
call get_dword_value
mov edx,eax
mov al,0B8h
call store_mov_reg_imm_code
mov_store_imm_32bit:
mov eax,edx
call mark_relocation
stos dword [edi]
jmp instruction_assembled
store_mov_reg_imm_code:
mov ah,[postbyte_register]
test ah,1000b
jz mov_reg_imm_prefix_ok
or [rex_prefix],41h
mov_reg_imm_prefix_ok:
and ah,111b
add al,ah
mov [base_code],al
call store_classic_instruction_code
ret
mov_reg_64bit_imm_32bit:
mov edx,eax
mov bl,[postbyte_register]
mov [postbyte_register],0
mov [base_code],0C7h
call store_nomem_instruction
jmp mov_store_imm_32bit
mov_sreg:
mov ah,al
and al,1111b
mov [postbyte_register],al
shr ah,4
cmp ah,3
jne invalid_operand
cmp al,2
je illegal_instruction
dec [postbyte_register]
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
je mov_sreg_mem
cmp al,10h
jne invalid_operand
mov_sreg_reg:
lods byte [esi]
call convert_register
or ah,ah
jz mov_sreg_reg_size_ok
cmp ah,2
jne invalid_operand_size
mov bl,al
mov_sreg_reg_size_ok:
mov [base_code],8Eh
jmp nomem_instruction_ready
mov_sreg_mem:
call get_address
mov al,[operand_size]
or al,al
jz mov_sreg_mem_size_ok
cmp al,2
jne invalid_operand_size
mov_sreg_mem_size_ok:
mov [base_code],8Eh
jmp instruction_ready
mov_creg:
lods byte [esi]
mov ah,al
shr ah,4
cmp ah,4
ja invalid_operand
add ah,22h
mov [extended_code],ah
and al,1111b
mov [postbyte_register],al
mov [base_code],0Fh
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
mov bl,al
cmp [code_type],64
je mov_creg_64bit
cmp ah,4
jne invalid_operand_size
cmp [postbyte_register],8
jb mov_creg_store
cmp [extended_code],22h
jne mov_creg_store
mov al,0F0h
stos byte [edi]
mov [postbyte_register],0
mov_creg_store:
jmp nomem_instruction_ready
mov_creg_64bit:
cmp ah,8
je mov_creg_store
jmp invalid_operand_size
test_instruction:
mov [base_code],84h
lods byte [esi]
call get_size_operator
cmp al,10h
je test_reg
cmp al,'['
jne invalid_operand
test_mem:
call get_address
push edx ebx ecx
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'('
je test_mem_imm
cmp al,10h
jne invalid_operand
test_mem_reg:
lods byte [esi]
call convert_register
mov [postbyte_register],al
pop ecx ebx edx
mov al,ah
cmp al,1
je test_mem_reg_8bit
call operand_autodetect
inc [base_code]
test_mem_reg_8bit:
jmp instruction_ready
test_mem_imm:
mov al,[operand_size]
cmp al,1
jb test_mem_imm_nosize
je test_mem_imm_8bit
cmp al,2
je test_mem_imm_16bit
cmp al,4
je test_mem_imm_32bit
cmp al,8
jne invalid_operand_size
test_mem_imm_64bit:
cmp [size_declared],0
jne long_immediate_not_encodable
call operand_64bit
call get_simm32
cmp [value_type],4
jae long_immediate_not_encodable
jmp test_mem_imm_32bit_store
test_mem_imm_nosize:
call recoverable_unknown_size
test_mem_imm_8bit:
call get_byte_value
mov byte [value],al
mov [postbyte_register],0
mov [base_code],0F6h
pop ecx ebx edx
call store_instruction_with_imm8
jmp instruction_assembled
test_mem_imm_16bit:
call operand_16bit
call get_word_value
mov word [value],ax
mov [postbyte_register],0
mov [base_code],0F7h
pop ecx ebx edx
call store_instruction_with_imm16
jmp instruction_assembled
test_mem_imm_32bit:
call operand_32bit
call get_dword_value
test_mem_imm_32bit_store:
mov dword [value],eax
mov [postbyte_register],0
mov [base_code],0F7h
pop ecx ebx edx
call store_instruction_with_imm32
jmp instruction_assembled
test_reg:
lods byte [esi]
call convert_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
je test_reg_mem
cmp al,'('
je test_reg_imm
cmp al,10h
jne invalid_operand
test_reg_reg:
lods byte [esi]
call convert_register
mov bl,[postbyte_register]
mov [postbyte_register],al
mov al,ah
cmp al,1
je test_reg_reg_8bit
call operand_autodetect
inc [base_code]
test_reg_reg_8bit:
jmp nomem_instruction_ready
test_reg_imm:
mov al,[operand_size]
cmp al,1
je test_reg_imm_8bit
cmp al,2
je test_reg_imm_16bit
cmp al,4
je test_reg_imm_32bit
cmp al,8
jne invalid_operand_size
test_reg_imm_64bit:
cmp [size_declared],0
jne long_immediate_not_encodable
call operand_64bit
call get_simm32
cmp [value_type],4
jae long_immediate_not_encodable
jmp test_reg_imm_32bit_store
test_reg_imm_8bit:
call get_byte_value
mov dl,al
mov bl,[postbyte_register]
mov [postbyte_register],0
mov [base_code],0F6h
or bl,bl
jz test_al_imm
call store_nomem_instruction
mov al,dl
stos byte [edi]
jmp instruction_assembled
test_al_imm:
mov [base_code],0A8h
call store_classic_instruction_code
mov al,dl
stos byte [edi]
jmp instruction_assembled
test_reg_imm_16bit:
call operand_16bit
call get_word_value
mov dx,ax
mov bl,[postbyte_register]
mov [postbyte_register],0
mov [base_code],0F7h
or bl,bl
jz test_ax_imm
call store_nomem_instruction
mov ax,dx
call mark_relocation
stos word [edi]
jmp instruction_assembled
test_ax_imm:
mov [base_code],0A9h
call store_classic_instruction_code
mov ax,dx
stos word [edi]
jmp instruction_assembled
test_reg_imm_32bit:
call operand_32bit
call get_dword_value
test_reg_imm_32bit_store:
mov edx,eax
mov bl,[postbyte_register]
mov [postbyte_register],0
mov [base_code],0F7h
or bl,bl
jz test_eax_imm
call store_nomem_instruction
mov eax,edx
call mark_relocation
stos dword [edi]
jmp instruction_assembled
test_eax_imm:
mov [base_code],0A9h
call store_classic_instruction_code
mov eax,edx
stos dword [edi]
jmp instruction_assembled
test_reg_mem:
call get_address
mov al,[operand_size]
cmp al,1
je test_reg_mem_8bit
call operand_autodetect
inc [base_code]
test_reg_mem_8bit:
jmp instruction_ready
xchg_instruction:
mov [base_code],86h
lods byte [esi]
call get_size_operator
cmp al,10h
je xchg_reg
cmp al,'['
jne invalid_operand
xchg_mem:
call get_address
push edx ebx ecx
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je test_mem_reg
jmp invalid_operand
xchg_reg:
lods byte [esi]
call convert_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
je test_reg_mem
cmp al,10h
jne invalid_operand
xchg_reg_reg:
lods byte [esi]
call convert_register
mov bl,al
mov al,ah
cmp al,1
je xchg_reg_reg_8bit
call operand_autodetect
cmp [postbyte_register],0
je xchg_ax_reg
or bl,bl
jnz xchg_reg_reg_store
mov bl,[postbyte_register]
xchg_ax_reg:
cmp [code_type],64
jne xchg_ax_reg_ok
cmp ah,4
jne xchg_ax_reg_ok
or bl,bl
jz xchg_reg_reg_store
xchg_ax_reg_ok:
test bl,1000b
jz xchg_ax_reg_store
or [rex_prefix],41h
and bl,111b
xchg_ax_reg_store:
add bl,90h
mov [base_code],bl
call store_classic_instruction_code
jmp instruction_assembled
xchg_reg_reg_store:
inc [base_code]
xchg_reg_reg_8bit:
jmp nomem_instruction_ready
push_instruction:
mov [push_size],al
push_next:
lods byte [esi]
call get_size_operator
cmp al,10h
je push_reg
cmp al,'('
je push_imm
cmp al,'['
jne invalid_operand
push_mem:
call get_address
mov al,[operand_size]
mov ah,[push_size]
cmp al,2
je push_mem_16bit
cmp al,4
je push_mem_32bit
cmp al,8
je push_mem_64bit
or al,al
jnz invalid_operand_size
cmp ah,2
je push_mem_16bit
cmp ah,4
je push_mem_32bit
cmp ah,8
je push_mem_64bit
call recoverable_unknown_size
jmp push_mem_store
push_mem_16bit:
test ah,not 2
jnz invalid_operand_size
call operand_16bit
jmp push_mem_store
push_mem_32bit:
test ah,not 4
jnz invalid_operand_size
cmp [code_type],64
je illegal_instruction
call operand_32bit
jmp push_mem_store
push_mem_64bit:
test ah,not 8
jnz invalid_operand_size
cmp [code_type],64
jne illegal_instruction
push_mem_store:
mov [base_code],0FFh
mov [postbyte_register],110b
call store_instruction
jmp push_done
push_reg:
lods byte [esi]
mov ah,al
sub ah,10h
and ah,al
test ah,0F0h
jnz push_sreg
call convert_register
test al,1000b
jz push_reg_ok
or [rex_prefix],41h
and al,111b
push_reg_ok:
add al,50h
mov [base_code],al
mov al,ah
mov ah,[push_size]
cmp al,2
je push_reg_16bit
cmp al,4
je push_reg_32bit
cmp al,8
jne invalid_operand_size
push_reg_64bit:
test ah,not 8
jnz invalid_operand_size
cmp [code_type],64
jne illegal_instruction
jmp push_reg_store
push_reg_32bit:
test ah,not 4
jnz invalid_operand_size
cmp [code_type],64
je illegal_instruction
call operand_32bit
jmp push_reg_store
push_reg_16bit:
test ah,not 2
jnz invalid_operand_size
call operand_16bit
push_reg_store:
call store_classic_instruction_code
jmp push_done
push_sreg:
mov bl,al
mov dl,[operand_size]
mov dh,[push_size]
cmp dl,2
je push_sreg16
cmp dl,4
je push_sreg32
cmp dl,8
je push_sreg64
or dl,dl
jnz invalid_operand_size
cmp dh,2
je push_sreg16
cmp dh,4
je push_sreg32
cmp dh,8
je push_sreg64
jmp push_sreg_store
push_sreg16:
test dh,not 2
jnz invalid_operand_size
call operand_16bit
jmp push_sreg_store
push_sreg32:
test dh,not 4
jnz invalid_operand_size
cmp [code_type],64
je illegal_instruction
call operand_32bit
jmp push_sreg_store
push_sreg64:
test dh,not 8
jnz invalid_operand_size
cmp [code_type],64
jne illegal_instruction
push_sreg_store:
mov al,bl
cmp al,40h
jae invalid_operand
sub al,31h
jc invalid_operand
cmp al,4
jae push_sreg_386
shl al,3
add al,6
mov [base_code],al
cmp [code_type],64
je illegal_instruction
jmp push_reg_store
push_sreg_386:
sub al,4
shl al,3
add al,0A0h
mov [extended_code],al
mov [base_code],0Fh
jmp push_reg_store
push_imm:
mov al,[operand_size]
mov ah,[push_size]
or al,al
je push_imm_size_ok
or ah,ah
je push_imm_size_ok
cmp al,ah
jne invalid_operand_size
push_imm_size_ok:
cmp al,2
je push_imm_16bit
cmp al,4
je push_imm_32bit
cmp al,8
je push_imm_64bit
cmp ah,2
je push_imm_optimized_16bit
cmp ah,4
je push_imm_optimized_32bit
cmp ah,8
je push_imm_optimized_64bit
or al,al
jnz invalid_operand_size
cmp [code_type],16
je push_imm_optimized_16bit
cmp [code_type],32
je push_imm_optimized_32bit
push_imm_optimized_64bit:
cmp [code_type],64
jne illegal_instruction
call get_simm32
mov edx,eax
cmp [value_type],0
jne push_imm_32bit_store
cmp eax,-80h
jl push_imm_32bit_store
cmp eax,80h
jge push_imm_32bit_store
jmp push_imm_8bit
push_imm_optimized_32bit:
cmp [code_type],64
je illegal_instruction
call get_dword_value
mov edx,eax
call operand_32bit
cmp [value_type],0
jne push_imm_32bit_store
cmp eax,-80h
jl push_imm_32bit_store
cmp eax,80h
jge push_imm_32bit_store
jmp push_imm_8bit
push_imm_optimized_16bit:
call get_word_value
mov dx,ax
call operand_16bit
cmp [value_type],0
jne push_imm_16bit_store
cmp ax,-80h
jl push_imm_16bit_store
cmp ax,80h
jge push_imm_16bit_store
push_imm_8bit:
mov ah,al
mov [base_code],6Ah
call store_classic_instruction_code
mov al,ah
stos byte [edi]
jmp push_done
push_imm_16bit:
call get_word_value
mov dx,ax
call operand_16bit
push_imm_16bit_store:
mov [base_code],68h
call store_classic_instruction_code
mov ax,dx
call mark_relocation
stos word [edi]
jmp push_done
push_imm_64bit:
cmp [code_type],64
jne illegal_instruction
call get_simm32
mov edx,eax
jmp push_imm_32bit_store
push_imm_32bit:
cmp [code_type],64
je illegal_instruction
call get_dword_value
mov edx,eax
call operand_32bit
push_imm_32bit_store:
mov [base_code],68h
call store_classic_instruction_code
mov eax,edx
call mark_relocation
stos dword [edi]
push_done:
lods byte [esi]
dec esi
cmp al,0Fh
je instruction_assembled
or al,al
jz instruction_assembled
; mov [operand_size],0
; mov [operand_flags],0
; mov [operand_prefix],0
; mov [rex_prefix],0
and dword [operand_size],0
jmp push_next
pop_instruction:
mov [push_size],al
pop_next:
lods byte [esi]
call get_size_operator
cmp al,10h
je pop_reg
cmp al,'['
jne invalid_operand
pop_mem:
call get_address
mov al,[operand_size]
mov ah,[push_size]
cmp al,2
je pop_mem_16bit
cmp al,4
je pop_mem_32bit
cmp al,8
je pop_mem_64bit
or al,al
jnz invalid_operand_size
cmp ah,2
je pop_mem_16bit
cmp ah,4
je pop_mem_32bit
cmp ah,8
je pop_mem_64bit
call recoverable_unknown_size
jmp pop_mem_store
pop_mem_16bit:
test ah,not 2
jnz invalid_operand_size
call operand_16bit
jmp pop_mem_store
pop_mem_32bit:
test ah,not 4
jnz invalid_operand_size
cmp [code_type],64
je illegal_instruction
call operand_32bit
jmp pop_mem_store
pop_mem_64bit:
test ah,not 8
jnz invalid_operand_size
cmp [code_type],64
jne illegal_instruction
pop_mem_store:
mov [base_code],08Fh
mov [postbyte_register],0
call store_instruction
jmp pop_done
pop_reg:
lods byte [esi]
mov ah,al
sub ah,10h
and ah,al
test ah,0F0h
jnz pop_sreg
call convert_register
test al,1000b
jz pop_reg_ok
or [rex_prefix],41h
and al,111b
pop_reg_ok:
add al,58h
mov [base_code],al
mov al,ah
mov ah,[push_size]
cmp al,2
je pop_reg_16bit
cmp al,4
je pop_reg_32bit
cmp al,8
je pop_reg_64bit
jmp invalid_operand_size
pop_reg_64bit:
test ah,not 8
jnz invalid_operand_size
cmp [code_type],64
jne illegal_instruction
jmp pop_reg_store
pop_reg_32bit:
test ah,not 4
jnz invalid_operand_size
cmp [code_type],64
je illegal_instruction
call operand_32bit
jmp pop_reg_store
pop_reg_16bit:
test ah,not 2
jnz invalid_operand_size
call operand_16bit
pop_reg_store:
call store_classic_instruction_code
pop_done:
lods byte [esi]
dec esi
cmp al,0Fh
je instruction_assembled
or al,al
jz instruction_assembled
; mov [operand_size],0
; mov [operand_flags],0
; mov [operand_prefix],0
; mov [rex_prefix],0
and dword [operand_size],0
jmp pop_next
pop_sreg:
mov dl,[operand_size]
mov dh,[push_size]
cmp al,32h
je pop_cs
mov bl,al
cmp dl,2
je pop_sreg16
cmp dl,4
je pop_sreg32
cmp dl,8
je pop_sreg64
or dl,dl
jnz invalid_operand_size
cmp dh,2
je pop_sreg16
cmp dh,4
je pop_sreg32
cmp dh,8
je pop_sreg64
jmp pop_sreg_store
pop_sreg16:
test dh,not 2
jnz invalid_operand_size
call operand_16bit
jmp pop_sreg_store
pop_sreg32:
test dh,not 4
jnz invalid_operand_size
cmp [code_type],64
je illegal_instruction
call operand_32bit
jmp pop_sreg_store
pop_sreg64:
test dh,not 8
jnz invalid_operand_size
cmp [code_type],64
jne illegal_instruction
pop_sreg_store:
mov al,bl
cmp al,40h
jae invalid_operand
sub al,31h
jc invalid_operand
cmp al,4
jae pop_sreg_386
shl al,3
add al,7
mov [base_code],al
cmp [code_type],64
je illegal_instruction
jmp pop_reg_store
pop_cs:
cmp [code_type],16
jne illegal_instruction
cmp dl,2
je pop_cs_store
or dl,dl
jnz invalid_operand_size
cmp dh,2
je pop_cs_store
or dh,dh
jnz illegal_instruction
pop_cs_store:
test dh,not 2
jnz invalid_operand_size
mov al,0Fh
stos byte [edi]
jmp pop_done
pop_sreg_386:
sub al,4
shl al,3
add al,0A1h
mov [extended_code],al
mov [base_code],0Fh
jmp pop_reg_store
inc_instruction:
mov [base_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
je inc_reg
cmp al,'['
je inc_mem
jne invalid_operand
inc_mem:
call get_address
mov al,[operand_size]
cmp al,1
je inc_mem_8bit
jb inc_mem_nosize
call operand_autodetect
mov al,0FFh
xchg al,[base_code]
mov [postbyte_register],al
jmp instruction_ready
inc_mem_nosize:
call recoverable_unknown_size
inc_mem_8bit:
mov al,0FEh
xchg al,[base_code]
mov [postbyte_register],al
jmp instruction_ready
inc_reg:
lods byte [esi]
call convert_register
mov bl,al
mov al,0FEh
xchg al,[base_code]
mov [postbyte_register],al
mov al,ah
cmp al,1
je inc_reg_8bit
call operand_autodetect
cmp [code_type],64
je inc_reg_long_form
mov al,[postbyte_register]
shl al,3
add al,bl
add al,40h
mov [base_code],al
call store_classic_instruction_code
jmp instruction_assembled
inc_reg_long_form:
inc [base_code]
inc_reg_8bit:
jmp nomem_instruction_ready
set_instruction:
mov [base_code],0Fh
mov [extended_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
je set_reg
cmp al,'['
jne invalid_operand
set_mem:
call get_address
cmp [operand_size],1
ja invalid_operand_size
mov [postbyte_register],0
jmp instruction_ready
set_reg:
lods byte [esi]
call convert_register
cmp ah,1
jne invalid_operand_size
mov bl,al
mov [postbyte_register],0
jmp nomem_instruction_ready
arpl_instruction:
cmp [code_type],64
je illegal_instruction
mov [base_code],63h
lods byte [esi]
call get_size_operator
cmp al,10h
je arpl_reg
cmp al,'['
jne invalid_operand
call get_address
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
mov [postbyte_register],al
cmp ah,2
jne invalid_operand_size
jmp instruction_ready
arpl_reg:
lods byte [esi]
call convert_register
cmp ah,2
jne invalid_operand_size
mov bl,al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
mov [postbyte_register],al
jmp nomem_instruction_ready
bound_instruction:
cmp [code_type],64
je illegal_instruction
call take_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
cmp al,2
je bound_store
cmp al,4
jne invalid_operand_size
bound_store:
call operand_autodetect
mov [base_code],62h
jmp instruction_ready
enter_instruction:
lods byte [esi]
call get_size_operator
cmp ah,2
je enter_imm16_size_ok
or ah,ah
jnz invalid_operand_size
enter_imm16_size_ok:
cmp al,'('
jne invalid_operand
call get_word_value
cmp [next_pass_needed],0
jne enter_imm16_ok
cmp [value_type],0
jne invalid_use_of_symbol
test eax,eax
js value_out_of_range
enter_imm16_ok:
push eax
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp ah,1
je enter_imm8_size_ok
or ah,ah
jnz invalid_operand_size
enter_imm8_size_ok:
cmp al,'('
jne invalid_operand
call get_byte_value
cmp [next_pass_needed],0
jne enter_imm8_ok
test eax,eax
js value_out_of_range
enter_imm8_ok:
mov dl,al
pop ebx
mov al,0C8h
stos byte [edi]
mov ax,bx
stos word [edi]
mov al,dl
stos byte [edi]
jmp instruction_assembled
ret_instruction_only64:
cmp [code_type],64
jne illegal_instruction
jmp ret_instruction
ret_instruction_32bit_except64:
cmp [code_type],64
je illegal_instruction
ret_instruction_32bit:
call operand_32bit
jmp ret_instruction
ret_instruction_16bit:
call operand_16bit
jmp ret_instruction
ret_instruction_64bit:
call operand_64bit
ret_instruction:
and [prefix_flags],not 10h
ret_common:
mov [base_code],al
lods byte [esi]
dec esi
or al,al
jz simple_ret
cmp al,0Fh
je simple_ret
lods byte [esi]
call get_size_operator
or ah,ah
jz ret_imm
cmp ah,2
je ret_imm
jmp invalid_operand_size
ret_imm:
cmp al,'('
jne invalid_operand
call get_word_value
cmp [next_pass_needed],0
jne ret_imm_ok
cmp [value_type],0
jne invalid_use_of_symbol
test eax,eax
js value_out_of_range
ret_imm_ok:
cmp [size_declared],0
jne ret_imm_store
or ax,ax
jz simple_ret
ret_imm_store:
mov dx,ax
call store_classic_instruction_code
mov ax,dx
stos word [edi]
jmp instruction_assembled
simple_ret:
inc [base_code]
call store_classic_instruction_code
jmp instruction_assembled
retf_instruction:
cmp [code_type],64
jne ret_common
retf_instruction_64bit:
call operand_64bit
jmp ret_common
retf_instruction_32bit:
call operand_32bit
jmp ret_common
retf_instruction_16bit:
call operand_16bit
jmp ret_common
lea_instruction:
mov [base_code],8Dh
call take_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
xor al,al
xchg al,[operand_size]
push eax
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
or [operand_flags],1
call get_address
pop eax
mov [operand_size],al
call operand_autodetect
jmp instruction_ready
ls_instruction:
or al,al
jz les_instruction
cmp al,3
jz lds_instruction
add al,0B0h
mov [extended_code],al
mov [base_code],0Fh
jmp ls_code_ok
les_instruction:
mov [base_code],0C4h
jmp ls_short_code
lds_instruction:
mov [base_code],0C5h
ls_short_code:
cmp [code_type],64
je illegal_instruction
ls_code_ok:
call take_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
add [operand_size],2
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
cmp al,4
je ls_16bit
cmp al,6
je ls_32bit
cmp al,10
je ls_64bit
jmp invalid_operand_size
ls_16bit:
call operand_16bit
jmp instruction_ready
ls_32bit:
call operand_32bit
jmp instruction_ready
ls_64bit:
call operand_64bit
jmp instruction_ready
sh_instruction:
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,10h
je sh_reg
cmp al,'['
jne invalid_operand
sh_mem:
call get_address
push edx ebx ecx
mov al,[operand_size]
push eax
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'('
je sh_mem_imm
cmp al,10h
jne invalid_operand
sh_mem_reg:
lods byte [esi]
cmp al,11h
jne invalid_operand
pop eax ecx ebx edx
cmp al,1
je sh_mem_cl_8bit
jb sh_mem_cl_nosize
call operand_autodetect
mov [base_code],0D3h
jmp instruction_ready
sh_mem_cl_nosize:
call recoverable_unknown_size
sh_mem_cl_8bit:
mov [base_code],0D2h
jmp instruction_ready
sh_mem_imm:
mov al,[operand_size]
or al,al
jz sh_mem_imm_size_ok
cmp al,1
jne invalid_operand_size
sh_mem_imm_size_ok:
call get_byte_value
mov byte [value],al
pop eax ecx ebx edx
cmp al,1
je sh_mem_imm_8bit
jb sh_mem_imm_nosize
call operand_autodetect
cmp byte [value],1
je sh_mem_1
mov [base_code],0C1h
call store_instruction_with_imm8
jmp instruction_assembled
sh_mem_1:
mov [base_code],0D1h
jmp instruction_ready
sh_mem_imm_nosize:
call recoverable_unknown_size
sh_mem_imm_8bit:
cmp byte [value],1
je sh_mem_1_8bit
mov [base_code],0C0h
call store_instruction_with_imm8
jmp instruction_assembled
sh_mem_1_8bit:
mov [base_code],0D0h
jmp instruction_ready
sh_reg:
lods byte [esi]
call convert_register
mov bx,ax
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'('
je sh_reg_imm
cmp al,10h
jne invalid_operand
sh_reg_reg:
lods byte [esi]
cmp al,11h
jne invalid_operand
mov al,bh
cmp al,1
je sh_reg_cl_8bit
call operand_autodetect
mov [base_code],0D3h
jmp nomem_instruction_ready
sh_reg_cl_8bit:
mov [base_code],0D2h
jmp nomem_instruction_ready
sh_reg_imm:
mov al,[operand_size]
or al,al
jz sh_reg_imm_size_ok
cmp al,1
jne invalid_operand_size
sh_reg_imm_size_ok:
push ebx
call get_byte_value
mov dl,al
pop ebx
mov al,bh
cmp al,1
je sh_reg_imm_8bit
call operand_autodetect
cmp dl,1
je sh_reg_1
mov [base_code],0C1h
call store_nomem_instruction
mov al,dl
stos byte [edi]
jmp instruction_assembled
sh_reg_1:
mov [base_code],0D1h
jmp nomem_instruction_ready
sh_reg_imm_8bit:
cmp dl,1
je sh_reg_1_8bit
mov [base_code],0C0h
call store_nomem_instruction
mov al,dl
stos byte [edi]
jmp instruction_assembled
sh_reg_1_8bit:
mov [base_code],0D0h
jmp nomem_instruction_ready
shd_instruction:
mov [base_code],0Fh
mov [extended_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
je shd_reg
cmp al,'['
jne invalid_operand
shd_mem:
call get_address
push edx ebx ecx
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
mov al,ah
mov [operand_size],0
push eax
lods byte [esi]
call get_size_operator
cmp al,'('
je shd_mem_reg_imm
cmp al,10h
jne invalid_operand
lods byte [esi]
cmp al,11h
jne invalid_operand
pop eax ecx ebx edx
call operand_autodetect
inc [extended_code]
jmp instruction_ready
shd_mem_reg_imm:
mov al,[operand_size]
or al,al
jz shd_mem_reg_imm_size_ok
cmp al,1
jne invalid_operand_size
shd_mem_reg_imm_size_ok:
call get_byte_value
mov byte [value],al
pop eax ecx ebx edx
call operand_autodetect
call store_instruction_with_imm8
jmp instruction_assembled
shd_reg:
lods byte [esi]
call convert_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
mov bl,[postbyte_register]
mov [postbyte_register],al
mov al,ah
push eax ebx
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,'('
je shd_reg_reg_imm
cmp al,10h
jne invalid_operand
lods byte [esi]
cmp al,11h
jne invalid_operand
pop ebx eax
call operand_autodetect
inc [extended_code]
jmp nomem_instruction_ready
shd_reg_reg_imm:
mov al,[operand_size]
or al,al
jz shd_reg_reg_imm_size_ok
cmp al,1
jne invalid_operand_size
shd_reg_reg_imm_size_ok:
call get_byte_value
mov dl,al
pop ebx eax
call operand_autodetect
call store_nomem_instruction
mov al,dl
stos byte [edi]
jmp instruction_assembled
movx_instruction:
mov [base_code],0Fh
mov [extended_code],al
call take_register
mov [postbyte_register],al
mov al,ah
push eax
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,10h
je movx_reg
cmp al,'['
jne invalid_operand
call get_address
pop eax
mov ah,[operand_size]
or ah,ah
jz movx_unknown_size
cmp ah,al
jae invalid_operand_size
cmp ah,1
je movx_mem_store
cmp ah,2
jne invalid_operand_size
inc [extended_code]
movx_mem_store:
call operand_autodetect
jmp instruction_ready
movx_unknown_size:
call recoverable_unknown_size
jmp movx_mem_store
movx_reg:
lods byte [esi]
call convert_register
pop ebx
xchg bl,al
cmp ah,al
jae invalid_operand_size
cmp ah,1
je movx_reg_8bit
cmp ah,2
je movx_reg_16bit
jmp invalid_operand_size
movx_reg_8bit:
call operand_autodetect
jmp nomem_instruction_ready
movx_reg_16bit:
call operand_autodetect
inc [extended_code]
jmp nomem_instruction_ready
movsxd_instruction:
mov [base_code],al
call take_register
mov [postbyte_register],al
cmp ah,8
jne invalid_operand_size
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,10h
je movsxd_reg
cmp al,'['
jne invalid_operand
call get_address
cmp [operand_size],4
je movsxd_mem_store
cmp [operand_size],0
jne invalid_operand_size
movsxd_mem_store:
call operand_64bit
jmp instruction_ready
movsxd_reg:
lods byte [esi]
call convert_register
cmp ah,4
jne invalid_operand_size
mov bl,al
call operand_64bit
jmp nomem_instruction_ready
bt_instruction:
mov [postbyte_register],al
shl al,3
add al,83h
mov [extended_code],al
mov [base_code],0Fh
lods byte [esi]
call get_size_operator
cmp al,10h
je bt_reg
cmp al,'['
jne invalid_operand
call get_address
push eax ebx ecx
lods byte [esi]
cmp al,','
jne invalid_operand
cmp byte [esi],'('
je bt_mem_imm
cmp byte [esi],11h
jne bt_mem_reg
cmp byte [esi+2],'('
je bt_mem_imm
bt_mem_reg:
call take_register
mov [postbyte_register],al
pop ecx ebx edx
mov al,ah
call operand_autodetect
jmp instruction_ready
bt_mem_imm:
xor al,al
xchg al,[operand_size]
push eax
lods byte [esi]
call get_size_operator
cmp al,'('
jne invalid_operand
mov al,[operand_size]
or al,al
jz bt_mem_imm_size_ok
cmp al,1
jne invalid_operand_size
bt_mem_imm_size_ok:
call get_byte_value
mov byte [value],al
pop eax
or al,al
jz bt_mem_imm_nosize
call operand_autodetect
bt_mem_imm_store:
pop ecx ebx edx
mov [extended_code],0BAh
call store_instruction_with_imm8
jmp instruction_assembled
bt_mem_imm_nosize:
call recoverable_unknown_size
jmp bt_mem_imm_store
bt_reg:
lods byte [esi]
call convert_register
mov bl,al
lods byte [esi]
cmp al,','
jne invalid_operand
cmp byte [esi],'('
je bt_reg_imm
cmp byte [esi],11h
jne bt_reg_reg
cmp byte [esi+2],'('
je bt_reg_imm
bt_reg_reg:
call take_register
mov [postbyte_register],al
mov al,ah
call operand_autodetect
jmp nomem_instruction_ready
bt_reg_imm:
xor al,al
xchg al,[operand_size]
push eax ebx
lods byte [esi]
call get_size_operator
cmp al,'('
jne invalid_operand
mov al,[operand_size]
or al,al
jz bt_reg_imm_size_ok
cmp al,1
jne invalid_operand_size
bt_reg_imm_size_ok:
call get_byte_value
mov byte [value],al
pop ebx eax
call operand_autodetect
bt_reg_imm_store:
mov [extended_code],0BAh
call store_nomem_instruction
mov al,byte [value]
stos byte [edi]
jmp instruction_assembled
bs_instruction:
mov [extended_code],al
mov [base_code],0Fh
call get_reg_mem
jc bs_reg_reg
mov al,[operand_size]
call operand_autodetect
jmp instruction_ready
bs_reg_reg:
mov al,ah
call operand_autodetect
jmp nomem_instruction_ready
get_reg_mem:
call take_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je get_reg_reg
cmp al,'['
jne invalid_argument
call get_address
clc
ret
get_reg_reg:
lods byte [esi]
call convert_register
mov bl,al
stc
ret
 
imul_instruction:
mov [base_code],0F6h
mov [postbyte_register],5
lods byte [esi]
call get_size_operator
cmp al,10h
je imul_reg
cmp al,'['
jne invalid_operand
imul_mem:
call get_address
mov al,[operand_size]
cmp al,1
je imul_mem_8bit
jb imul_mem_nosize
call operand_autodetect
inc [base_code]
jmp instruction_ready
imul_mem_nosize:
call recoverable_unknown_size
imul_mem_8bit:
jmp instruction_ready
imul_reg:
lods byte [esi]
call convert_register
cmp byte [esi],','
je imul_reg_
mov bl,al
mov al,ah
cmp al,1
je imul_reg_8bit
call operand_autodetect
inc [base_code]
imul_reg_8bit:
jmp nomem_instruction_ready
imul_reg_:
mov [postbyte_register],al
inc esi
cmp byte [esi],'('
je imul_reg_imm
cmp byte [esi],11h
jne imul_reg_noimm
cmp byte [esi+2],'('
je imul_reg_imm
imul_reg_noimm:
lods byte [esi]
call get_size_operator
cmp al,10h
je imul_reg_reg
cmp al,'['
jne invalid_operand
imul_reg_mem:
call get_address
push edx ebx ecx
cmp byte [esi],','
je imul_reg_mem_imm
mov al,[operand_size]
call operand_autodetect
pop ecx ebx edx
mov [base_code],0Fh
mov [extended_code],0AFh
jmp instruction_ready
imul_reg_mem_imm:
inc esi
lods byte [esi]
call get_size_operator
cmp al,'('
jne invalid_operand
mov al,[operand_size]
cmp al,2
je imul_reg_mem_imm_16bit
cmp al,4
je imul_reg_mem_imm_32bit
cmp al,8
jne invalid_operand_size
imul_reg_mem_imm_64bit:
cmp [size_declared],0
jne long_immediate_not_encodable
call operand_64bit
call get_simm32
cmp [value_type],4
jae long_immediate_not_encodable
jmp imul_reg_mem_imm_32bit_ok
imul_reg_mem_imm_16bit:
call operand_16bit
call get_word_value
mov word [value],ax
cmp [value_type],0
jne imul_reg_mem_imm_16bit_store
cmp [size_declared],0
jne imul_reg_mem_imm_16bit_store
cmp ax,-80h
jl imul_reg_mem_imm_16bit_store
cmp ax,80h
jl imul_reg_mem_imm_8bit_store
imul_reg_mem_imm_16bit_store:
pop ecx ebx edx
mov [base_code],69h
call store_instruction_with_imm16
jmp instruction_assembled
imul_reg_mem_imm_32bit:
call operand_32bit
call get_dword_value
imul_reg_mem_imm_32bit_ok:
mov dword [value],eax
cmp [value_type],0
jne imul_reg_mem_imm_32bit_store
cmp [size_declared],0
jne imul_reg_mem_imm_32bit_store
cmp eax,-80h
jl imul_reg_mem_imm_32bit_store
cmp eax,80h
jl imul_reg_mem_imm_8bit_store
imul_reg_mem_imm_32bit_store:
pop ecx ebx edx
mov [base_code],69h
call store_instruction_with_imm32
jmp instruction_assembled
imul_reg_mem_imm_8bit_store:
pop ecx ebx edx
mov [base_code],6Bh
call store_instruction_with_imm8
jmp instruction_assembled
imul_reg_imm:
mov bl,[postbyte_register]
dec esi
jmp imul_reg_reg_imm
imul_reg_reg:
lods byte [esi]
call convert_register
mov bl,al
cmp byte [esi],','
je imul_reg_reg_imm
mov al,ah
call operand_autodetect
mov [base_code],0Fh
mov [extended_code],0AFh
jmp nomem_instruction_ready
imul_reg_reg_imm:
inc esi
lods byte [esi]
call get_size_operator
cmp al,'('
jne invalid_operand
mov al,[operand_size]
cmp al,2
je imul_reg_reg_imm_16bit
cmp al,4
je imul_reg_reg_imm_32bit
cmp al,8
jne invalid_operand_size
imul_reg_reg_imm_64bit:
cmp [size_declared],0
jne long_immediate_not_encodable
call operand_64bit
push ebx
call get_simm32
cmp [value_type],4
jae long_immediate_not_encodable
jmp imul_reg_reg_imm_32bit_ok
imul_reg_reg_imm_16bit:
call operand_16bit
push ebx
call get_word_value
pop ebx
mov dx,ax
cmp [value_type],0
jne imul_reg_reg_imm_16bit_store
cmp [size_declared],0
jne imul_reg_reg_imm_16bit_store
cmp ax,-80h
jl imul_reg_reg_imm_16bit_store
cmp ax,80h
jl imul_reg_reg_imm_8bit_store
imul_reg_reg_imm_16bit_store:
mov [base_code],69h
call store_nomem_instruction
mov ax,dx
call mark_relocation
stos word [edi]
jmp instruction_assembled
imul_reg_reg_imm_32bit:
call operand_32bit
push ebx
call get_dword_value
imul_reg_reg_imm_32bit_ok:
pop ebx
mov edx,eax
cmp [value_type],0
jne imul_reg_reg_imm_32bit_store
cmp [size_declared],0
jne imul_reg_reg_imm_32bit_store
cmp eax,-80h
jl imul_reg_reg_imm_32bit_store
cmp eax,80h
jl imul_reg_reg_imm_8bit_store
imul_reg_reg_imm_32bit_store:
mov [base_code],69h
call store_nomem_instruction
mov eax,edx
call mark_relocation
stos dword [edi]
jmp instruction_assembled
imul_reg_reg_imm_8bit_store:
mov [base_code],6Bh
call store_nomem_instruction
mov al,dl
stos byte [edi]
jmp instruction_assembled
in_instruction:
call take_register
or al,al
jnz invalid_operand
lods byte [esi]
cmp al,','
jne invalid_operand
mov al,ah
push eax
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,'('
je in_imm
cmp al,10h
je in_reg
jmp invalid_operand
in_reg:
lods byte [esi]
cmp al,22h
jne invalid_operand
pop eax
cmp al,1
je in_al_dx
cmp al,2
je in_ax_dx
cmp al,4
jne invalid_operand_size
in_ax_dx:
call operand_autodetect
mov [base_code],0EDh
call store_classic_instruction_code
jmp instruction_assembled
in_al_dx:
mov al,0ECh
stos byte [edi]
jmp instruction_assembled
in_imm:
mov al,[operand_size]
or al,al
jz in_imm_size_ok
cmp al,1
jne invalid_operand_size
in_imm_size_ok:
call get_byte_value
mov dl,al
pop eax
cmp al,1
je in_al_imm
cmp al,2
je in_ax_imm
cmp al,4
jne invalid_operand_size
in_ax_imm:
call operand_autodetect
mov [base_code],0E5h
call store_classic_instruction_code
mov al,dl
stos byte [edi]
jmp instruction_assembled
in_al_imm:
mov al,0E4h
stos byte [edi]
mov al,dl
stos byte [edi]
jmp instruction_assembled
out_instruction:
lods byte [esi]
call get_size_operator
cmp al,'('
je out_imm
cmp al,10h
jne invalid_operand
lods byte [esi]
cmp al,22h
jne invalid_operand
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
call take_register
or al,al
jnz invalid_operand
mov al,ah
cmp al,1
je out_dx_al
cmp al,2
je out_dx_ax
cmp al,4
jne invalid_operand_size
out_dx_ax:
call operand_autodetect
mov [base_code],0EFh
call store_classic_instruction_code
jmp instruction_assembled
out_dx_al:
mov al,0EEh
stos byte [edi]
jmp instruction_assembled
out_imm:
mov al,[operand_size]
or al,al
jz out_imm_size_ok
cmp al,1
jne invalid_operand_size
out_imm_size_ok:
call get_byte_value
mov dl,al
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
call take_register
or al,al
jnz invalid_operand
mov al,ah
cmp al,1
je out_imm_al
cmp al,2
je out_imm_ax
cmp al,4
jne invalid_operand_size
out_imm_ax:
call operand_autodetect
mov [base_code],0E7h
call store_classic_instruction_code
mov al,dl
stos byte [edi]
jmp instruction_assembled
out_imm_al:
mov al,0E6h
stos byte [edi]
mov al,dl
stos byte [edi]
jmp instruction_assembled
 
call_instruction:
mov [postbyte_register],10b
mov [base_code],0E8h
mov [extended_code],9Ah
jmp process_jmp
jmp_instruction:
mov [postbyte_register],100b
mov [base_code],0E9h
mov [extended_code],0EAh
process_jmp:
lods byte [esi]
call get_jump_operator
test [prefix_flags],10h
jz jmp_type_ok
test [jump_type],not 2
jnz illegal_instruction
mov [jump_type],2
and [prefix_flags],not 10h
jmp_type_ok:
call get_size_operator
cmp al,'('
je jmp_imm
mov [base_code],0FFh
cmp al,10h
je jmp_reg
cmp al,'['
jne invalid_operand
jmp_mem:
cmp [jump_type],1
je illegal_instruction
call get_address
mov edx,eax
mov al,[operand_size]
or al,al
jz jmp_mem_size_not_specified
cmp al,2
je jmp_mem_16bit
cmp al,4
je jmp_mem_32bit
cmp al,6
je jmp_mem_48bit
cmp al,8
je jmp_mem_64bit
cmp al,10
je jmp_mem_80bit
jmp invalid_operand_size
jmp_mem_size_not_specified:
cmp [jump_type],3
je jmp_mem_far
cmp [jump_type],2
je jmp_mem_near
call recoverable_unknown_size
jmp_mem_near:
cmp [code_type],16
je jmp_mem_16bit
cmp [code_type],32
je jmp_mem_near_32bit
jmp_mem_64bit:
cmp [jump_type],3
je invalid_operand_size
cmp [code_type],64
jne illegal_instruction
jmp instruction_ready
jmp_mem_far:
cmp [code_type],16
je jmp_mem_far_32bit
jmp_mem_48bit:
call operand_32bit
jmp_mem_far_store:
cmp [jump_type],2
je invalid_operand_size
inc [postbyte_register]
jmp instruction_ready
jmp_mem_80bit:
call operand_64bit
jmp jmp_mem_far_store
jmp_mem_far_32bit:
call operand_16bit
jmp jmp_mem_far_store
jmp_mem_32bit:
cmp [jump_type],3
je jmp_mem_far_32bit
cmp [jump_type],2
je jmp_mem_near_32bit
cmp [code_type],16
je jmp_mem_far_32bit
jmp_mem_near_32bit:
cmp [code_type],64
je illegal_instruction
call operand_32bit
jmp instruction_ready
jmp_mem_16bit:
cmp [jump_type],3
je invalid_operand_size
call operand_16bit
jmp instruction_ready
jmp_reg:
test [jump_type],1
jnz invalid_operand
lods byte [esi]
call convert_register
mov bl,al
mov al,ah
cmp al,2
je jmp_reg_16bit
cmp al,4
je jmp_reg_32bit
cmp al,8
jne invalid_operand_size
jmp_reg_64bit:
cmp [code_type],64
jne illegal_instruction
jmp nomem_instruction_ready
jmp_reg_32bit:
cmp [code_type],64
je illegal_instruction
call operand_32bit
jmp nomem_instruction_ready
jmp_reg_16bit:
call operand_16bit
jmp nomem_instruction_ready
jmp_imm:
cmp byte [esi],'.'
je invalid_value
mov ebx,esi
dec esi
call skip_symbol
xchg esi,ebx
cmp byte [ebx],':'
je jmp_far
cmp [jump_type],3
je invalid_operand
jmp_near:
mov al,[operand_size]
cmp al,2
je jmp_imm_16bit
cmp al,4
je jmp_imm_32bit
cmp al,8
je jmp_imm_64bit
or al,al
jnz invalid_operand_size
cmp [code_type],16
je jmp_imm_16bit
cmp [code_type],64
je jmp_imm_64bit
jmp_imm_32bit:
cmp [code_type],64
je invalid_operand_size
call get_address_dword_value
cmp [code_type],16
jne jmp_imm_32bit_prefix_ok
mov byte [edi],66h
inc edi
jmp_imm_32bit_prefix_ok:
call calculate_jump_offset
cdq
call check_for_short_jump
jc jmp_short
jmp_imm_32bit_store:
mov edx,eax
sub edx,3
jno jmp_imm_32bit_ok
cmp [code_type],64
je jump_out_of_range
jmp_imm_32bit_ok:
mov al,[base_code]
stos byte [edi]
mov eax,edx
call mark_relocation
stos dword [edi]
jmp instruction_assembled
jmp_imm_64bit:
cmp [code_type],64
jne invalid_operand_size
call get_address_qword_value
call calculate_jump_offset
mov ecx,edx
cdq
cmp edx,ecx
jne jump_out_of_range
call check_for_short_jump
jnc jmp_imm_32bit_store
jmp_short:
mov ah,al
mov al,0EBh
stos word [edi]
jmp instruction_assembled
jmp_imm_16bit:
call get_address_word_value
cmp [code_type],16
je jmp_imm_16bit_prefix_ok
mov byte [edi],66h
inc edi
jmp_imm_16bit_prefix_ok:
call calculate_jump_offset
cwde
cdq
call check_for_short_jump
jc jmp_short
cmp [value_type],0
jne invalid_use_of_symbol
mov edx,eax
dec edx
mov al,[base_code]
stos byte [edi]
mov eax,edx
stos word [edi]
jmp instruction_assembled
calculate_jump_offset:
add edi,2
mov ebp,[addressing_space]
call calculate_relative_offset
sub edi,2
ret
check_for_short_jump:
cmp [jump_type],1
je forced_short
ja no_short_jump
cmp [base_code],0E8h
je no_short_jump
cmp [value_type],0
jne no_short_jump
cmp eax,80h
jb short_jump
cmp eax,-80h
jae short_jump
no_short_jump:
clc
ret
forced_short:
cmp [base_code],0E8h
je illegal_instruction
cmp [next_pass_needed],0
jne jmp_short_value_type_ok
cmp [value_type],0
jne invalid_use_of_symbol
jmp_short_value_type_ok:
cmp eax,-80h
jae short_jump
cmp eax,80h
jae jump_out_of_range
short_jump:
stc
ret
jump_out_of_range:
cmp [error_line],0
jne instruction_assembled
mov eax,[current_line]
mov [error_line],eax
mov [error],relative_jump_out_of_range
jmp instruction_assembled
jmp_far:
cmp [jump_type],2
je invalid_operand
cmp [code_type],64
je illegal_instruction
mov al,[extended_code]
mov [base_code],al
call get_word_value
push eax
inc esi
lods byte [esi]
cmp al,'('
jne invalid_operand
mov al,[value_type]
push eax [symbol_identifier]
cmp byte [esi],'.'
je invalid_value
mov al,[operand_size]
cmp al,4
je jmp_far_16bit
cmp al,6
je jmp_far_32bit
or al,al
jnz invalid_operand_size
cmp [code_type],16
jne jmp_far_32bit
jmp_far_16bit:
call get_word_value
mov ebx,eax
call operand_16bit
call store_classic_instruction_code
mov ax,bx
call mark_relocation
stos word [edi]
jmp_far_segment:
pop [symbol_identifier] eax
mov [value_type],al
pop eax
call mark_relocation
stos word [edi]
jmp instruction_assembled
jmp_far_32bit:
call get_dword_value
mov ebx,eax
call operand_32bit
call store_classic_instruction_code
mov eax,ebx
call mark_relocation
stos dword [edi]
jmp jmp_far_segment
conditional_jump:
mov [base_code],al
and [prefix_flags],not 10h
lods byte [esi]
call get_jump_operator
cmp [jump_type],3
je invalid_operand
call get_size_operator
cmp al,'('
jne invalid_operand
cmp byte [esi],'.'
je invalid_value
mov al,[operand_size]
cmp al,2
je conditional_jump_16bit
cmp al,4
je conditional_jump_32bit
cmp al,8
je conditional_jump_64bit
or al,al
jnz invalid_operand_size
cmp [code_type],16
je conditional_jump_16bit
cmp [code_type],64
je conditional_jump_64bit
conditional_jump_32bit:
cmp [code_type],64
je invalid_operand_size
call get_address_dword_value
cmp [code_type],16
jne conditional_jump_32bit_prefix_ok
mov byte [edi],66h
inc edi
conditional_jump_32bit_prefix_ok:
call calculate_jump_offset
cdq
call check_for_short_jump
jc conditional_jump_short
conditional_jump_32bit_store:
mov edx,eax
sub edx,4
jno conditional_jump_32bit_range_ok
cmp [code_type],64
je jump_out_of_range
conditional_jump_32bit_range_ok:
mov ah,[base_code]
add ah,10h
mov al,0Fh
stos word [edi]
mov eax,edx
call mark_relocation
stos dword [edi]
jmp instruction_assembled
conditional_jump_64bit:
cmp [code_type],64
jne invalid_operand_size
call get_address_qword_value
call calculate_jump_offset
mov ecx,edx
cdq
cmp edx,ecx
jne jump_out_of_range
call check_for_short_jump
jnc conditional_jump_32bit_store
conditional_jump_short:
mov ah,al
mov al,[base_code]
stos word [edi]
jmp instruction_assembled
conditional_jump_16bit:
call get_address_word_value
cmp [code_type],16
je conditional_jump_16bit_prefix_ok
mov byte [edi],66h
inc edi
conditional_jump_16bit_prefix_ok:
call calculate_jump_offset
cwde
cdq
call check_for_short_jump
jc conditional_jump_short
cmp [value_type],0
jne invalid_use_of_symbol
mov edx,eax
sub dx,2
mov ah,[base_code]
add ah,10h
mov al,0Fh
stos word [edi]
mov eax,edx
stos word [edi]
jmp instruction_assembled
loop_instruction_16bit:
cmp [code_type],64
je illegal_instruction
cmp [code_type],16
je loop_instruction
mov [operand_prefix],67h
jmp loop_instruction
loop_instruction_32bit:
cmp [code_type],32
je loop_instruction
mov [operand_prefix],67h
jmp loop_instruction
loop_instruction_64bit:
cmp [code_type],64
jne illegal_instruction
loop_instruction:
mov [base_code],al
lods byte [esi]
call get_jump_operator
cmp [jump_type],1
ja invalid_operand
call get_size_operator
cmp al,'('
jne invalid_operand
cmp byte [esi],'.'
je invalid_value
mov al,[operand_size]
cmp al,2
je loop_jump_16bit
cmp al,4
je loop_jump_32bit
cmp al,8
je loop_jump_64bit
or al,al
jnz invalid_operand_size
cmp [code_type],16
je loop_jump_16bit
cmp [code_type],64
je loop_jump_64bit
loop_jump_32bit:
cmp [code_type],64
je invalid_operand_size
call get_address_dword_value
cmp [code_type],16
jne loop_jump_32bit_prefix_ok
mov byte [edi],66h
inc edi
loop_jump_32bit_prefix_ok:
call loop_counter_size
call calculate_jump_offset
cdq
make_loop_jump:
call check_for_short_jump
jc conditional_jump_short
scas word [edi]
jmp jump_out_of_range
loop_counter_size:
cmp [operand_prefix],0
je loop_counter_size_ok
push eax
mov al,[operand_prefix]
stos byte [edi]
pop eax
loop_counter_size_ok:
ret
loop_jump_64bit:
cmp [code_type],64
jne invalid_operand_size
call get_address_qword_value
call loop_counter_size
call calculate_jump_offset
mov ecx,edx
cdq
cmp edx,ecx
jne jump_out_of_range
jmp make_loop_jump
loop_jump_16bit:
call get_address_word_value
cmp [code_type],16
je loop_jump_16bit_prefix_ok
mov byte [edi],66h
inc edi
loop_jump_16bit_prefix_ok:
call loop_counter_size
call calculate_jump_offset
cwde
cdq
jmp make_loop_jump
 
movs_instruction:
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
or eax,eax
jnz invalid_address
or bl,ch
jnz invalid_address
cmp [segment_register],1
ja invalid_address
push ebx
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
pop edx
or eax,eax
jnz invalid_address
or bl,ch
jnz invalid_address
mov al,dh
mov ah,bh
shr al,4
shr ah,4
cmp al,ah
jne address_sizes_do_not_agree
and bh,111b
and dh,111b
cmp bh,6
jne invalid_address
cmp dh,7
jne invalid_address
cmp al,2
je movs_address_16bit
cmp al,4
je movs_address_32bit
cmp [code_type],64
jne invalid_address_size
jmp movs_store
movs_address_32bit:
call address_32bit_prefix
jmp movs_store
movs_address_16bit:
cmp [code_type],64
je invalid_address_size
call address_16bit_prefix
movs_store:
xor ebx,ebx
call store_segment_prefix_if_necessary
mov al,0A4h
movs_check_size:
mov bl,[operand_size]
cmp bl,1
je simple_instruction
inc al
cmp bl,2
je simple_instruction_16bit
cmp bl,4
je simple_instruction_32bit
cmp bl,8
je simple_instruction_64bit
or bl,bl
jnz invalid_operand_size
call recoverable_unknown_size
jmp simple_instruction
lods_instruction:
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
or eax,eax
jnz invalid_address
or bl,ch
jnz invalid_address
cmp bh,26h
je lods_address_16bit
cmp bh,46h
je lods_address_32bit
cmp bh,86h
jne invalid_address
cmp [code_type],64
jne invalid_address_size
jmp lods_store
lods_address_32bit:
call address_32bit_prefix
jmp lods_store
lods_address_16bit:
cmp [code_type],64
je invalid_address_size
call address_16bit_prefix
lods_store:
xor ebx,ebx
call store_segment_prefix_if_necessary
mov al,0ACh
jmp movs_check_size
stos_instruction:
mov [base_code],al
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
or eax,eax
jnz invalid_address
or bl,ch
jnz invalid_address
cmp bh,27h
je stos_address_16bit
cmp bh,47h
je stos_address_32bit
cmp bh,87h
jne invalid_address
cmp [code_type],64
jne invalid_address_size
jmp stos_store
stos_address_32bit:
call address_32bit_prefix
jmp stos_store
stos_address_16bit:
cmp [code_type],64
je invalid_address_size
call address_16bit_prefix
stos_store:
cmp [segment_register],1
ja invalid_address
mov al,[base_code]
jmp movs_check_size
cmps_instruction:
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
or eax,eax
jnz invalid_address
or bl,ch
jnz invalid_address
mov al,[segment_register]
push eax ebx
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
or eax,eax
jnz invalid_address
or bl,ch
jnz invalid_address
pop edx eax
cmp [segment_register],1
ja invalid_address
mov [segment_register],al
mov al,dh
mov ah,bh
shr al,4
shr ah,4
cmp al,ah
jne address_sizes_do_not_agree
and bh,111b
and dh,111b
cmp bh,7
jne invalid_address
cmp dh,6
jne invalid_address
cmp al,2
je cmps_address_16bit
cmp al,4
je cmps_address_32bit
cmp [code_type],64
jne invalid_address_size
jmp cmps_store
cmps_address_32bit:
call address_32bit_prefix
jmp cmps_store
cmps_address_16bit:
cmp [code_type],64
je invalid_address_size
call address_16bit_prefix
cmps_store:
xor ebx,ebx
call store_segment_prefix_if_necessary
mov al,0A6h
jmp movs_check_size
ins_instruction:
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
or eax,eax
jnz invalid_address
or bl,ch
jnz invalid_address
cmp bh,27h
je ins_address_16bit
cmp bh,47h
je ins_address_32bit
cmp bh,87h
jne invalid_address
cmp [code_type],64
jne invalid_address_size
jmp ins_store
ins_address_32bit:
call address_32bit_prefix
jmp ins_store
ins_address_16bit:
cmp [code_type],64
je invalid_address_size
call address_16bit_prefix
ins_store:
cmp [segment_register],1
ja invalid_address
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
cmp al,10h
jne invalid_operand
lods byte [esi]
cmp al,22h
jne invalid_operand
mov al,6Ch
ins_check_size:
cmp [operand_size],8
jne movs_check_size
jmp invalid_operand_size
outs_instruction:
lods byte [esi]
cmp al,10h
jne invalid_operand
lods byte [esi]
cmp al,22h
jne invalid_operand
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
or eax,eax
jnz invalid_address
or bl,ch
jnz invalid_address
cmp bh,26h
je outs_address_16bit
cmp bh,46h
je outs_address_32bit
cmp bh,86h
jne invalid_address
cmp [code_type],64
jne invalid_address_size
jmp outs_store
outs_address_32bit:
call address_32bit_prefix
jmp outs_store
outs_address_16bit:
cmp [code_type],64
je invalid_address_size
call address_16bit_prefix
outs_store:
xor ebx,ebx
call store_segment_prefix_if_necessary
mov al,6Eh
jmp ins_check_size
xlat_instruction:
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
or eax,eax
jnz invalid_address
or bl,ch
jnz invalid_address
cmp bh,23h
je xlat_address_16bit
cmp bh,43h
je xlat_address_32bit
cmp bh,83h
jne invalid_address
cmp [code_type],64
jne invalid_address_size
jmp xlat_store
xlat_address_32bit:
call address_32bit_prefix
jmp xlat_store
xlat_address_16bit:
cmp [code_type],64
je invalid_address_size
call address_16bit_prefix
xlat_store:
call store_segment_prefix_if_necessary
mov al,0D7h
cmp [operand_size],1
jbe simple_instruction
jmp invalid_operand_size
 
pm_word_instruction:
mov ah,al
shr ah,4
and al,111b
mov [base_code],0Fh
mov [extended_code],ah
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,10h
je pm_reg
pm_mem:
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
cmp al,2
je pm_mem_store
or al,al
jnz invalid_operand_size
pm_mem_store:
jmp instruction_ready
pm_reg:
lods byte [esi]
call convert_register
mov bl,al
cmp ah,2
jne invalid_operand_size
jmp nomem_instruction_ready
pm_store_word_instruction:
mov ah,al
shr ah,4
and al,111b
mov [base_code],0Fh
mov [extended_code],ah
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne pm_mem
lods byte [esi]
call convert_register
mov bl,al
mov al,ah
call operand_autodetect
jmp nomem_instruction_ready
lgdt_instruction:
mov [base_code],0Fh
mov [extended_code],1
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
cmp al,6
je lgdt_mem_48bit
cmp al,10
je lgdt_mem_80bit
or al,al
jnz invalid_operand_size
jmp lgdt_mem_store
lgdt_mem_80bit:
cmp [code_type],64
jne illegal_instruction
jmp lgdt_mem_store
lgdt_mem_48bit:
cmp [code_type],64
je illegal_instruction
cmp [postbyte_register],2
jb lgdt_mem_store
call operand_32bit
lgdt_mem_store:
jmp instruction_ready
lar_instruction:
mov [extended_code],al
mov [base_code],0Fh
call take_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
xor al,al
xchg al,[operand_size]
call operand_autodetect
lods byte [esi]
call get_size_operator
cmp al,10h
je lar_reg_reg
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
or al,al
jz lar_reg_mem
cmp al,2
jne invalid_operand_size
lar_reg_mem:
jmp instruction_ready
lar_reg_reg:
lods byte [esi]
call convert_register
cmp ah,2
jne invalid_operand_size
mov bl,al
jmp nomem_instruction_ready
invlpg_instruction:
mov [base_code],0Fh
mov [extended_code],1
mov [postbyte_register],7
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
jmp instruction_ready
swapgs_instruction:
cmp [code_type],64
jne illegal_instruction
simple_instruction_0f_01:
mov ah,al
mov al,0Fh
stos byte [edi]
mov al,1
stos word [edi]
jmp instruction_assembled
 
basic_486_instruction:
mov [base_code],0Fh
mov [extended_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
je basic_486_reg
cmp al,'['
jne invalid_operand
call get_address
push edx ebx ecx
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
mov [postbyte_register],al
pop ecx ebx edx
mov al,ah
cmp al,1
je basic_486_mem_reg_8bit
call operand_autodetect
inc [extended_code]
basic_486_mem_reg_8bit:
jmp instruction_ready
basic_486_reg:
lods byte [esi]
call convert_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
mov bl,[postbyte_register]
mov [postbyte_register],al
mov al,ah
cmp al,1
je basic_486_reg_reg_8bit
call operand_autodetect
inc [extended_code]
basic_486_reg_reg_8bit:
jmp nomem_instruction_ready
bswap_instruction:
call take_register
test al,1000b
jz bswap_reg_code_ok
or [rex_prefix],41h
and al,111b
bswap_reg_code_ok:
add al,0C8h
mov [extended_code],al
mov [base_code],0Fh
cmp ah,8
je bswap_reg64
cmp ah,4
jne invalid_operand_size
call operand_32bit
call store_classic_instruction_code
jmp instruction_assembled
bswap_reg64:
call operand_64bit
call store_classic_instruction_code
jmp instruction_assembled
cmpxchgx_instruction:
mov [base_code],0Fh
mov [extended_code],0C7h
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov ah,1
xchg [postbyte_register],ah
mov al,[operand_size]
or al,al
jz cmpxchgx_size_ok
cmp al,ah
jne invalid_operand_size
cmpxchgx_size_ok:
cmp ah,16
jne cmpxchgx_store
call operand_64bit
cmpxchgx_store:
jmp instruction_ready
nop_instruction:
mov ah,[esi]
cmp ah,10h
je extended_nop
cmp ah,11h
je extended_nop
cmp ah,'['
je extended_nop
stos byte [edi]
jmp instruction_assembled
extended_nop:
mov [base_code],0Fh
mov [extended_code],1Fh
mov [postbyte_register],0
lods byte [esi]
call get_size_operator
cmp al,10h
je extended_nop_reg
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
or al,al
jz extended_nop_store
call operand_autodetect
extended_nop_store:
jmp instruction_ready
extended_nop_reg:
lods byte [esi]
call convert_register
mov bl,al
mov al,ah
call operand_autodetect
jmp nomem_instruction_ready
 
basic_fpu_instruction:
mov [postbyte_register],al
mov [base_code],0D8h
lods byte [esi]
call get_size_operator
cmp al,10h
je basic_fpu_streg
cmp al,'['
je basic_fpu_mem
dec esi
mov ah,[postbyte_register]
cmp ah,2
jb invalid_operand
cmp ah,3
ja invalid_operand
mov bl,1
jmp nomem_instruction_ready
basic_fpu_mem:
call get_address
mov al,[operand_size]
cmp al,4
je basic_fpu_mem_32bit
cmp al,8
je basic_fpu_mem_64bit
or al,al
jnz invalid_operand_size
call recoverable_unknown_size
basic_fpu_mem_32bit:
jmp instruction_ready
basic_fpu_mem_64bit:
mov [base_code],0DCh
jmp instruction_ready
basic_fpu_streg:
lods byte [esi]
call convert_fpu_register
mov bl,al
mov ah,[postbyte_register]
cmp ah,2
je basic_fpu_single_streg
cmp ah,3
je basic_fpu_single_streg
or al,al
jz basic_fpu_st0
test ah,110b
jz basic_fpu_streg_st0
xor [postbyte_register],1
basic_fpu_streg_st0:
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_fpu_register
or al,al
jnz invalid_operand
mov [base_code],0DCh
jmp nomem_instruction_ready
basic_fpu_st0:
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_fpu_register
mov bl,al
basic_fpu_single_streg:
mov [base_code],0D8h
jmp nomem_instruction_ready
simple_fpu_instruction:
mov ah,al
or ah,11000000b
mov al,0D9h
stos word [edi]
jmp instruction_assembled
fi_instruction:
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
cmp al,2
je fi_mem_16bit
cmp al,4
je fi_mem_32bit
or al,al
jnz invalid_operand_size
call recoverable_unknown_size
fi_mem_32bit:
mov [base_code],0DAh
jmp instruction_ready
fi_mem_16bit:
mov [base_code],0DEh
jmp instruction_ready
fld_instruction:
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,10h
je fld_streg
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
cmp al,4
je fld_mem_32bit
cmp al,8
je fld_mem_64bit
cmp al,10
je fld_mem_80bit
or al,al
jnz invalid_operand_size
call recoverable_unknown_size
fld_mem_32bit:
mov [base_code],0D9h
jmp instruction_ready
fld_mem_64bit:
mov [base_code],0DDh
jmp instruction_ready
fld_mem_80bit:
mov al,[postbyte_register]
cmp al,0
je fld_mem_80bit_store
dec [postbyte_register]
cmp al,3
je fld_mem_80bit_store
jmp invalid_operand_size
fld_mem_80bit_store:
add [postbyte_register],5
mov [base_code],0DBh
jmp instruction_ready
fld_streg:
lods byte [esi]
call convert_fpu_register
mov bl,al
cmp [postbyte_register],2
jae fst_streg
mov [base_code],0D9h
jmp nomem_instruction_ready
fst_streg:
mov [base_code],0DDh
jmp nomem_instruction_ready
fild_instruction:
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
cmp al,2
je fild_mem_16bit
cmp al,4
je fild_mem_32bit
cmp al,8
je fild_mem_64bit
or al,al
jnz invalid_operand_size
call recoverable_unknown_size
fild_mem_32bit:
mov [base_code],0DBh
jmp instruction_ready
fild_mem_16bit:
mov [base_code],0DFh
jmp instruction_ready
fild_mem_64bit:
mov al,[postbyte_register]
cmp al,1
je fisttp_64bit_store
jb fild_mem_64bit_store
dec [postbyte_register]
cmp al,3
je fild_mem_64bit_store
jmp invalid_operand_size
fild_mem_64bit_store:
add [postbyte_register],5
mov [base_code],0DFh
jmp instruction_ready
fisttp_64bit_store:
mov [base_code],0DDh
jmp instruction_ready
fbld_instruction:
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
or al,al
jz fbld_mem_80bit
cmp al,10
je fbld_mem_80bit
jmp invalid_operand_size
fbld_mem_80bit:
mov [base_code],0DFh
jmp instruction_ready
faddp_instruction:
mov [postbyte_register],al
mov [base_code],0DEh
mov edx,esi
lods byte [esi]
call get_size_operator
cmp al,10h
je faddp_streg
mov esi,edx
mov bl,1
jmp nomem_instruction_ready
faddp_streg:
lods byte [esi]
call convert_fpu_register
mov bl,al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_fpu_register
or al,al
jnz invalid_operand
jmp nomem_instruction_ready
fcompp_instruction:
mov ax,0D9DEh
stos word [edi]
jmp instruction_assembled
fucompp_instruction:
mov ax,0E9DAh
stos word [edi]
jmp instruction_assembled
fxch_instruction:
mov dx,01D9h
jmp fpu_single_operand
ffreep_instruction:
mov dx,00DFh
jmp fpu_single_operand
ffree_instruction:
mov dl,0DDh
mov dh,al
fpu_single_operand:
mov ebx,esi
lods byte [esi]
call get_size_operator
cmp al,10h
je fpu_streg
or dh,dh
jz invalid_operand
mov esi,ebx
shl dh,3
or dh,11000001b
mov ax,dx
stos word [edi]
jmp instruction_assembled
fpu_streg:
lods byte [esi]
call convert_fpu_register
shl dh,3
or dh,al
or dh,11000000b
mov ax,dx
stos word [edi]
jmp instruction_assembled
 
fstenv_instruction:
mov byte [edi],9Bh
inc edi
fldenv_instruction:
mov [base_code],0D9h
jmp fpu_mem
fstenv_instruction_16bit:
mov byte [edi],9Bh
inc edi
fldenv_instruction_16bit:
call operand_16bit
jmp fldenv_instruction
fstenv_instruction_32bit:
mov byte [edi],9Bh
inc edi
fldenv_instruction_32bit:
call operand_32bit
jmp fldenv_instruction
fsave_instruction_32bit:
mov byte [edi],9Bh
inc edi
fnsave_instruction_32bit:
call operand_32bit
jmp fnsave_instruction
fsave_instruction_16bit:
mov byte [edi],9Bh
inc edi
fnsave_instruction_16bit:
call operand_16bit
jmp fnsave_instruction
fsave_instruction:
mov byte [edi],9Bh
inc edi
fnsave_instruction:
mov [base_code],0DDh
fpu_mem:
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
cmp [operand_size],0
jne invalid_operand_size
jmp instruction_ready
fstcw_instruction:
mov byte [edi],9Bh
inc edi
fldcw_instruction:
mov [postbyte_register],al
mov [base_code],0D9h
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
or al,al
jz fldcw_mem_16bit
cmp al,2
je fldcw_mem_16bit
jmp invalid_operand_size
fldcw_mem_16bit:
jmp instruction_ready
fstsw_instruction:
mov al,9Bh
stos byte [edi]
fnstsw_instruction:
mov [base_code],0DDh
mov [postbyte_register],7
lods byte [esi]
call get_size_operator
cmp al,10h
je fstsw_reg
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
or al,al
jz fstsw_mem_16bit
cmp al,2
je fstsw_mem_16bit
jmp invalid_operand_size
fstsw_mem_16bit:
jmp instruction_ready
fstsw_reg:
lods byte [esi]
call convert_register
cmp ax,0200h
jne invalid_operand
mov ax,0E0DFh
stos word [edi]
jmp instruction_assembled
finit_instruction:
mov byte [edi],9Bh
inc edi
fninit_instruction:
mov ah,al
mov al,0DBh
stos word [edi]
jmp instruction_assembled
fcmov_instruction:
mov dh,0DAh
jmp fcomi_streg
fcomi_instruction:
mov dh,0DBh
jmp fcomi_streg
fcomip_instruction:
mov dh,0DFh
fcomi_streg:
mov dl,al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_fpu_register
mov ah,al
cmp byte [esi],','
je fcomi_st0_streg
add ah,dl
mov al,dh
stos word [edi]
jmp instruction_assembled
fcomi_st0_streg:
or ah,ah
jnz invalid_operand
inc esi
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_fpu_register
mov ah,al
add ah,dl
mov al,dh
stos word [edi]
jmp instruction_assembled
 
basic_mmx_instruction:
mov [base_code],0Fh
mov [extended_code],al
mmx_instruction:
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
call make_mmx_prefix
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je mmx_mmreg_mmreg
cmp al,'['
jne invalid_operand
mmx_mmreg_mem:
call get_address
jmp instruction_ready
mmx_mmreg_mmreg:
lods byte [esi]
call convert_mmx_register
mov bl,al
jmp nomem_instruction_ready
mmx_bit_shift_instruction:
mov [base_code],0Fh
mov [extended_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
call make_mmx_prefix
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,10h
je mmx_mmreg_mmreg
cmp al,'('
je mmx_ps_mmreg_imm8
cmp al,'['
je mmx_mmreg_mem
jmp invalid_operand
mmx_ps_mmreg_imm8:
call get_byte_value
mov byte [value],al
test [operand_size],not 1
jnz invalid_value
mov bl,[extended_code]
mov al,bl
shr bl,4
and al,1111b
add al,70h
mov [extended_code],al
sub bl,0Ch
shl bl,1
xchg bl,[postbyte_register]
call store_nomem_instruction
mov al,byte [value]
stos byte [edi]
jmp instruction_assembled
pmovmskb_instruction:
mov [base_code],0Fh
mov [extended_code],al
call take_register
cmp ah,4
je pmovmskb_reg_size_ok
cmp [code_type],64
jne invalid_operand_size
cmp ah,8
jnz invalid_operand_size
pmovmskb_reg_size_ok:
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
mov bl,al
call make_mmx_prefix
cmp [extended_code],0C5h
je mmx_nomem_imm8
jmp nomem_instruction_ready
mmx_imm8:
push ebx ecx edx
xor cl,cl
xchg cl,[operand_size]
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
test ah,not 1
jnz invalid_operand_size
mov [operand_size],cl
cmp al,'('
jne invalid_operand
call get_byte_value
mov byte [value],al
pop edx ecx ebx
call store_instruction_with_imm8
jmp instruction_assembled
mmx_nomem_imm8:
call store_nomem_instruction
call append_imm8
jmp instruction_assembled
append_imm8:
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
test ah,not 1
jnz invalid_operand_size
cmp al,'('
jne invalid_operand
call get_byte_value
stosb
ret
pinsrw_instruction:
mov [extended_code],al
mov [base_code],0Fh
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
call make_mmx_prefix
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je pinsrw_mmreg_reg
cmp al,'['
jne invalid_operand
call get_address
cmp [operand_size],0
je mmx_imm8
cmp [operand_size],2
jne invalid_operand_size
jmp mmx_imm8
pinsrw_mmreg_reg:
lods byte [esi]
call convert_register
cmp ah,4
jne invalid_operand_size
mov bl,al
jmp mmx_nomem_imm8
pshufw_instruction:
mov [mmx_size],8
mov [opcode_prefix],al
jmp pshuf_instruction
pshufd_instruction:
mov [mmx_size],16
mov [opcode_prefix],al
pshuf_instruction:
mov [base_code],0Fh
mov [extended_code],70h
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
cmp ah,[mmx_size]
jne invalid_operand_size
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je pshuf_mmreg_mmreg
cmp al,'['
jne invalid_operand
call get_address
jmp mmx_imm8
pshuf_mmreg_mmreg:
lods byte [esi]
call convert_mmx_register
mov bl,al
jmp mmx_nomem_imm8
movd_instruction:
mov [base_code],0Fh
mov [extended_code],7Eh
lods byte [esi]
call get_size_operator
cmp al,10h
je movd_reg
cmp al,'['
jne invalid_operand
call get_address
test [operand_size],not 4
jnz invalid_operand_size
call get_mmx_source_register
jmp instruction_ready
movd_reg:
lods byte [esi]
cmp al,0B0h
jae movd_mmreg
call convert_register
cmp ah,4
jne invalid_operand_size
mov bl,al
call get_mmx_source_register
jmp nomem_instruction_ready
movd_mmreg:
mov [extended_code],6Eh
call convert_mmx_register
mov [postbyte_register],al
call make_mmx_prefix
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je movd_mmreg_reg
cmp al,'['
jne invalid_operand
call get_address
test [operand_size],not 4
jnz invalid_operand_size
jmp instruction_ready
movd_mmreg_reg:
lods byte [esi]
call convert_register
cmp ah,4
jne invalid_operand_size
mov bl,al
jmp nomem_instruction_ready
get_mmx_source_register:
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
mov [postbyte_register],al
make_mmx_prefix:
cmp [operand_size],16
jne no_mmx_prefix
mov [operand_prefix],66h
no_mmx_prefix:
ret
movq_instruction:
mov [base_code],0Fh
lods byte [esi]
call get_size_operator
cmp al,10h
je movq_reg
cmp al,'['
jne invalid_operand
call get_address
test [operand_size],not 8
jnz invalid_operand_size
call get_mmx_source_register
mov al,7Fh
cmp ah,8
je movq_mem_ready
mov al,0D6h
movq_mem_ready:
mov [extended_code],al
jmp instruction_ready
movq_reg:
lods byte [esi]
cmp al,0B0h
jae movq_mmreg
call convert_register
cmp ah,8
jne invalid_operand_size
mov bl,al
mov [extended_code],7Eh
call operand_64bit
call get_mmx_source_register
jmp nomem_instruction_ready
movq_mmreg:
call convert_mmx_register
mov [postbyte_register],al
mov [extended_code],6Fh
mov [mmx_size],ah
cmp ah,16
jne movq_mmreg_
mov [extended_code],7Eh
mov [opcode_prefix],0F3h
movq_mmreg_:
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,10h
je movq_mmreg_reg
cmp al,'['
jne invalid_operand
call get_address
test [operand_size],not 8
jnz invalid_operand_size
jmp instruction_ready
movq_mmreg_reg:
lods byte [esi]
cmp al,0B0h
jae movq_mmreg_mmreg
mov [operand_size],0
call convert_register
cmp ah,8
jne invalid_operand_size
mov [extended_code],6Eh
mov [opcode_prefix],0
mov bl,al
cmp [mmx_size],16
jne movq_mmreg_reg_store
mov [opcode_prefix],66h
movq_mmreg_reg_store:
call operand_64bit
jmp nomem_instruction_ready
movq_mmreg_mmreg:
call convert_mmx_register
cmp ah,[mmx_size]
jne invalid_operand_size
mov bl,al
jmp nomem_instruction_ready
movdq_instruction:
mov [opcode_prefix],al
mov [base_code],0Fh
mov [extended_code],6Fh
lods byte [esi]
call get_size_operator
cmp al,10h
je movdq_mmreg
cmp al,'['
jne invalid_operand
call get_address
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
mov [extended_code],7Fh
jmp instruction_ready
movdq_mmreg:
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je movdq_mmreg_mmreg
cmp al,'['
jne invalid_operand
call get_address
jmp instruction_ready
movdq_mmreg_mmreg:
lods byte [esi]
call convert_xmm_register
mov bl,al
jmp nomem_instruction_ready
lddqu_instruction:
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
push eax
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
pop eax
mov [postbyte_register],al
mov [opcode_prefix],0F2h
mov [base_code],0Fh
mov [extended_code],0F0h
jmp instruction_ready
 
movdq2q_instruction:
mov [opcode_prefix],0F2h
mov [mmx_size],8
jmp movq2dq_
movq2dq_instruction:
mov [opcode_prefix],0F3h
mov [mmx_size],16
movq2dq_:
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
cmp ah,[mmx_size]
jne invalid_operand_size
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
xor [mmx_size],8+16
cmp ah,[mmx_size]
jne invalid_operand_size
mov bl,al
mov [base_code],0Fh
mov [extended_code],0D6h
jmp nomem_instruction_ready
 
sse_ps_instruction_imm8:
mov [immediate_size],1
sse_ps_instruction:
mov [mmx_size],16
jmp sse_instruction
sse_pd_instruction_imm8:
mov [immediate_size],1
sse_pd_instruction:
mov [mmx_size],16
mov [opcode_prefix],66h
jmp sse_instruction
sse_ss_instruction:
mov [mmx_size],4
mov [opcode_prefix],0F3h
jmp sse_instruction
sse_sd_instruction:
mov [mmx_size],8
mov [opcode_prefix],0F2h
jmp sse_instruction
cmp_pd_instruction:
mov [opcode_prefix],66h
cmp_ps_instruction:
mov [mmx_size],16
mov byte [value],al
mov al,0C2h
jmp sse_instruction
cmp_ss_instruction:
mov [mmx_size],4
mov [opcode_prefix],0F3h
jmp cmp_sx_instruction
cmpsd_instruction:
mov al,0A7h
mov ah,[esi]
or ah,ah
jz simple_instruction_32bit
cmp ah,0Fh
je simple_instruction_32bit
mov al,-1
cmp_sd_instruction:
mov [mmx_size],8
mov [opcode_prefix],0F2h
cmp_sx_instruction:
mov byte [value],al
mov al,0C2h
jmp sse_instruction
comiss_instruction:
mov [mmx_size],4
jmp sse_instruction
comisd_instruction:
mov [mmx_size],8
mov [opcode_prefix],66h
jmp sse_instruction
cvtdq2pd_instruction:
mov [opcode_prefix],0F3h
cvtps2pd_instruction:
mov [mmx_size],8
jmp sse_instruction
cvtpd2dq_instruction:
mov [mmx_size],16
mov [opcode_prefix],0F2h
jmp sse_instruction
movshdup_instruction:
mov [mmx_size],16
mov [opcode_prefix],0F3h
sse_instruction:
mov [base_code],0Fh
mov [extended_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
sse_xmmreg:
lods byte [esi]
call convert_xmm_register
sse_reg:
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je sse_xmmreg_xmmreg
sse_reg_mem:
cmp al,'['
jne invalid_operand
call get_address
cmp [operand_size],0
je sse_mem_size_ok
mov al,[mmx_size]
cmp [operand_size],al
jne invalid_operand_size
sse_mem_size_ok:
mov al,[extended_code]
mov ah,[supplemental_code]
cmp al,0C2h
je sse_cmp_mem_ok
cmp ax,443Ah
je sse_cmp_mem_ok
cmp [immediate_size],1
je mmx_imm8
cmp [immediate_size],-1
jne sse_ok
call take_additional_xmm0
mov [immediate_size],0
sse_ok:
jmp instruction_ready
sse_cmp_mem_ok:
cmp byte [value],-1
je mmx_imm8
call store_instruction_with_imm8
jmp instruction_assembled
sse_xmmreg_xmmreg:
cmp [operand_prefix],66h
jne sse_xmmreg_xmmreg_ok
cmp [extended_code],12h
je invalid_operand
cmp [extended_code],16h
je invalid_operand
sse_xmmreg_xmmreg_ok:
lods byte [esi]
call convert_xmm_register
mov bl,al
mov al,[extended_code]
mov ah,[supplemental_code]
cmp al,0C2h
je sse_cmp_nomem_ok
cmp ax,443Ah
je sse_cmp_nomem_ok
cmp [immediate_size],1
je mmx_nomem_imm8
cmp [immediate_size],-1
jne sse_nomem_ok
call take_additional_xmm0
mov [immediate_size],0
sse_nomem_ok:
jmp nomem_instruction_ready
sse_cmp_nomem_ok:
cmp byte [value],-1
je mmx_nomem_imm8
call store_nomem_instruction
mov al,byte [value]
stosb
jmp instruction_assembled
take_additional_xmm0:
cmp byte [esi],','
jne additional_xmm0_ok
inc esi
lods byte [esi]
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
test al,al
jnz invalid_operand
additional_xmm0_ok:
ret
 
pslldq_instruction:
mov [postbyte_register],al
mov [opcode_prefix],66h
mov [base_code],0Fh
mov [extended_code],73h
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov bl,al
jmp mmx_nomem_imm8
movpd_instruction:
mov [opcode_prefix],66h
movps_instruction:
mov [base_code],0Fh
mov [extended_code],al
mov [mmx_size],16
jmp sse_mov_instruction
movss_instruction:
mov [mmx_size],4
mov [opcode_prefix],0F3h
jmp sse_movs
movsd_instruction:
mov al,0A5h
mov ah,[esi]
or ah,ah
jz simple_instruction_32bit
cmp ah,0Fh
je simple_instruction_32bit
mov [mmx_size],8
mov [opcode_prefix],0F2h
sse_movs:
mov [base_code],0Fh
mov [extended_code],10h
jmp sse_mov_instruction
sse_mov_instruction:
lods byte [esi]
call get_size_operator
cmp al,10h
je sse_xmmreg
sse_mem:
cmp al,'['
jne invalid_operand
inc [extended_code]
call get_address
cmp [operand_size],0
je sse_mem_xmmreg
mov al,[mmx_size]
cmp [operand_size],al
jne invalid_operand_size
mov [operand_size],0
sse_mem_xmmreg:
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
jmp instruction_ready
movlpd_instruction:
mov [opcode_prefix],66h
movlps_instruction:
mov [base_code],0Fh
mov [extended_code],al
mov [mmx_size],8
lods byte [esi]
call get_size_operator
cmp al,10h
jne sse_mem
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
jmp sse_reg_mem
movhlps_instruction:
mov [base_code],0Fh
mov [extended_code],al
mov [mmx_size],0
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je sse_xmmreg_xmmreg_ok
jmp invalid_operand
maskmovq_instruction:
mov cl,8
jmp maskmov_instruction
maskmovdqu_instruction:
mov cl,16
mov [opcode_prefix],66h
maskmov_instruction:
mov [base_code],0Fh
mov [extended_code],0F7h
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
cmp ah,cl
jne invalid_operand_size
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
mov bl,al
jmp nomem_instruction_ready
movmskpd_instruction:
mov [opcode_prefix],66h
movmskps_instruction:
mov [base_code],0Fh
mov [extended_code],50h
call take_register
mov [postbyte_register],al
cmp ah,4
je movmskps_reg_ok
cmp ah,8
jne invalid_operand_size
cmp [code_type],64
jne invalid_operand
movmskps_reg_ok:
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je sse_xmmreg_xmmreg_ok
jmp invalid_operand
 
cvtpi2pd_instruction:
mov [opcode_prefix],66h
cvtpi2ps_instruction:
mov [base_code],0Fh
mov [extended_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je cvtpi_xmmreg_xmmreg
cmp al,'['
jne invalid_operand
call get_address
cmp [operand_size],0
je cvtpi_size_ok
cmp [operand_size],8
jne invalid_operand_size
cvtpi_size_ok:
jmp instruction_ready
cvtpi_xmmreg_xmmreg:
lods byte [esi]
call convert_mmx_register
cmp ah,8
jne invalid_operand_size
mov bl,al
jmp nomem_instruction_ready
cvtsi2ss_instruction:
mov [opcode_prefix],0F3h
jmp cvtsi_instruction
cvtsi2sd_instruction:
mov [opcode_prefix],0F2h
cvtsi_instruction:
mov [base_code],0Fh
mov [extended_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
cvtsi_xmmreg:
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je cvtsi_xmmreg_reg
cmp al,'['
jne invalid_operand
call get_address
cmp [operand_size],0
je cvtsi_size_ok
cmp [operand_size],4
je cvtsi_size_ok
cmp [operand_size],8
jne invalid_operand_size
call operand_64bit
cvtsi_size_ok:
jmp instruction_ready
cvtsi_xmmreg_reg:
lods byte [esi]
call convert_register
cmp ah,4
je cvtsi_xmmreg_reg_store
cmp ah,8
jne invalid_operand_size
call operand_64bit
cvtsi_xmmreg_reg_store:
mov bl,al
jmp nomem_instruction_ready
cvtps2pi_instruction:
mov [mmx_size],8
jmp cvtpd_instruction
cvtpd2pi_instruction:
mov [opcode_prefix],66h
mov [mmx_size],16
cvtpd_instruction:
mov [base_code],0Fh
mov [extended_code],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
cmp ah,8
jne invalid_operand_size
mov [operand_size],0
jmp sse_reg
cvtss2si_instruction:
mov [opcode_prefix],0F3h
mov [mmx_size],4
jmp cvt2si_instruction
cvtsd2si_instruction:
mov [opcode_prefix],0F2h
mov [mmx_size],8
cvt2si_instruction:
mov [extended_code],al
mov [base_code],0Fh
call take_register
mov [operand_size],0
cmp ah,4
je sse_reg
cmp ah,8
jne invalid_operand_size
call operand_64bit
jmp sse_reg
 
ssse3_instruction:
mov [base_code],0Fh
mov [extended_code],38h
mov [supplemental_code],al
jmp mmx_instruction
palignr_instruction:
mov [base_code],0Fh
mov [extended_code],3Ah
mov [supplemental_code],0Fh
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
call make_mmx_prefix
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je palignr_mmreg_mmreg
cmp al,'['
jne invalid_operand
call get_address
jmp mmx_imm8
palignr_mmreg_mmreg:
lods byte [esi]
call convert_mmx_register
mov bl,al
jmp mmx_nomem_imm8
amd3dnow_instruction:
mov [base_code],0Fh
mov [extended_code],0Fh
mov byte [value],al
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
cmp ah,8
jne invalid_operand_size
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je amd3dnow_mmreg_mmreg
cmp al,'['
jne invalid_operand
call get_address
call store_instruction_with_imm8
jmp instruction_assembled
amd3dnow_mmreg_mmreg:
lods byte [esi]
call convert_mmx_register
cmp ah,8
jne invalid_operand_size
mov bl,al
call store_nomem_instruction
mov al,byte [value]
stos byte [edi]
jmp instruction_assembled
 
sse4_instruction_38_xmm0:
mov [immediate_size],-1
jmp sse4_instruction_38
sse4_instruction_66_38_xmm0:
mov [immediate_size],-1
sse4_instruction_66_38:
mov [opcode_prefix],66h
sse4_instruction_38:
mov [mmx_size],16
mov [supplemental_code],al
mov al,38h
jmp sse_instruction
sse4_ss_instruction_66_3a_imm8:
mov [immediate_size],1
mov cl,4
jmp sse4_instruction_66_3a_setup
sse4_sd_instruction_66_3a_imm8:
mov [immediate_size],1
mov cl,8
jmp sse4_instruction_66_3a_setup
sse4_instruction_66_3a_imm8:
mov [immediate_size],1
mov cl,16
sse4_instruction_66_3a_setup:
mov [opcode_prefix],66h
sse4_instruction_3a_setup:
mov [supplemental_code],al
mov al,3Ah
mov [mmx_size],cl
jmp sse_instruction
sse4_instruction_3a_imm8:
mov [immediate_size],1
mov cl,16
jmp sse4_instruction_3a_setup
pclmulqdq_instruction:
mov byte [value],al
mov al,44h
mov cl,16
jmp sse4_instruction_66_3a_setup
extractps_instruction:
call setup_66_0f_3a
lods byte [esi]
call get_size_operator
cmp al,10h
je extractps_reg
cmp al,'['
jne invalid_operand
call get_address
cmp [operand_size],4
je extractps_size_ok
cmp [operand_size],0
jne invalid_operand_size
extractps_size_ok:
push edx ebx ecx
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
pop ecx ebx edx
jmp mmx_imm8
extractps_reg:
lods byte [esi]
call convert_register
push eax
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
pop ebx
mov al,bh
cmp al,4
je mmx_nomem_imm8
cmp al,8
jne invalid_operand_size
cmp [code_type],64
jne illegal_instruction
jmp mmx_nomem_imm8
setup_66_0f_3a:
mov [extended_code],3Ah
mov [supplemental_code],al
mov [base_code],0Fh
mov [opcode_prefix],66h
ret
insertps_instruction:
call setup_66_0f_3a
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je insertps_xmmreg_reg
cmp al,'['
jne invalid_operand
call get_address
cmp [operand_size],4
je insertps_size_ok
cmp [operand_size],0
jne invalid_operand_size
insertps_size_ok:
jmp mmx_imm8
insertps_xmmreg_reg:
lods byte [esi]
call convert_mmx_register
mov bl,al
jmp mmx_nomem_imm8
pextrq_instruction:
mov [mmx_size],8
jmp pextr_instruction
pextrd_instruction:
mov [mmx_size],4
jmp pextr_instruction
pextrw_instruction:
mov [mmx_size],2
jmp pextr_instruction
pextrb_instruction:
mov [mmx_size],1
pextr_instruction:
call setup_66_0f_3a
lods byte [esi]
call get_size_operator
cmp al,10h
je pextr_reg
cmp al,'['
jne invalid_operand
call get_address
mov al,[mmx_size]
cmp al,[operand_size]
je pextr_size_ok
cmp [operand_size],0
jne invalid_operand_size
pextr_size_ok:
cmp al,8
jne pextr_prefix_ok
call operand_64bit
pextr_prefix_ok:
push edx ebx ecx
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
pop ecx ebx edx
jmp mmx_imm8
pextr_reg:
lods byte [esi]
call convert_register
cmp [mmx_size],4
ja pextrq_reg
cmp ah,4
je pextr_reg_size_ok
cmp [code_type],64
jne pextr_invalid_size
cmp ah,8
je pextr_reg_size_ok
pextr_invalid_size:
jmp invalid_operand_size
pextrq_reg:
cmp ah,8
jne pextr_invalid_size
call operand_64bit
pextr_reg_size_ok:
mov [operand_size],0
push eax
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
mov ebx,eax
pop eax
mov [postbyte_register],al
mov al,ah
cmp [mmx_size],2
jne pextr_reg_store
mov [opcode_prefix],0
mov [extended_code],0C5h
call make_mmx_prefix
jmp mmx_nomem_imm8
pextr_reg_store:
cmp bh,16
jne invalid_operand_size
xchg bl,[postbyte_register]
jmp mmx_nomem_imm8
pinsrb_instruction:
mov [mmx_size],1
jmp pinsr_instruction
pinsrd_instruction:
mov [mmx_size],4
jmp pinsr_instruction
pinsrq_instruction:
mov [mmx_size],8
call operand_64bit
pinsr_instruction:
call setup_66_0f_3a
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
pinsr_xmmreg:
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je pinsr_xmmreg_reg
cmp al,'['
jne invalid_operand
call get_address
cmp [operand_size],0
je mmx_imm8
mov al,[mmx_size]
cmp al,[operand_size]
je mmx_imm8
jmp invalid_operand_size
pinsr_xmmreg_reg:
lods byte [esi]
call convert_register
mov bl,al
cmp [mmx_size],8
je pinsrq_xmmreg_reg
cmp ah,4
je mmx_nomem_imm8
jmp invalid_operand_size
pinsrq_xmmreg_reg:
cmp ah,8
je mmx_nomem_imm8
jmp invalid_operand_size
pmovsxbw_instruction:
mov [mmx_size],8
jmp pmovsx_instruction
pmovsxbd_instruction:
mov [mmx_size],4
jmp pmovsx_instruction
pmovsxbq_instruction:
mov [mmx_size],2
jmp pmovsx_instruction
pmovsxwd_instruction:
mov [mmx_size],8
jmp pmovsx_instruction
pmovsxwq_instruction:
mov [mmx_size],4
jmp pmovsx_instruction
pmovsxdq_instruction:
mov [mmx_size],8
pmovsx_instruction:
call setup_66_0f_38
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,10h
je pmovsx_xmmreg_reg
cmp al,'['
jne invalid_operand
call get_address
cmp [operand_size],0
je instruction_ready
mov al,[mmx_size]
cmp al,[operand_size]
jne invalid_operand_size
jmp instruction_ready
pmovsx_xmmreg_reg:
lods byte [esi]
call convert_xmm_register
mov bl,al
jmp nomem_instruction_ready
setup_66_0f_38:
mov [extended_code],38h
mov [supplemental_code],al
mov [base_code],0Fh
mov [opcode_prefix],66h
ret
 
fxsave_instruction_64bit:
call operand_64bit
fxsave_instruction:
mov [extended_code],0AEh
mov [base_code],0Fh
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov ah,[operand_size]
or ah,ah
jz fxsave_size_ok
mov al,[postbyte_register]
cmp al,111b
je clflush_size_check
cmp al,10b
jb invalid_operand_size
cmp al,11b
ja invalid_operand_size
cmp ah,4
jne invalid_operand_size
jmp fxsave_size_ok
clflush_size_check:
cmp ah,1
jne invalid_operand_size
fxsave_size_ok:
jmp instruction_ready
prefetch_instruction:
mov [extended_code],18h
prefetch_mem_8bit:
mov [base_code],0Fh
mov [postbyte_register],al
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
or ah,ah
jz prefetch_size_ok
cmp ah,1
jne invalid_operand_size
prefetch_size_ok:
call get_address
jmp instruction_ready
amd_prefetch_instruction:
mov [extended_code],0Dh
jmp prefetch_mem_8bit
clflushopt_instruction:
mov [extended_code],0AEh
mov [opcode_prefix],66h
jmp prefetch_mem_8bit
pcommit_instruction:
mov byte [edi],66h
inc edi
fence_instruction:
mov bl,al
mov ax,0AE0Fh
stos word [edi]
mov al,bl
stos byte [edi]
jmp instruction_assembled
pause_instruction:
mov ax,90F3h
stos word [edi]
jmp instruction_assembled
movntq_instruction:
mov [mmx_size],8
jmp movnt_instruction
movntpd_instruction:
mov [opcode_prefix],66h
movntps_instruction:
mov [mmx_size],16
movnt_instruction:
mov [extended_code],al
mov [base_code],0Fh
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_mmx_register
cmp ah,[mmx_size]
jne invalid_operand_size
mov [postbyte_register],al
jmp instruction_ready
 
movntsd_instruction:
mov [opcode_prefix],0F2h
mov [mmx_size],8
jmp movnts_instruction
movntss_instruction:
mov [opcode_prefix],0F3h
mov [mmx_size],4
movnts_instruction:
mov [extended_code],al
mov [base_code],0Fh
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
cmp al,[mmx_size]
je movnts_size_ok
test al,al
jnz invalid_operand_size
movnts_size_ok:
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
jmp instruction_ready
 
movnti_instruction:
mov [base_code],0Fh
mov [extended_code],al
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
cmp ah,4
je movnti_store
cmp ah,8
jne invalid_operand_size
call operand_64bit
movnti_store:
mov [postbyte_register],al
jmp instruction_ready
monitor_instruction:
mov [postbyte_register],al
cmp byte [esi],0
je monitor_instruction_store
cmp byte [esi],0Fh
je monitor_instruction_store
call take_register
cmp ax,0400h
jne invalid_operand
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
cmp ax,0401h
jne invalid_operand
cmp [postbyte_register],0C8h
jne monitor_instruction_store
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
cmp ax,0402h
jne invalid_operand
monitor_instruction_store:
mov ax,010Fh
stos word [edi]
mov al,[postbyte_register]
stos byte [edi]
jmp instruction_assembled
movntdqa_instruction:
call setup_66_0f_38
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
jmp instruction_ready
 
extrq_instruction:
mov [opcode_prefix],66h
mov [base_code],0Fh
mov [extended_code],78h
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je extrq_xmmreg_xmmreg
test ah,not 1
jnz invalid_operand_size
cmp al,'('
jne invalid_operand
xor bl,bl
xchg bl,[postbyte_register]
call store_nomem_instruction
call get_byte_value
stosb
call append_imm8
jmp instruction_assembled
extrq_xmmreg_xmmreg:
inc [extended_code]
lods byte [esi]
call convert_xmm_register
mov bl,al
jmp nomem_instruction_ready
insertq_instruction:
mov [opcode_prefix],0F2h
mov [base_code],0Fh
mov [extended_code],78h
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov [postbyte_register],al
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_xmm_register
mov bl,al
cmp byte [esi],','
je insertq_with_imm
inc [extended_code]
jmp nomem_instruction_ready
insertq_with_imm:
call store_nomem_instruction
call append_imm8
call append_imm8
jmp instruction_assembled
 
crc32_instruction:
mov [opcode_prefix],0F2h
mov [base_code],0Fh
mov [extended_code],38h
mov [supplemental_code],0F0h
call take_register
mov [postbyte_register],al
cmp ah,4
je crc32_reg_size_ok
cmp ah,8
jne invalid_operand
cmp [code_type],64
jne illegal_instruction
crc32_reg_size_ok:
lods byte [esi]
cmp al,','
jne invalid_operand
mov [operand_size],0
lods byte [esi]
call get_size_operator
cmp al,10h
je crc32_reg_reg
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
test al,al
jz crc32_unknown_size
cmp al,1
je crc32_reg_mem_store
inc [supplemental_code]
call operand_autodetect
crc32_reg_mem_store:
jmp instruction_ready
crc32_unknown_size:
call recoverable_unknown_size
jmp crc32_reg_mem_store
crc32_reg_reg:
lods byte [esi]
call convert_register
mov bl,al
mov al,ah
cmp al,1
je crc32_reg_reg_store
inc [supplemental_code]
call operand_autodetect
crc32_reg_reg_store:
jmp nomem_instruction_ready
popcnt_instruction:
mov [opcode_prefix],0F3h
jmp bs_instruction
movbe_instruction:
mov [supplemental_code],al
mov [extended_code],38h
mov [base_code],0Fh
lods byte [esi]
call get_size_operator
cmp al,'['
je movbe_mem
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_argument
call get_address
mov al,[operand_size]
call operand_autodetect
jmp instruction_ready
movbe_mem:
inc [supplemental_code]
call get_address
push edx ebx ecx
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
mov [postbyte_register],al
pop ecx ebx edx
mov al,[operand_size]
call operand_autodetect
jmp instruction_ready
adx_instruction:
mov [base_code],0Fh
mov [extended_code],38h
mov [supplemental_code],0F6h
mov [operand_prefix],al
call get_reg_mem
jc adx_reg_reg
mov al,[operand_size]
cmp al,4
je instruction_ready
cmp al,8
jne invalid_operand_size
call operand_64bit
jmp instruction_ready
adx_reg_reg:
cmp ah,4
je nomem_instruction_ready
cmp ah,8
jne invalid_operand_size
call operand_64bit
jmp nomem_instruction_ready
 
vmclear_instruction:
mov [opcode_prefix],66h
jmp vmx_instruction
vmxon_instruction:
mov [opcode_prefix],0F3h
vmx_instruction:
mov [postbyte_register],al
mov [extended_code],0C7h
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
or al,al
jz vmx_size_ok
cmp al,8
jne invalid_operand_size
vmx_size_ok:
mov [base_code],0Fh
jmp instruction_ready
vmread_instruction:
mov [extended_code],78h
lods byte [esi]
call get_size_operator
cmp al,10h
je vmread_nomem
cmp al,'['
jne invalid_operand
call get_address
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
mov [postbyte_register],al
call vmread_check_size
jmp vmx_size_ok
vmread_nomem:
lods byte [esi]
call convert_register
push eax
call vmread_check_size
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
mov [postbyte_register],al
call vmread_check_size
pop ebx
mov [base_code],0Fh
jmp nomem_instruction_ready
vmread_check_size:
cmp [code_type],64
je vmread_long
cmp [operand_size],4
jne invalid_operand_size
ret
vmread_long:
cmp [operand_size],8
jne invalid_operand_size
ret
vmwrite_instruction:
mov [extended_code],79h
call take_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,10h
je vmwrite_nomem
cmp al,'['
jne invalid_operand
call get_address
call vmread_check_size
jmp vmx_size_ok
vmwrite_nomem:
lods byte [esi]
call convert_register
mov bl,al
mov [base_code],0Fh
jmp nomem_instruction_ready
vmx_inv_instruction:
call setup_66_0f_38
call take_register
mov [postbyte_register],al
call vmread_check_size
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address
mov al,[operand_size]
or al,al
jz vmx_size_ok
cmp al,16
jne invalid_operand_size
jmp vmx_size_ok
simple_svm_instruction:
push eax
mov [base_code],0Fh
mov [extended_code],1
call take_register
or al,al
jnz invalid_operand
simple_svm_detect_size:
cmp ah,2
je simple_svm_16bit
cmp ah,4
je simple_svm_32bit
cmp [code_type],64
jne invalid_operand_size
jmp simple_svm_store
simple_svm_16bit:
cmp [code_type],16
je simple_svm_store
cmp [code_type],64
je invalid_operand_size
jmp prefixed_svm_store
simple_svm_32bit:
cmp [code_type],32
je simple_svm_store
prefixed_svm_store:
mov al,67h
stos byte [edi]
simple_svm_store:
call store_classic_instruction_code
pop eax
stos byte [edi]
jmp instruction_assembled
skinit_instruction:
call take_register
cmp ax,0400h
jne invalid_operand
mov al,0DEh
jmp simple_instruction_0f_01
invlpga_instruction:
push eax
mov [base_code],0Fh
mov [extended_code],1
call take_register
or al,al
jnz invalid_operand
mov bl,ah
mov [operand_size],0
lods byte [esi]
cmp al,','
jne invalid_operand
call take_register
cmp ax,0401h
jne invalid_operand
mov ah,bl
jmp simple_svm_detect_size
 
rdrand_instruction:
mov [base_code],0Fh
mov [extended_code],0C7h
mov [postbyte_register],al
call take_register
mov bl,al
mov al,ah
call operand_autodetect
jmp nomem_instruction_ready
rdfsbase_instruction:
cmp [code_type],64
jne illegal_instruction
mov [opcode_prefix],0F3h
mov [base_code],0Fh
mov [extended_code],0AEh
mov [postbyte_register],al
call take_register
mov bl,al
mov al,ah
cmp ah,2
je invalid_operand_size
call operand_autodetect
jmp nomem_instruction_ready
 
xabort_instruction:
lods byte [esi]
call get_size_operator
cmp ah,1
ja invalid_operand_size
cmp al,'('
jne invalid_operand
call get_byte_value
mov dl,al
mov ax,0F8C6h
stos word [edi]
mov al,dl
stos byte [edi]
jmp instruction_assembled
xbegin_instruction:
lods byte [esi]
cmp al,'('
jne invalid_operand
mov al,[code_type]
cmp al,64
je xbegin_64bit
cmp al,32
je xbegin_32bit
xbegin_16bit:
call get_address_word_value
add edi,4
mov ebp,[addressing_space]
call calculate_relative_offset
sub edi,4
shl eax,16
mov ax,0F8C7h
stos dword [edi]
jmp instruction_assembled
xbegin_32bit:
call get_address_dword_value
jmp xbegin_address_ok
xbegin_64bit:
call get_address_qword_value
xbegin_address_ok:
add edi,5
mov ebp,[addressing_space]
call calculate_relative_offset
sub edi,5
mov edx,eax
cwde
cmp eax,edx
jne xbegin_rel32
mov al,66h
stos byte [edi]
mov eax,edx
shl eax,16
mov ax,0F8C7h
stos dword [edi]
jmp instruction_assembled
xbegin_rel32:
sub edx,1
jno xbegin_rel32_ok
cmp [code_type],64
je jump_out_of_range
xbegin_rel32_ok:
mov ax,0F8C7h
stos word [edi]
mov eax,edx
stos dword [edi]
jmp instruction_assembled
 
bndcl_instruction:
mov ah,0F3h
jmp bndc_instruction
bndcu_instruction:
mov ah,0F2h
bndc_instruction:
mov [opcode_prefix],ah
mov [base_code],0Fh
mov [extended_code],al
call take_bnd_register
mov [postbyte_register],al
call get_bnd_size
mov [operand_size],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
je bndc_mem
cmp al,10h
jne invalid_operand
lods byte [esi]
call convert_register
mov bl,al
jmp nomem_instruction_ready
bndc_mem:
call get_address_of_required_size
jmp instruction_ready
bndmov_instruction:
mov [opcode_prefix],66h
mov [base_code],0Fh
mov [extended_code],al
call get_bnd_size
shl al,1
mov [operand_size],al
lods byte [esi]
cmp al,14h
je bndmov_reg
call get_size_operator
cmp al,'['
jne invalid_operand
inc [extended_code]
call get_address_of_required_size
lods byte [esi]
cmp al,','
jne invalid_operand
call take_bnd_register
mov [postbyte_register],al
jmp instruction_ready
bndmov_reg:
lods byte [esi]
call convert_bnd_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
cmp al,14h
je bndmov_reg_reg
call get_size_operator
cmp al,'['
jne invalid_operand
call get_address_of_required_size
jmp instruction_ready
bndmov_reg_reg:
lods byte [esi]
call convert_bnd_register
mov bl,al
jmp nomem_instruction_ready
take_bnd_register:
lods byte [esi]
cmp al,14h
jne invalid_operand
lods byte [esi]
convert_bnd_register:
mov ah,al
shr ah,4
cmp ah,6
jne invalid_operand
and al,1111b
ret
bndmk_instruction:
mov [opcode_prefix],0F3h
mov [base_code],0Fh
mov [extended_code],al
call take_bnd_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
call get_size_operator
cmp al,'['
jne invalid_operand
call get_bnd_size
call get_address_prefixes
call get_address_component
cmp byte [esi-1],']'
je bndmk_ready
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
cmp al,'('
jne invalid_operand
or dl,bl
or dl,[address_sign]
or edx,[address_high]
jnz invalid_address
mov [address_register],bh
call get_address_component
lods byte [esi]
cmp al,']'
jne invalid_operand
or bh,bh
jz bndmk_selected_base
cmp bl,bh
je bndmk_to_index
or bl,bl
jnz invalid_address
mov bl,bh
bndmk_to_index:
inc cl
bndmk_selected_base:
mov bh,[address_register]
bndmk_ready:
or bx,bx
jz instruction_ready
cmp [address_size_declared],0
jne instruction_ready
and ch,not 0Fh
jmp instruction_ready
get_bnd_size:
mov al,4
cmp [code_type],64
jne bnd_size_ok
add al,4
bnd_size_ok:
mov [address_size],al
ret
get_address_component:
mov [free_address_range],0
call calculate_address
mov [address_high],edx
mov edx,eax
or bx,bx
jz address_component_ok
mov al,bl
or al,bh
shr al,4
cmp al,[address_size]
jne invalid_address
address_component_ok:
ret
bndldx_instruction:
mov [base_code],0Fh
mov [extended_code],al
call take_bnd_register
mov [postbyte_register],al
lods byte [esi]
cmp al,','
jne invalid_operand
call take_bnd_mib
jmp bndmk_ready
bndstx_instruction:
mov [base_code],0Fh
mov [extended_code],al
call take_bnd_mib
lods byte [esi]
cmp al,','
jne invalid_operand
call take_bnd_register
mov [postbyte_register],al
jmp bndmk_ready
take_bnd_mib:
lods byte [esi]
cmp al,'['
jne invalid_operand
call get_bnd_size
call get_address_prefixes
call get_address_component
cmp byte [esi-1],']'
je bnd_mib_ok
lods byte [esi]
cmp al,','
jne invalid_operand
lods byte [esi]
cmp al,'('
jne invalid_operand
mov al,[address_sign]
push eax ebx ecx edx [address_symbol]
call get_address_component
lods byte [esi]
cmp al,']'
jne invalid_operand
or dl,bl
or dl,[address_sign]
or edx,[address_high]
jnz invalid_address
mov [address_register],bh
pop [address_symbol] edx ecx ebx eax
mov [address_sign],al
or bl,bl
jz mib_place_index
or bh,bh
jnz invalid_address
cmp cl,1
jne invalid_address
mov bh,bl
mib_place_index:
mov bl,[address_register]
xor cl,cl
or al,al
jz bnd_mib_ok
inc cl
bnd_mib_ok:
ret
 
take_register:
lods byte [esi]
call get_size_operator
cmp al,10h
jne invalid_operand
lods byte [esi]
convert_register:
mov ah,al
shr ah,4
and al,0Fh
cmp ah,8
je match_register_size
cmp ah,4
ja invalid_operand
cmp ah,1
ja match_register_size
cmp al,4
jb match_register_size
or ah,ah
jz high_byte_register
or [rex_prefix],40h
match_register_size:
cmp ah,[operand_size]
je register_size_ok
cmp [operand_size],0
jne operand_sizes_do_not_match
mov [operand_size],ah
register_size_ok:
ret
high_byte_register:
mov ah,1
or [rex_prefix],10h
jmp match_register_size
convert_fpu_register:
mov ah,al
shr ah,4
and al,111b
cmp ah,10
jne invalid_operand
jmp match_register_size
convert_mmx_register:
mov ah,al
shr ah,4
cmp ah,0Ch
je xmm_register
ja invalid_operand
and al,111b
cmp ah,0Bh
jne invalid_operand
mov ah,8
jmp match_register_size
xmm_register:
and al,0Fh
mov ah,16
cmp al,8
jb match_register_size
cmp [code_type],64
jne invalid_operand
jmp match_register_size
convert_xmm_register:
mov ah,al
shr ah,4
cmp ah,0Ch
je xmm_register
jmp invalid_operand
get_size_operator:
xor ah,ah
cmp al,11h
jne no_size_operator
mov [size_declared],1
lods word [esi]
xchg al,ah
or [operand_flags],1
cmp ah,[operand_size]
je size_operator_ok
cmp [operand_size],0
jne operand_sizes_do_not_match
mov [operand_size],ah
size_operator_ok:
ret
no_size_operator:
mov [size_declared],0
cmp al,'['
jne size_operator_ok
and [operand_flags],not 1
ret
get_jump_operator:
mov [jump_type],0
cmp al,12h
jne jump_operator_ok
lods word [esi]
mov [jump_type],al
mov al,ah
jump_operator_ok:
ret
get_address:
and [address_size],0
get_address_of_required_size:
call get_address_prefixes
and [free_address_range],0
call calculate_address
cmp byte [esi-1],']'
jne invalid_address
mov [address_high],edx
mov edx,eax
cmp [address_size_declared],0
jne address_ok
or bx,bx
jnz clear_address_size
cmp [code_type],64
jne address_ok
calculate_relative_address:
mov edx,[address_symbol]
mov [symbol_identifier],edx
mov edx,[address_high]
mov ebp,[addressing_space]
call calculate_relative_offset
mov [address_high],edx
cdq
cmp edx,[address_high]
je address_high_ok
call recoverable_overflow
address_high_ok:
mov edx,eax
ror ecx,16
mov cl,[value_type]
rol ecx,16
mov bx,9900h
clear_address_size:
and ch,not 0Fh
address_ok:
ret
get_address_prefixes:
and [segment_register],0
and [address_size_declared],0
mov al,[code_type]
shr al,3
mov [value_size],al
mov al,[esi]
and al,11110000b
cmp al,60h
jne get_address_size_prefix
lods byte [esi]
sub al,60h
mov [segment_register],al
mov al,[esi]
and al,11110000b
get_address_size_prefix:
cmp al,70h
jne address_size_prefix_ok
lods byte [esi]
sub al,70h
cmp al,2
jb invalid_address_size
cmp al,8
ja invalid_address_size
mov [value_size],al
or [address_size_declared],1
or [address_size],al
cmp al,[address_size]
jne invalid_address_size
address_size_prefix_ok:
ret
operand_16bit:
cmp [code_type],16
je size_prefix_ok
mov [operand_prefix],66h
ret
operand_32bit:
cmp [code_type],16
jne size_prefix_ok
mov [operand_prefix],66h
size_prefix_ok:
ret
operand_64bit:
cmp [code_type],64
jne illegal_instruction
or [rex_prefix],48h
ret
operand_autodetect:
cmp al,2
je operand_16bit
cmp al,4
je operand_32bit
cmp al,8
je operand_64bit
jmp invalid_operand_size
store_segment_prefix_if_necessary:
mov al,[segment_register]
or al,al
jz segment_prefix_ok
cmp al,4
ja segment_prefix_386
cmp [code_type],64
je segment_prefix_ok
cmp al,3
je ss_prefix
jb segment_prefix_86
cmp bl,25h
je segment_prefix_86
cmp bh,25h
je segment_prefix_86
cmp bh,45h
je segment_prefix_86
cmp bh,44h
je segment_prefix_86
ret
ss_prefix:
cmp bl,25h
je segment_prefix_ok
cmp bh,25h
je segment_prefix_ok
cmp bh,45h
je segment_prefix_ok
cmp bh,44h
je segment_prefix_ok
jmp segment_prefix_86
store_segment_prefix:
mov al,[segment_register]
or al,al
jz segment_prefix_ok
cmp al,5
jae segment_prefix_386
segment_prefix_86:
dec al
shl al,3
add al,26h
stos byte [edi]
jmp segment_prefix_ok
segment_prefix_386:
add al,64h-5
stos byte [edi]
segment_prefix_ok:
ret
store_instruction_code:
cmp [vex_required],0
jne store_vex_instruction_code
store_classic_instruction_code:
mov al,[operand_prefix]
or al,al
jz operand_prefix_ok
stos byte [edi]
operand_prefix_ok:
mov al,[opcode_prefix]
or al,al
jz opcode_prefix_ok
stos byte [edi]
opcode_prefix_ok:
mov al,[rex_prefix]
test al,40h
jz rex_prefix_ok
cmp [code_type],64
jne invalid_operand
test al,0B0h
jnz disallowed_combination_of_registers
stos byte [edi]
rex_prefix_ok:
mov al,[base_code]
stos byte [edi]
cmp al,0Fh
jne instruction_code_ok
store_extended_code:
mov al,[extended_code]
stos byte [edi]
cmp al,38h
je store_supplemental_code
cmp al,3Ah
je store_supplemental_code
instruction_code_ok:
ret
store_supplemental_code:
mov al,[supplemental_code]
stos byte [edi]
ret
store_nomem_instruction:
test [postbyte_register],10000b
jz nomem_reg_high_code_ok
or [vex_required],10h
and [postbyte_register],1111b
nomem_reg_high_code_ok:
test [postbyte_register],1000b
jz nomem_reg_code_ok
or [rex_prefix],44h
and [postbyte_register],111b
nomem_reg_code_ok:
test bl,10000b
jz nomem_rm_high_code_ok
or [rex_prefix],42h
or [vex_required],8
and bl,1111b
nomem_rm_high_code_ok:
test bl,1000b
jz nomem_rm_code_ok
or [rex_prefix],41h
and bl,111b
nomem_rm_code_ok:
and [displacement_compression],0
call store_instruction_code
mov al,[postbyte_register]
shl al,3
or al,bl
or al,11000000b
stos byte [edi]
ret
store_instruction:
mov [current_offset],edi
and [displacement_compression],0
test [postbyte_register],10000b
jz reg_high_code_ok
or [vex_required],10h
and [postbyte_register],1111b
reg_high_code_ok:
test [postbyte_register],1000b
jz reg_code_ok
or [rex_prefix],44h
and [postbyte_register],111b
reg_code_ok:
cmp [code_type],64
jne address_value_ok
xor eax,eax
bt edx,31
sbb eax,[address_high]
jz address_value_ok
cmp [address_high],0
jne address_value_out_of_range
test ch,44h
jnz address_value_ok
test bx,8080h
jz address_value_ok
address_value_out_of_range:
call recoverable_overflow
address_value_ok:
call store_segment_prefix_if_necessary
test [vex_required],4
jnz address_vsib
or bx,bx
jz address_immediate
cmp bx,9800h
je address_rip_based
cmp bx,9400h
je address_eip_based
cmp bx,9900h
je address_relative
mov al,bl
or al,bh
and al,11110000b
cmp al,80h
je postbyte_64bit
cmp al,40h
je postbyte_32bit
cmp al,20h
jne invalid_address
cmp [code_type],64
je invalid_address_size
call address_16bit_prefix
test ch,22h
setz [displacement_compression]
call store_instruction_code
cmp bl,bh
jbe determine_16bit_address
xchg bl,bh
determine_16bit_address:
cmp bx,2600h
je address_si
cmp bx,2700h
je address_di
cmp bx,2300h
je address_bx
cmp bx,2500h
je address_bp
cmp bx,2625h
je address_bp_si
cmp bx,2725h
je address_bp_di
cmp bx,2723h
je address_bx_di
cmp bx,2623h
jne invalid_address
address_bx_si:
xor al,al
jmp postbyte_16bit
address_bx_di:
mov al,1
jmp postbyte_16bit
address_bp_si:
mov al,10b
jmp postbyte_16bit
address_bp_di:
mov al,11b
jmp postbyte_16bit
address_si:
mov al,100b
jmp postbyte_16bit
address_di:
mov al,101b
jmp postbyte_16bit
address_bx:
mov al,111b
jmp postbyte_16bit
address_bp:
mov al,110b
postbyte_16bit:
test ch,22h
jnz address_16bit_value
or ch,ch
jnz address_sizes_do_not_agree
cmp edx,10000h
jge value_out_of_range
cmp edx,-8000h
jl value_out_of_range
or dx,dx
jz address
cmp [displacement_compression],2
ja address_8bit_value
je address_16bit_value
cmp dx,80h
jb address_8bit_value
cmp dx,-80h
jae address_8bit_value
address_16bit_value:
or al,10000000b
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos byte [edi]
mov eax,edx
stos word [edi]
ret
address_8bit_value:
or al,01000000b
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos byte [edi]
mov al,dl
stos byte [edi]
ret
address:
cmp al,110b
je address_8bit_value
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos byte [edi]
ret
address_vsib:
mov al,bl
shr al,4
test al,1
jz vsib_high_code_ok
or [vex_register],10000b
or [vex_required],8
xor al,1
vsib_high_code_ok:
cmp al,6
je vsib_index_ok
cmp al,0Ch
jb invalid_address
vsib_index_ok:
mov al,bh
shr al,4
cmp al,4
je postbyte_32bit
cmp [code_type],64
je address_prefix_ok
test al,al
jnz invalid_address
postbyte_32bit:
call address_32bit_prefix
jmp address_prefix_ok
postbyte_64bit:
cmp [code_type],64
jne invalid_address_size
address_prefix_ok:
cmp bl,44h
je invalid_address
cmp bl,84h
je invalid_address
test bh,1000b
jz base_code_ok
or [rex_prefix],41h
base_code_ok:
test bl,1000b
jz index_code_ok
or [rex_prefix],42h
index_code_ok:
test ch,44h or 88h
setz [displacement_compression]
call store_instruction_code
or cl,cl
jz only_base_register
base_and_index:
mov al,100b
xor ah,ah
cmp cl,1
je scale_ok
cmp cl,2
je scale_1
cmp cl,4
je scale_2
or ah,11000000b
jmp scale_ok
scale_2:
or ah,10000000b
jmp scale_ok
scale_1:
or ah,01000000b
scale_ok:
or bh,bh
jz only_index_register
and bl,111b
shl bl,3
or ah,bl
and bh,111b
or ah,bh
sib_ready:
test ch,44h or 88h
jnz sib_address_32bit_value
or ch,ch
jnz address_sizes_do_not_agree
cmp bh,5
je address_value
or edx,edx
jz sib_address
address_value:
cmp [displacement_compression],2
ja sib_address_8bit_value
je sib_address_32bit_value
cmp edx,80h
jb sib_address_8bit_value
cmp edx,-80h
jnb sib_address_8bit_value
sib_address_32bit_value:
or al,10000000b
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos word [edi]
jmp store_address_32bit_value
sib_address_8bit_value:
or al,01000000b
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos word [edi]
mov al,dl
stos byte [edi]
ret
sib_address:
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos word [edi]
ret
only_index_register:
or ah,101b
and bl,111b
shl bl,3
or ah,bl
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos word [edi]
test ch,44h or 88h
jnz store_address_32bit_value
or ch,ch
jnz invalid_address_size
cmp [displacement_compression],2
jbe store_address_32bit_value
mov edx,[uncompressed_displacement]
jmp store_address_32bit_value
zero_index_register:
mov bl,4
mov cl,1
jmp base_and_index
only_base_register:
mov al,bh
and al,111b
cmp al,4
je zero_index_register
test ch,44h or 88h
jnz simple_address_32bit_value
or ch,ch
jnz address_sizes_do_not_agree
or edx,edx
jz simple_address
cmp [displacement_compression],2
ja simple_address_8bit_value
je simple_address_32bit_value
cmp edx,80h
jb simple_address_8bit_value
cmp edx,-80h
jnb simple_address_8bit_value
simple_address_32bit_value:
or al,10000000b
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos byte [edi]
jmp store_address_32bit_value
simple_address_8bit_value:
or al,01000000b
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos byte [edi]
mov al,dl
stos byte [edi]
ret
simple_address:
cmp al,5
je simple_address_8bit_value
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos byte [edi]
ret
address_immediate:
cmp [code_type],64
je address_immediate_sib
test ch,44h or 88h
jnz address_immediate_32bit
test ch,22h
jnz address_immediate_16bit
or ch,ch
jnz invalid_address_size
cmp [code_type],16
je addressing_16bit
address_immediate_32bit:
call address_32bit_prefix
call store_instruction_code
store_immediate_address:
mov al,101b
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos byte [edi]
store_address_32bit_value:
test ch,0F0h
jz address_32bit_relocation_ok
mov eax,ecx
shr eax,16
cmp al,4
jne address_32bit_relocation
mov al,2
address_32bit_relocation:
xchg [value_type],al
mov ebx,[address_symbol]
xchg ebx,[symbol_identifier]
call mark_relocation
mov [value_type],al
mov [symbol_identifier],ebx
address_32bit_relocation_ok:
mov eax,edx
stos dword [edi]
ret
store_address_64bit_value:
test ch,0F0h
jz address_64bit_relocation_ok
mov eax,ecx
shr eax,16
xchg [value_type],al
mov ebx,[address_symbol]
xchg ebx,[symbol_identifier]
call mark_relocation
mov [value_type],al
mov [symbol_identifier],ebx
address_64bit_relocation_ok:
mov eax,edx
stos dword [edi]
mov eax,[address_high]
stos dword [edi]
ret
address_immediate_sib:
test ch,44h
jnz address_immediate_sib_32bit
test ch,not 88h
jnz invalid_address_size
address_immediate_sib_store:
call store_instruction_code
mov al,100b
mov ah,100101b
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos word [edi]
jmp store_address_32bit_value
address_immediate_sib_32bit:
test ecx,0FF0000h
jnz address_immediate_sib_nosignextend
test edx,80000000h
jz address_immediate_sib_store
address_immediate_sib_nosignextend:
call address_32bit_prefix
jmp address_immediate_sib_store
address_eip_based:
mov al,67h
stos byte [edi]
address_rip_based:
cmp [code_type],64
jne invalid_address
call store_instruction_code
jmp store_immediate_address
address_relative:
call store_instruction_code
movzx eax,[immediate_size]
add eax,edi
sub eax,[current_offset]
add eax,5
sub edx,eax
jno @f
call recoverable_overflow
@@:
mov al,101b
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos byte [edi]
shr ecx,16
xchg [value_type],cl
mov ebx,[address_symbol]
xchg ebx,[symbol_identifier]
mov eax,edx
call mark_relocation
mov [value_type],cl
mov [symbol_identifier],ebx
stos dword [edi]
ret
addressing_16bit:
cmp edx,10000h
jge address_immediate_32bit
cmp edx,-8000h
jl address_immediate_32bit
movzx edx,dx
address_immediate_16bit:
call address_16bit_prefix
call store_instruction_code
mov al,110b
mov cl,[postbyte_register]
shl cl,3
or al,cl
stos byte [edi]
mov eax,edx
stos word [edi]
cmp edx,10000h
jge value_out_of_range
cmp edx,-8000h
jl value_out_of_range
ret
address_16bit_prefix:
cmp [code_type],16
je instruction_prefix_ok
mov al,67h
stos byte [edi]
ret
address_32bit_prefix:
cmp [code_type],32
je instruction_prefix_ok
mov al,67h
stos byte [edi]
instruction_prefix_ok:
ret
store_instruction_with_imm8:
mov [immediate_size],1
call store_instruction
mov al,byte [value]
stos byte [edi]
ret
store_instruction_with_imm16:
mov [immediate_size],2
call store_instruction
mov ax,word [value]
call mark_relocation
stos word [edi]
ret
store_instruction_with_imm32:
mov [immediate_size],4
call store_instruction
mov eax,dword [value]
call mark_relocation
stos dword [edi]
ret
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/Tupfile.lua
0,0 → 1,3
if tup.getconfig("NO_FASM") ~= "" then return end
tup.rule("echo lang fix " .. ((tup.getconfig("LANG") == "") and "en" or tup.getconfig("LANG")) .. " > lang.inc", {"lang.inc"})
tup.rule({"fasm.asm", extra_inputs = {"lang.inc"}}, "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "fasm")
/programs/develop/fasm/1.71/fasm.txt
0,0 → 1,4726
 
,'''
,,;,, ,,,, ,,,,, ,,, ,,
; ; ; ; ; ;
; ,''''; '''', ; ; ;
; ',,,,;, ,,,,,' ; ; ;
 
flat assembler 1.70
Programmer's Manual
 
 
Table of contents
-----------------
 
Chapter 1 Introduction
 
1.1 Compiler overview
1.1.1 System requirements
1.1.2 Executing compiler from command line
1.1.3 Compiler messages
1.1.4 Output formats
 
1.2 Assembly syntax
1.2.1 Instruction syntax
1.2.2 Data definitions
1.2.3 Constants and labels
1.2.4 Numerical expressions
1.2.5 Jumps and calls
1.2.6 Size settings
 
Chapter 2 Instruction set
 
2.1 The x86 architecture instructions
2.1.1 Data movement instructions
2.1.2 Type conversion instructions
2.1.3 Binary arithmetic instructions
2.1.4 Decimal arithmetic instructions
2.1.5 Logical instructions
2.1.6 Control transfer instructions
2.1.7 I/O instructions
2.1.8 Strings operations
2.1.9 Flag control instructions
2.1.10 Conditional operations
2.1.11 Miscellaneous instructions
2.1.12 System instructions
2.1.13 FPU instructions
2.1.14 MMX instructions
2.1.15 SSE instructions
2.1.16 SSE2 instructions
2.1.17 SSE3 instructions
2.1.18 AMD 3DNow! instructions
2.1.19 The x86-64 long mode instructions
2.1.20 SSE4 instructions
2.1.21 AVX instructions
2.1.22 AVX2 instructions
2.1.23 Auxiliary sets of computational instructions
2.1.24 Other extensions of instruction set
 
2.2 Control directives
2.2.1 Numerical constants
2.2.2 Conditional assembly
2.2.3 Repeating blocks of instructions
2.2.4 Addressing spaces
2.2.5 Other directives
2.2.6 Multiple passes
 
2.3 Preprocessor directives
2.3.1 Including source files
2.3.2 Symbolic constants
2.3.3 Macroinstructions
2.3.4 Structures
2.3.5 Repeating macroinstructions
2.3.6 Conditional preprocessing
2.3.7 Order of processing
 
2.4 Formatter directives
2.4.1 MZ executable
2.4.2 Portable Executable
2.4.3 Common Object File Format
2.4.4 Executable and Linkable Format
 
 
 
Chapter 1 Introduction
-----------------------
 
This chapter contains all the most important information you need to begin
using the flat assembler. If you are experienced assembly language programmer,
you should read at least this chapter before using this compiler.
 
 
1.1 Compiler overview
 
Flat assembler is a fast assembly language compiler for the x86 architecture
processors, which does multiple passes to optimize the size of generated
machine code. It is self-compilable and versions for different operating
systems are provided. All the versions are designed to be used from the system
command line and they should not differ in behavior.
 
 
1.1.1 System requirements
 
All versions require the x86 architecture 32-bit processor (at least 80386),
although they can produce programs for the x86 architecture 16-bit processors,
too. DOS version requires an OS compatible with MS DOS 2.0 and either true
real mode environment or DPMI. Windows version requires a Win32 console
compatible with 3.1 version.
 
 
1.1.2 Executing compiler from command line
 
To execute flat assembler from the command line you need to provide two
parameters - first should be name of source file, second should be name of
destination file. If no second parameter is given, the name for output
file will be guessed automatically. After displaying short information about
the program name and version, compiler will read the data from source file and
compile it. When the compilation is successful, compiler will write the
generated code to the destination file and display the summary of compilation
process; otherwise it will display the information about error that occurred.
The source file should be a text file, and can be created in any text
editor. Line breaks are accepted in both DOS and Unix standards, tabulators
are treated as spaces.
In the command line you can also include "-m" option followed by a number,
which specifies how many kilobytes of memory flat assembler should maximally
use. In case of DOS version this options limits only the usage of extended
memory. The "-p" option followed by a number can be used to specify the limit
for number of passes the assembler performs. If code cannot be generated
within specified amount of passes, the assembly will be terminated with an
error message. The maximum value of this setting is 65536, while the default
limit, used when no such option is included in command line, is 100.
It is also possible to limit the number of passes the assembler
performs, with the "-p" option followed by a number specifying the maximum
number of passes.
There are no command line options that would affect the output of compiler,
flat assembler requires only the source code to include the information it
really needs. For example, to specify output format you specify it by using
the "format" directive at the beginning of source.
 
 
1.1.3 Compiler messages
 
As it is stated above, after the successful compilation, the compiler displays
the compilation summary. It includes the information of how many passes was
done, how much time it took, and how many bytes were written into the
destination file.
The following is an example of the compilation summary:
 
flat assembler version 1.70 (16384 kilobytes memory)
38 passes, 5.3 seconds, 77824 bytes.
 
In case of error during the compilation process, the program will display an
error message. For example, when compiler can't find the input file, it will
display the following message:
 
flat assembler version 1.70 (16384 kilobytes memory)
error: source file not found.
 
If the error is connected with a specific part of source code, the source line
that caused the error will be also displayed. Also placement of this line in
the source is given to help you finding this error, for example:
 
flat assembler version 1.70 (16384 kilobytes memory)
example.asm [3]:
mob ax,1
error: illegal instruction.
 
It means that in the third line of the "example.asm" file compiler has
encountered an unrecognized instruction. When the line that caused error
contains a macroinstruction, also the line in macroinstruction definition
that generated the erroneous instruction is displayed:
 
flat assembler version 1.70 (16384 kilobytes memory)
example.asm [6]:
stoschar 7
example.asm [3] stoschar [1]:
mob al,char
error: illegal instruction.
 
It means that the macroinstruction in the sixth line of the "example.asm" file
generated an unrecognized instruction with the first line of its definition.
 
 
1.1.4 Output formats
 
By default, when there is no "format" directive in source file, flat
assembler simply puts generated instruction codes into output, creating this
way flat binary file. By default it generates 16-bit code, but you can always
turn it into the 16-bit or 32-bit mode by using "use16" or "use32" directive.
Some of the output formats switch into 32-bit mode, when selected - more
information about formats which you can choose can be found in 2.4.
All output code is always in the order in which it was entered into the
source file.
 
 
1.2 Assembly syntax
 
The information provided below is intended mainly for the assembler
programmers that have been using some other assembly compilers before.
If you are beginner, you should look for the assembly programming tutorials.
Flat assembler by default uses the Intel syntax for the assembly
instructions, although you can customize it using the preprocessor
capabilities (macroinstructions and symbolic constants). It also has its own
set of the directives - the instructions for compiler.
All symbols defined inside the sources are case-sensitive.
 
 
1.2.1 Instruction syntax
 
Instructions in assembly language are separated by line breaks, and one
instruction is expected to fill the one line of text. If a line contains
a semicolon, except for the semicolons inside the quoted strings, the rest of
this line is the comment and compiler ignores it. If a line ends with "\"
character (eventually the semicolon and comment may follow it), the next line
is attached at this point.
Each line in source is the sequence of items, which may be one of the three
types. One type are the symbol characters, which are the special characters
that are individual items even when are not spaced from the other ones.
Any of the "+-*/=<>()[]{}:,|&~#`" is the symbol character. The sequence of
other characters, separated from other items with either blank spaces or
symbol characters, is a symbol. If the first character of symbol is either a
single or double quote, it integrates any sequence of characters following it,
even the special ones, into a quoted string, which should end with the same
character, with which it began (the single or double quote) - however if there
are two such characters in a row (without any other character between them),
they are integrated into quoted string as just one of them and the quoted
string continues then. The symbols other than symbol characters and quoted
strings can be used as names, so are also called the name symbols.
Every instruction consists of the mnemonic and the various number of
operands, separated with commas. The operand can be register, immediate value
or a data addressed in memory, it can also be preceded by size operator to
define or override its size (table 1.1). Names of available registers you can
find in table 1.2, their sizes cannot be overridden. Immediate value can be
specified by any numerical expression.
When operand is a data in memory, the address of that data (also any
numerical expression, but it may contain registers) should be enclosed in
square brackets or preceded by "ptr" operator. For example instruction
"mov eax,3" will put the immediate value 3 into the EAX register, instruction
"mov eax,[7]" will put the 32-bit value from the address 7 into EAX and the
instruction "mov byte [7],3" will put the immediate value 3 into the byte at
address 7, it can also be written as "mov byte ptr 7,3". To specify which
segment register should be used for addressing, segment register name followed
by a colon should be put just before the address value (inside the square
brackets or after the "ptr" operator).
 
Table 1.1 Size operators
/-------------------------\
| Operator | Bits | Bytes |
|==========|======|=======|
| byte | 8 | 1 |
| word | 16 | 2 |
| dword | 32 | 4 |
| fword | 48 | 6 |
| pword | 48 | 6 |
| qword | 64 | 8 |
| tbyte | 80 | 10 |
| tword | 80 | 10 |
| dqword | 128 | 16 |
| xword | 128 | 16 |
| qqword | 256 | 32 |
| yword | 256 | 32 |
\-------------------------/
 
Table 1.2 Registers
/-----------------------------------------------------------------\
| Type | Bits | |
|=========|======|================================================|
| | 8 | al cl dl bl ah ch dh bh |
| General | 16 | ax cx dx bx sp bp si di |
| | 32 | eax ecx edx ebx esp ebp esi edi |
|---------|------|------------------------------------------------|
| Segment | 16 | es cs ss ds fs gs |
|---------|------|------------------------------------------------|
| Control | 32 | cr0 cr2 cr3 cr4 |
|---------|------|------------------------------------------------|
| Debug | 32 | dr0 dr1 dr2 dr3 dr6 dr7 |
|---------|------|------------------------------------------------|
| FPU | 80 | st0 st1 st2 st3 st4 st5 st6 st7 |
|---------|------|------------------------------------------------|
| MMX | 64 | mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 |
|---------|------|------------------------------------------------|
| SSE | 128 | xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 |
|---------|------|------------------------------------------------|
| AVX | 256 | ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 |
\-----------------------------------------------------------------/
 
 
1.2.2 Data definitions
 
To define data or reserve a space for it, use one of the directives listed in
table 1.3. The data definition directive should be followed by one or more of
numerical expressions, separated with commas. These expressions define the
values for data cells of size depending on which directive is used. For
example "db 1,2,3" will define the three bytes of values 1, 2 and 3
respectively.
The "db" and "du" directives also accept the quoted string values of any
length, which will be converted into chain of bytes when "db" is used and into
chain of words with zeroed high byte when "du" is used. For example "db 'abc'"
will define the three bytes of values 61, 62 and 63.
The "dp" directive and its synonym "df" accept the values consisting of two
numerical expressions separated with colon, the first value will become the
high word and the second value will become the low double word of the far
pointer value. Also "dd" accepts such pointers consisting of two word values
separated with colon, and "dt" accepts the word and quad word value separated
with colon, the quad word is stored first. The "dt" directive with single
expression as parameter accepts only floating point values and creates data in
FPU double extended precision format.
Any of the above directive allows the usage of special "dup" operator to
make multiple copies of given values. The count of duplicates should precede
this operator and the value to duplicate should follow - it can even be the
chain of values separated with commas, but such set of values needs to be
enclosed with parenthesis, like "db 5 dup (1,2)", which defines five copies
of the given two byte sequence.
The "file" is a special directive and its syntax is different. This
directive includes a chain of bytes from file and it should be followed by the
quoted file name, then optionally numerical expression specifying offset in
file preceded by the colon, and - also optionally - comma and numerical
expression specifying count of bytes to include (if no count is specified, all
data up to the end of file is included). For example "file 'data.bin'" will
include the whole file as binary data and "file 'data.bin':10h,4" will include
only four bytes starting at offset 10h.
The data reservation directive should be followed by only one numerical
expression, and this value defines how many cells of the specified size should
be reserved. All data definition directives also accept the "?" value, which
means that this cell should not be initialized to any value and the effect is
the same as by using the data reservation directive. The uninitialized data
may not be included in the output file, so its values should be always
considered unknown.
 
Table 1.3 Data directives
/----------------------------\
| Size | Define | Reserve |
| (bytes) | data | data |
|=========|========|=========|
| 1 | db | rb |
| | file | |
|---------|--------|---------|
| 2 | dw | rw |
| | du | |
|---------|--------|---------|
| 4 | dd | rd |
|---------|--------|---------|
| 6 | dp | rp |
| | df | rf |
|---------|--------|---------|
| 8 | dq | rq |
|---------|--------|---------|
| 10 | dt | rt |
\----------------------------/
 
 
1.2.3 Constants and labels
 
In the numerical expressions you can also use constants or labels instead of
numbers. To define the constant or label you should use the specific
directives. Each label can be defined only once and it is accessible from the
any place of source (even before it was defined). Constant can be redefined
many times, but in this case it is accessible only after it was defined, and
is always equal to the value from last definition before the place where it's
used. When a constant is defined only once in source, it is - like the label -
accessible from anywhere.
The definition of constant consists of name of the constant followed by the
"=" character and numerical expression, which after calculation will become
the value of constant. This value is always calculated at the time the
constant is defined. For example you can define "count" constant by using the
directive "count = 17", and then use it in the assembly instructions, like
"mov cx,count" - which will become "mov cx,17" during the compilation process.
There are different ways to define labels. The simplest is to follow the
name of label by the colon, this directive can even be followed by the other
instruction in the same line. It defines the label whose value is equal to
offset of the point where it's defined. This method is usually used to label
the places in code. The other way is to follow the name of label (without a
colon) by some data directive. It defines the label with value equal to
offset of the beginning of defined data, and remembered as a label for data
with cell size as specified for that data directive in table 1.3.
The label can be treated as constant of value equal to offset of labeled
code or data. For example when you define data using the labeled directive
"char db 224", to put the offset of this data into BX register you should use
"mov bx,char" instruction, and to put the value of byte addressed by "char"
label to DL register, you should use "mov dl,[char]" (or "mov dl,ptr char").
But when you try to assemble "mov ax,[char]", it will cause an error, because
fasm compares the sizes of operands, which should be equal. You can force
assembling that instruction by using size override: "mov ax,word [char]", but
remember that this instruction will read the two bytes beginning at "char"
address, while it was defined as a one byte.
The last and the most flexible way to define labels is to use "label"
directive. This directive should be followed by the name of label, then
optionally size operator (it can be preceded by a colon) and then - also
optionally "at" operator and the numerical expression defining the address at
which this label should be defined. For example "label wchar word at char"
will define a new label for the 16-bit data at the address of "char". Now the
instruction "mov ax,[wchar]" will be after compilation the same as
"mov ax,word [char]". If no address is specified, "label" directive defines
the label at current offset. Thus "mov [wchar],57568" will copy two bytes
while "mov [char],224" will copy one byte to the same address.
The label whose name begins with dot is treated as local label, and its name
is attached to the name of last global label (with name beginning with
anything but dot) to make the full name of this label. So you can use the
short name (beginning with dot) of this label anywhere before the next global
label is defined, and in the other places you have to use the full name. Label
beginning with two dots are the exception - they are like global, but they
don't become the new prefix for local labels.
The "@@" name means anonymous label, you can have defined many of them in
the source. Symbol "@b" (or equivalent "@r") references the nearest preceding
anonymous label, symbol "@f" references the nearest following anonymous label.
These special symbol are case-insensitive.
 
 
1.2.4 Numerical expressions
 
In the above examples all the numerical expressions were the simple numbers,
constants or labels. But they can be more complex, by using the arithmetical
or logical operators for calculations at compile time. All these operators
with their priority values are listed in table 1.4. The operations with higher
priority value will be calculated first, you can of course change this
behavior by putting some parts of expression into parenthesis. The "+", "-",
"*" and "/" are standard arithmetical operations, "mod" calculates the
remainder from division. The "and", "or", "xor", "shl", "shr" and "not"
perform the same logical operations as assembly instructions of those names.
The "rva" and "plt" are special unary operators that perform conversions
between different kinds of addresses, they can be used only with few of the
output formats and their meaning may vary (see 2.4).
The arithmetical and logical calculations are usually processed as if they
operated on infinite precision 2-adic numbers, and assembler signalizes an
overflow error if because of its limitations it is not table to perform the
required calculation, or if the result is too large number to fit in either
signed or unsigned range for the destination unit size. However "not", "xor"
and "shr" operators are exceptions from this rule - if the value specified
by numerical expression has to fit in a unit of specified size, and the
arguments for operation fit into that size, the operation will be performed
with precision limited to that size.
The numbers in the expression are by default treated as a decimal, binary
numbers should have the "b" letter attached at the end, octal number should
end with "o" letter, hexadecimal numbers should begin with "0x" characters
(like in C language) or with the "$" character (like in Pascal language) or
they should end with "h" letter. Also quoted string, when encountered in
expression, will be converted into number - the first character will become
the least significant byte of number.
The numerical expression used as an address value can also contain any of
general registers used for addressing, they can be added and multiplied by
appropriate values, as it is allowed for the x86 architecture instructions.
The numerical calculations inside address definition by default operate with
target size assumed to be the same as the current bitness of code, even if
generated instruction encoding will use a different address size.
There are also some special symbols that can be used inside the numerical
expression. First is "$", which is always equal to the value of current
offset, while "$$" is equal to base address of current addressing space. The
other one is "%", which is the number of current repeat in parts of code that
are repeated using some special directives (see 2.2) and zero anywhere else.
There's also "%t" symbol, which is always equal to the current time stamp.
Any numerical expression can also consist of single floating point value
(flat assembler does not allow any floating point operations at compilation
time) in the scientific notation, they can end with the "f" letter to be
recognized, otherwise they should contain at least one of the "." or "E"
characters. So "1.0", "1E0" and "1f" define the same floating point value,
while simple "1" defines an integer value.
 
Table 1.4 Arithmetical and logical operators by priority
/-------------------------\
| Priority | Operators |
|==========|==============|
| 0 | + - |
|----------|--------------|
| 1 | * / |
|----------|--------------|
| 2 | mod |
|----------|--------------|
| 3 | and or xor |
|----------|--------------|
| 4 | shl shr |
|----------|--------------|
| 5 | not |
|----------|--------------|
| 6 | rva plt |
\-------------------------/
 
 
1.2.5 Jumps and calls
 
The operand of any jump or call instruction can be preceded not only by the
size operator, but also by one of the operators specifying type of the jump:
"short", "near" or "far". For example, when assembler is in 16-bit mode,
instruction "jmp dword [0]" will become the far jump and when assembler is
in 32-bit mode, it will become the near jump. To force this instruction to be
treated differently, use the "jmp near dword [0]" or "jmp far dword [0]" form.
When operand of near jump is the immediate value, assembler will generate
the shortest variant of this jump instruction if possible (but will not create
32-bit instruction in 16-bit mode nor 16-bit instruction in 32-bit mode,
unless there is a size operator stating it). By specifying the jump type
you can force it to always generate long variant (for example "jmp near 0")
or to always generate short variant and terminate with an error when it's
impossible (for example "jmp short 0").
 
 
1.2.6 Size settings
 
When instruction uses some memory addressing, by default the smallest form of
instruction is generated by using the short displacement if only address
value fits in the range. This can be overridden using the "word" or "dword"
operator before the address inside the square brackets (or after the "ptr"
operator), which forces the long displacement of appropriate size to be made.
In case when address is not relative to any registers, those operators allow
also to choose the appropriate mode of absolute addressing.
Instructions "adc", "add", "and", "cmp", "or", "sbb", "sub" and "xor" with
first operand being 16-bit or 32-bit are by default generated in shortened
8-bit form when the second operand is immediate value fitting in the range
for signed 8-bit values. It also can be overridden by putting the "word" or
"dword" operator before the immediate value. The similar rules applies to the
"imul" instruction with the last operand being immediate value.
Immediate value as an operand for "push" instruction without a size operator
is by default treated as a word value if assembler is in 16-bit mode and as a
double word value if assembler is in 32-bit mode, shorter 8-bit form of this
instruction is used if possible, "word" or "dword" size operator forces the
"push" instruction to be generated in longer form for specified size. "pushw"
and "pushd" mnemonics force assembler to generate 16-bit or 32-bit code
without forcing it to use the longer form of instruction.
 
 
Chapter 2 Instruction set
--------------------------
 
This chapter provides the detailed information about the instructions and
directives supported by flat assembler. Directives for defining labels were
already discussed in 1.2.3, all other directives will be described later in
this chapter.
 
 
2.1 The x86 architecture instructions
 
In this section you can find both the information about the syntax and
purpose the assembly language instructions. If you need more technical
information, look for the Intel Architecture Software Developer's Manual.
Assembly instructions consist of the mnemonic (instruction's name) and from
zero to three operands. If there are two or more operands, usually first is
the destination operand and second is the source operand. Each operand can be
register, memory or immediate value (see 1.2 for details about syntax of
operands). After the description of each instruction there are examples
of different combinations of operands, if the instruction has any.
Some instructions act as prefixes and can be followed by other instruction
in the same line, and there can be more than one prefix in a line. Each name
of the segment register is also a mnemonic of instruction prefix, altough it
is recommended to use segment overrides inside the square brackets instead of
these prefixes.
 
 
2.1.1 Data movement instructions
 
"mov" transfers a byte, word or double word from the source operand to the
destination operand. It can transfer data between general registers, from
the general register to memory, or from memory to general register, but it
cannot move from memory to memory. It can also transfer an immediate value to
general register or memory, segment register to general register or memory,
general register or memory to segment register, control or debug register to
general register and general register to control or debug register. The "mov"
can be assembled only if the size of source operand and size of destination
operand are the same. Below are the examples for each of the allowed
combinations:
 
mov bx,ax ; general register to general register
mov [char],al ; general register to memory
mov bl,[char] ; memory to general register
mov dl,32 ; immediate value to general register
mov [char],32 ; immediate value to memory
mov ax,ds ; segment register to general register
mov [bx],ds ; segment register to memory
mov ds,ax ; general register to segment register
mov ds,[bx] ; memory to segment register
mov eax,cr0 ; control register to general register
mov cr3,ebx ; general register to control register
 
"xchg" swaps the contents of two operands. It can swap two byte operands,
two word operands or two double word operands. Order of operands is not
important. The operands may be two general registers, or general register
with memory. For example:
 
xchg ax,bx ; swap two general registers
xchg al,[char] ; swap register with memory
 
"push" decrements the stack frame pointer (ESP register), then transfers
the operand to the top of stack indicated by ESP. The operand can be memory,
general register, segment register or immediate value of word or double word
size. If operand is an immediate value and no size is specified, it is by
default treated as a word value if assembler is in 16-bit mode and as a double
word value if assembler is in 32-bit mode. "pushw" and "pushd" mnemonics are
variants of this instruction that store the values of word or double word size
respectively. If more operands follow in the same line (separated only with
spaces, not commas), compiler will assemble chain of the "push" instructions
with these operands. The examples are with single operands:
 
push ax ; store general register
push es ; store segment register
pushw [bx] ; store memory
push 1000h ; store immediate value
 
"pusha" saves the contents of the eight general register on the stack.
This instruction has no operands. There are two version of this instruction,
one 16-bit and one 32-bit, assembler automatically generates the appropriate
version for current mode, but it can be overridden by using "pushaw" or
"pushad" mnemonic to always get the 16-bit or 32-bit version. The 16-bit
version of this instruction pushes general registers on the stack in the
following order: AX, CX, DX, BX, the initial value of SP before AX was pushed,
BP, SI and DI. The 32-bit version pushes equivalent 32-bit general registers
in the same order.
"pop" transfers the word or double word at the current top of stack to the
destination operand, and then increments ESP to point to the new top of stack.
The operand can be memory, general register or segment register. "popw" and
"popd" mnemonics are variants of this instruction for restoring the values of
word or double word size respectively. If more operands separated with spaces
follow in the same line, compiler will assemble chain of the "pop"
instructions with these operands.
 
pop bx ; restore general register
pop ds ; restore segment register
popw [si] ; restore memory
 
"popa" restores the registers saved on the stack by "pusha" instruction,
except for the saved value of SP (or ESP), which is ignored. This instruction
has no operands. To force assembling 16-bit or 32-bit version of this
instruction use "popaw" or "popad" mnemonic.
 
 
2.1.2 Type conversion instructions
 
The type conversion instructions convert bytes into words, words into double
words, and double words into quad words. These conversions can be done using
the sign extension or zero extension. The sign extension fills the extra bits
of the larger item with the value of the sign bit of the smaller item, the
zero extension simply fills them with zeros.
"cwd" and "cdq" double the size of value AX or EAX register respectively
and store the extra bits into the DX or EDX register. The conversion is done
using the sign extension. These instructions have no operands.
"cbw" extends the sign of the byte in AL throughout AX, and "cwde" extends
the sign of the word in AX throughout EAX. These instructions also have no
operands.
"movsx" converts a byte to word or double word and a word to double word
using the sign extension. "movzx" does the same, but it uses the zero
extension. The source operand can be general register or memory, while the
destination operand must be a general register. For example:
 
movsx ax,al ; byte register to word register
movsx edx,dl ; byte register to double word register
movsx eax,ax ; word register to double word register
movsx ax,byte [bx] ; byte memory to word register
movsx edx,byte [bx] ; byte memory to double word register
movsx eax,word [bx] ; word memory to double word register
 
 
2.1.3 Binary arithmetic instructions
 
"add" replaces the destination operand with the sum of the source and
destination operands and sets CF if overflow has occurred. The operands may
be bytes, words or double words. The destination operand can be general
register or memory, the source operand can be general register or immediate
value, it can also be memory if the destination operand is register.
 
add ax,bx ; add register to register
add ax,[si] ; add memory to register
add [di],al ; add register to memory
add al,48 ; add immediate value to register
add [char],48 ; add immediate value to memory
 
"adc" sums the operands, adds one if CF is set, and replaces the destination
operand with the result. Rules for the operands are the same as for the "add"
instruction. An "add" followed by multiple "adc" instructions can be used to
add numbers longer than 32 bits.
"inc" adds one to the operand, it does not affect CF. The operand can be a
general register or memory, and the size of the operand can be byte, word or
double word.
 
inc ax ; increment register by one
inc byte [bx] ; increment memory by one
 
"sub" subtracts the source operand from the destination operand and replaces
the destination operand with the result. If a borrow is required, the CF is
set. Rules for the operands are the same as for the "add" instruction.
"sbb" subtracts the source operand from the destination operand, subtracts
one if CF is set, and stores the result to the destination operand. Rules for
the operands are the same as for the "add" instruction. A "sub" followed by
multiple "sbb" instructions may be used to subtract numbers longer than 32
bits.
"dec" subtracts one from the operand, it does not affect CF. Rules for the
operand are the same as for the "inc" instruction.
"cmp" subtracts the source operand from the destination operand. It updates
the flags as the "sub" instruction, but does not alter the source and
destination operands. Rules for the operands are the same as for the "sub"
instruction.
"neg" subtracts a signed integer operand from zero. The effect of this
instructon is to reverse the sign of the operand from positive to negative or
from negative to positive. Rules for the operand are the same as for the "inc"
instruction.
"xadd" exchanges the destination operand with the source operand, then loads
the sum of the two values into the destination operand. Rules for the operands
are the same as for the "add" instruction.
All the above binary arithmetic instructions update SF, ZF, PF and OF flags.
SF is always set to the same value as the result's sign bit, ZF is set when
all the bits of result are zero, PF is set when low order eight bits of result
contain an even number of set bits, OF is set if result is too large for a
positive number or too small for a negative number (excluding sign bit) to fit
in destination operand.
"mul" performs an unsigned multiplication of the operand and the
accumulator. If the operand is a byte, the processor multiplies it by the
contents of AL and returns the 16-bit result to AH and AL. If the operand is a
word, the processor multiplies it by the contents of AX and returns the 32-bit
result to DX and AX. If the operand is a double word, the processor multiplies
it by the contents of EAX and returns the 64-bit result in EDX and EAX. "mul"
sets CF and OF when the upper half of the result is nonzero, otherwise they
are cleared. Rules for the operand are the same as for the "inc" instruction.
"imul" performs a signed multiplication operation. This instruction has
three variations. First has one operand and behaves in the same way as the
"mul" instruction. Second has two operands, in this case destination operand
is multiplied by the source operand and the result replaces the destination
operand. Destination operand must be a general register, it can be word or
double word, source operand can be general register, memory or immediate
value. Third form has three operands, the destination operand must be a
general register, word or double word in size, source operand can be general
register or memory, and third operand must be an immediate value. The source
operand is multiplied by the immediate value and the result is stored in the
destination register. All the three forms calculate the product to twice the
size of operands and set CF and OF when the upper half of the result is
nonzero, but second and third form truncate the product to the size of
operands. So second and third forms can be also used for unsigned operands
because, whether the operands are signed or unsigned, the lower half of the
product is the same. Below are the examples for all three forms:
 
imul bl ; accumulator by register
imul word [si] ; accumulator by memory
imul bx,cx ; register by register
imul bx,[si] ; register by memory
imul bx,10 ; register by immediate value
imul ax,bx,10 ; register by immediate value to register
imul ax,[si],10 ; memory by immediate value to register
 
"div" performs an unsigned division of the accumulator by the operand.
The dividend (the accumulator) is twice the size of the divisor (the operand),
the quotient and remainder have the same size as the divisor. If divisor is
byte, the dividend is taken from AX register, the quotient is stored in AL and
the remainder is stored in AH. If divisor is word, the upper half of dividend
is taken from DX, the lower half of dividend is taken from AX, the quotient is
stored in AX and the remainder is stored in DX. If divisor is double word,
the upper half of dividend is taken from EDX, the lower half of dividend is
taken from EAX, the quotient is stored in EAX and the remainder is stored in
EDX. Rules for the operand are the same as for the "mul" instruction.
"idiv" performs a signed division of the accumulator by the operand.
It uses the same registers as the "div" instruction, and the rules for
the operand are the same.
 
 
2.1.4 Decimal arithmetic instructions
 
Decimal arithmetic is performed by combining the binary arithmetic
instructions (already described in the prior section) with the decimal
arithmetic instructions. The decimal arithmetic instructions are used to
adjust the results of a previous binary arithmetic operation to produce a
valid packed or unpacked decimal result, or to adjust the inputs to a
subsequent binary arithmetic operation so the operation will produce a valid
packed or unpacked decimal result.
"daa" adjusts the result of adding two valid packed decimal operands in
AL. "daa" must always follow the addition of two pairs of packed decimal
numbers (one digit in each half-byte) to obtain a pair of valid packed
decimal digits as results. The carry flag is set if carry was needed.
This instruction has no operands.
"das" adjusts the result of subtracting two valid packed decimal operands
in AL. "das" must always follow the subtraction of one pair of packed decimal
numbers (one digit in each half-byte) from another to obtain a pair of valid
packed decimal digits as results. The carry flag is set if a borrow was
needed. This instruction has no operands.
"aaa" changes the contents of register AL to a valid unpacked decimal
number, and zeroes the top four bits. "aaa" must always follow the addition
of two unpacked decimal operands in AL. The carry flag is set and AH is
incremented if a carry is necessary. This instruction has no operands.
"aas" changes the contents of register AL to a valid unpacked decimal
number, and zeroes the top four bits. "aas" must always follow the
subtraction of one unpacked decimal operand from another in AL. The carry flag
is set and AH decremented if a borrow is necessary. This instruction has no
operands.
"aam" corrects the result of a multiplication of two valid unpacked decimal
numbers. "aam" must always follow the multiplication of two decimal numbers
to produce a valid decimal result. The high order digit is left in AH, the
low order digit in AL. The generalized version of this instruction allows
adjustment of the contents of the AX to create two unpacked digits of any
number base. The standard version of this instruction has no operands, the
generalized version has one operand - an immediate value specifying the
number base for the created digits.
"aad" modifies the numerator in AH and AL to prepare for the division of two
valid unpacked decimal operands so that the quotient produced by the division
will be a valid unpacked decimal number. AH should contain the high order
digit and AL the low order digit. This instruction adjusts the value and
places the result in AL, while AH will contain zero. The generalized version
of this instruction allows adjustment of two unpacked digits of any number
base. Rules for the operand are the same as for the "aam" instruction.
 
 
2.1.5 Logical instructions
 
"not" inverts the bits in the specified operand to form a one's complement
of the operand. It has no effect on the flags. Rules for the operand are the
same as for the "inc" instruction.
"and", "or" and "xor" instructions perform the standard logical operations.
They update the SF, ZF and PF flags. Rules for the operands are the same as
for the "add" instruction.
"bt", "bts", "btr" and "btc" instructions operate on a single bit which can
be in memory or in a general register. The location of the bit is specified
as an offset from the low order end of the operand. The value of the offset
is the taken from the second operand, it either may be an immediate byte or
a general register. These instructions first assign the value of the selected
bit to CF. "bt" instruction does nothing more, "bts" sets the selected bit to
1, "btr" resets the selected bit to 0, "btc" changes the bit to its
complement. The first operand can be word or double word.
 
bt ax,15 ; test bit in register
bts word [bx],15 ; test and set bit in memory
btr ax,cx ; test and reset bit in register
btc word [bx],cx ; test and complement bit in memory
 
"bsf" and "bsr" instructions scan a word or double word for first set bit
and store the index of this bit into destination operand, which must be
general register. The bit string being scanned is specified by source operand,
it may be either general register or memory. The ZF flag is set if the entire
string is zero (no set bits are found); otherwise it is cleared. If no set bit
is found, the value of the destination register is undefined. "bsf" scans from
low order to high order (starting from bit index zero). "bsr" scans from high
order to low order (starting from bit index 15 of a word or index 31 of a
double word).
 
bsf ax,bx ; scan register forward
bsr ax,[si] ; scan memory reverse
 
"shl" shifts the destination operand left by the number of bits specified
in the second operand. The destination operand can be byte, word, or double
word general register or memory. The second operand can be an immediate value
or the CL register. The processor shifts zeros in from the right (low order)
side of the operand as bits exit from the left side. The last bit that exited
is stored in CF. "sal" is a synonym for "shl".
 
shl al,1 ; shift register left by one bit
shl byte [bx],1 ; shift memory left by one bit
shl ax,cl ; shift register left by count from cl
shl word [bx],cl ; shift memory left by count from cl
 
"shr" and "sar" shift the destination operand right by the number of bits
specified in the second operand. Rules for operands are the same as for the
"shl" instruction. "shr" shifts zeros in from the left side of the operand as
bits exit from the right side. The last bit that exited is stored in CF.
"sar" preserves the sign of the operand by shifting in zeros on the left side
if the value is positive or by shifting in ones if the value is negative.
"shld" shifts bits of the destination operand to the left by the number
of bits specified in third operand, while shifting high order bits from the
source operand into the destination operand on the right. The source operand
remains unmodified. The destination operand can be a word or double word
general register or memory, the source operand must be a general register,
third operand can be an immediate value or the CL register.
 
shld ax,bx,1 ; shift register left by one bit
shld [di],bx,1 ; shift memory left by one bit
shld ax,bx,cl ; shift register left by count from cl
shld [di],bx,cl ; shift memory left by count from cl
 
"shrd" shifts bits of the destination operand to the right, while shifting
low order bits from the source operand into the destination operand on the
left. The source operand remains unmodified. Rules for operands are the same
as for the "shld" instruction.
"rol" and "rcl" rotate the byte, word or double word destination operand
left by the number of bits specified in the second operand. For each rotation
specified, the high order bit that exits from the left of the operand returns
at the right to become the new low order bit. "rcl" additionally puts in CF
each high order bit that exits from the left side of the operand before it
returns to the operand as the low order bit on the next rotation cycle. Rules
for operands are the same as for the "shl" instruction.
"ror" and "rcr" rotate the byte, word or double word destination operand
right by the number of bits specified in the second operand. For each rotation
specified, the low order bit that exits from the right of the operand returns
at the left to become the new high order bit. "rcr" additionally puts in CF
each low order bit that exits from the right side of the operand before it
returns to the operand as the high order bit on the next rotation cycle.
Rules for operands are the same as for the "shl" instruction.
"test" performs the same action as the "and" instruction, but it does not
alter the destination operand, only updates flags. Rules for the operands are
the same as for the "and" instruction.
"bswap" reverses the byte order of a 32-bit general register: bits 0 through
7 are swapped with bits 24 through 31, and bits 8 through 15 are swapped with
bits 16 through 23. This instruction is provided for converting little-endian
values to big-endian format and vice versa.
 
bswap edx ; swap bytes in register
 
 
2.1.6 Control transfer instructions
 
"jmp" unconditionally transfers control to the target location. The
destination address can be specified directly within the instruction or
indirectly through a register or memory, the acceptable size of this address
depends on whether the jump is near or far (it can be specified by preceding
the operand with "near" or "far" operator) and whether the instruction is
16-bit or 32-bit. Operand for near jump should be "word" size for 16-bit
instruction or the "dword" size for 32-bit instruction. Operand for far jump
should be "dword" size for 16-bit instruction or "pword" size for 32-bit
instruction. A direct "jmp" instruction includes the destination address as
part of the instruction (and can be preceded by "short", "near" or "far"
operator), the operand specifying address should be the numerical expression
for near or short jump, or two numerical expressions separated with colon for
far jump, the first specifies selector of segment, the second is the offset
within segment. The "pword" operator can be used to force the 32-bit far call,
and "dword" to force the 16-bit far call. An indirect "jmp" instruction
obtains the destination address indirectly through a register or a pointer
variable, the operand should be general register or memory. See also 1.2.5 for
some more details.
 
jmp 100h ; direct near jump
jmp 0FFFFh:0 ; direct far jump
jmp ax ; indirect near jump
jmp pword [ebx] ; indirect far jump
 
"call" transfers control to the procedure, saving on the stack the address
of the instruction following the "call" for later use by a "ret" (return)
instruction. Rules for the operands are the same as for the "jmp" instruction,
but the "call" has no short variant of direct instruction and thus it not
optimized.
"ret", "retn" and "retf" instructions terminate the execution of a procedure
and transfers control back to the program that originally invoked the
procedure using the address that was stored on the stack by the "call"
instruction. "ret" is the equivalent for "retn", which returns from the
procedure that was executed using the near call, while "retf" returns from
the procedure that was executed using the far call. These instructions default
to the size of address appropriate for the current code setting, but the size
of address can be forced to 16-bit by using the "retw", "retnw" and "retfw"
mnemonics, and to 32-bit by using the "retd", "retnd" and "retfd" mnemonics.
All these instructions may optionally specify an immediate operand, by adding
this constant to the stack pointer, they effectively remove any arguments that
the calling program pushed on the stack before the execution of the "call"
instruction.
"iret" returns control to an interrupted procedure. It differs from "ret" in
that it also pops the flags from the stack into the flags register. The flags
are stored on the stack by the interrupt mechanism. It defaults to the size of
return address appropriate for the current code setting, but it can be forced
to use 16-bit or 32-bit address by using the "iretw" or "iretd" mnemonic.
The conditional transfer instructions are jumps that may or may not transfer
control, depending on the state of the CPU flags when the instruction
executes. The mnemonics for conditional jumps may be obtained by attaching
the condition mnemonic (see table 2.1) to the "j" mnemonic,
for example "jc" instruction will transfer the control when the CF flag is
set. The conditional jumps can be short or near, and direct only, and can be
optimized (see 1.2.5), the operand should be an immediate value specifying
target address.
 
Table 2.1 Conditions
/-----------------------------------------------------------\
| Mnemonic | Condition tested | Description |
|==========|=======================|========================|
| o | OF = 1 | overflow |
|----------|-----------------------|------------------------|
| no | OF = 0 | not overflow |
|----------|-----------------------|------------------------|
| c | | carry |
| b | CF = 1 | below |
| nae | | not above nor equal |
|----------|-----------------------|------------------------|
| nc | | not carry |
| ae | CF = 0 | above or equal |
| nb | | not below |
|----------|-----------------------|------------------------|
| e | ZF = 1 | equal |
| z | | zero |
|----------|-----------------------|------------------------|
| ne | ZF = 0 | not equal |
| nz | | not zero |
|----------|-----------------------|------------------------|
| be | CF or ZF = 1 | below or equal |
| na | | not above |
|----------|-----------------------|------------------------|
| a | CF or ZF = 0 | above |
| nbe | | not below nor equal |
|----------|-----------------------|------------------------|
| s | SF = 1 | sign |
|----------|-----------------------|------------------------|
| ns | SF = 0 | not sign |
|----------|-----------------------|------------------------|
| p | PF = 1 | parity |
| pe | | parity even |
|----------|-----------------------|------------------------|
| np | PF = 0 | not parity |
| po | | parity odd |
|----------|-----------------------|------------------------|
| l | SF xor OF = 1 | less |
| nge | | not greater nor equal |
|----------|-----------------------|------------------------|
| ge | SF xor OF = 0 | greater or equal |
| nl | | not less |
|----------|-----------------------|------------------------|
| le | (SF xor OF) or ZF = 1 | less or equal |
| ng | | not greater |
|----------|-----------------------|------------------------|
| g | (SF xor OF) or ZF = 0 | greater |
| nle | | not less nor equal |
\-----------------------------------------------------------/
 
The "loop" instructions are conditional jumps that use a value placed in
CX (or ECX) to specify the number of repetitions of a software loop. All
"loop" instructions automatically decrement CX (or ECX) and terminate the
loop (don't transfer the control) when CX (or ECX) is zero. It uses CX or ECX
whether the current code setting is 16-bit or 32-bit, but it can be forced to
us CX with the "loopw" mnemonic or to use ECX with the "loopd" mnemonic.
"loope" and "loopz" are the synonyms for the same instruction, which acts as
the standard "loop", but also terminates the loop when ZF flag is set.
"loopew" and "loopzw" mnemonics force them to use CX register while "looped"
and "loopzd" force them to use ECX register. "loopne" and "loopnz" are the
synonyms for the same instructions, which acts as the standard "loop", but
also terminate the loop when ZF flag is not set. "loopnew" and "loopnzw"
mnemonics force them to use CX register while "loopned" and "loopnzd" force
them to use ECX register. Every "loop" instruction needs an operand being an
immediate value specifying target address, it can be only short jump (in the
range of 128 bytes back and 127 bytes forward from the address of instruction
following the "loop" instruction).
"jcxz" branches to the label specified in the instruction if it finds a
value of zero in CX, "jecxz" does the same, but checks the value of ECX
instead of CX. Rules for the operands are the same as for the "loop"
instruction.
"int" activates the interrupt service routine that corresponds to the
number specified as an operand to the instruction, the number should be in
range from 0 to 255. The interrupt service routine terminates with an "iret"
instruction that returns control to the instruction that follows "int".
"int3" mnemonic codes the short (one byte) trap that invokes the interrupt 3.
"into" instruction invokes the interrupt 4 if the OF flag is set.
"bound" verifies that the signed value contained in the specified register
lies within specified limits. An interrupt 5 occurs if the value contained in
the register is less than the lower bound or greater than the upper bound. It
needs two operands, the first operand specifies the register being tested,
the second operand should be memory address for the two signed limit values.
The operands can be "word" or "dword" in size.
 
bound ax,[bx] ; check word for bounds
bound eax,[esi] ; check double word for bounds
 
 
2.1.7 I/O instructions
 
"in" transfers a byte, word, or double word from an input port to AL, AX,
or EAX. I/O ports can be addressed either directly, with the immediate byte
value coded in instruction, or indirectly via the DX register. The destination
operand should be AL, AX, or EAX register. The source operand should be an
immediate value in range from 0 to 255, or DX register.
 
in al,20h ; input byte from port 20h
in ax,dx ; input word from port addressed by dx
 
"out" transfers a byte, word, or double word to an output port from AL, AX,
or EAX. The program can specify the number of the port using the same methods
as the "in" instruction. The destination operand should be an immediate value
in range from 0 to 255, or DX register. The source operand should be AL, AX,
or EAX register.
 
out 20h,ax ; output word to port 20h
out dx,al ; output byte to port addressed by dx
 
 
2.1.8 Strings operations
 
The string operations operate on one element of a string. A string element
may be a byte, a word, or a double word. The string elements are addressed by
SI and DI (or ESI and EDI) registers. After every string operation SI and/or
DI (or ESI and/or EDI) are automatically updated to point to the next element
of the string. If DF (direction flag) is zero, the index registers are
incremented, if DF is one, they are decremented. The amount of the increment
or decrement is 1, 2, or 4 depending on the size of the string element. Every
string operation instruction has short forms which have no operands and use
SI and/or DI when the code type is 16-bit, and ESI and/or EDI when the code
type is 32-bit. SI and ESI by default address data in the segment selected
by DS, DI and EDI always address data in the segment selected by ES. Short
form is obtained by attaching to the mnemonic of string operation letter
specifying the size of string element, it should be "b" for byte element,
"w" for word element, and "d" for double word element. Full form of string
operation needs operands providing the size operator and the memory addresses,
which can be SI or ESI with any segment prefix, DI or EDI always with ES
segment prefix.
"movs" transfers the string element pointed to by SI (or ESI) to the
location pointed to by DI (or EDI). Size of operands can be byte, word, or
double word. The destination operand should be memory addressed by DI or EDI,
the source operand should be memory addressed by SI or ESI with any segment
prefix.
 
movs byte [di],[si] ; transfer byte
movs word [es:di],[ss:si] ; transfer word
movsd ; transfer double word
 
"cmps" subtracts the destination string element from the source string
element and updates the flags AF, SF, PF, CF and OF, but it does not change
any of the compared elements. If the string elements are equal, ZF is set,
otherwise it is cleared. The first operand for this instruction should be the
source string element addressed by SI or ESI with any segment prefix, the
second operand should be the destination string element addressed by DI or
EDI.
 
cmpsb ; compare bytes
cmps word [ds:si],[es:di] ; compare words
cmps dword [fs:esi],[edi] ; compare double words
 
"scas" subtracts the destination string element from AL, AX, or EAX
(depending on the size of string element) and updates the flags AF, SF, ZF,
PF, CF and OF. If the values are equal, ZF is set, otherwise it is cleared.
The operand should be the destination string element addressed by DI or EDI.
 
scas byte [es:di] ; scan byte
scasw ; scan word
scas dword [es:edi] ; scan double word
 
"stos" places the value of AL, AX, or EAX into the destination string
element. Rules for the operand are the same as for the "scas" instruction.
"lods" places the source string element into AL, AX, or EAX. The operand
should be the source string element addressed by SI or ESI with any segment
prefix.
 
lods byte [ds:si] ; load byte
lods word [cs:si] ; load word
lodsd ; load double word
 
"ins" transfers a byte, word, or double word from an input port addressed
by DX register to the destination string element. The destination operand
should be memory addressed by DI or EDI, the source operand should be the DX
register.
 
insb ; input byte
ins word [es:di],dx ; input word
ins dword [edi],dx ; input double word
 
"outs" transfers the source string element to an output port addressed by
DX register. The destination operand should be the DX register and the source
operand should be memory addressed by SI or ESI with any segment prefix.
 
outs dx,byte [si] ; output byte
outsw ; output word
outs dx,dword [gs:esi] ; output double word
 
The repeat prefixes "rep", "repe"/"repz", and "repne"/"repnz" specify
repeated string operation. When a string operation instruction has a repeat
prefix, the operation is executed repeatedly, each time using a different
element of the string. The repetition terminates when one of the conditions
specified by the prefix is satisfied. All three prefixes automatically
decrease CX or ECX register (depending whether string operation instruction
uses the 16-bit or 32-bit addressing) after each operation and repeat the
associated operation until CX or ECX is zero. "repe"/"repz" and
"repne"/"repnz" are used exclusively with the "scas" and "cmps" instructions
(described below). When these prefixes are used, repetition of the next
instruction depends on the zero flag (ZF) also, "repe" and "repz" terminate
the execution when the ZF is zero, "repne" and "repnz" terminate the execution
when the ZF is set.
 
rep movsd ; transfer multiple double words
repe cmpsb ; compare bytes until not equal
 
 
2.1.9 Flag control instructions
 
The flag control instructions provide a method for directly changing the
state of bits in the flag register. All instructions described in this
section have no operands.
"stc" sets the CF (carry flag) to 1, "clc" zeroes the CF, "cmc" changes the
CF to its complement. "std" sets the DF (direction flag) to 1, "cld" zeroes
the DF, "sti" sets the IF (interrupt flag) to 1 and therefore enables the
interrupts, "cli" zeroes the IF and therefore disables the interrupts.
"lahf" copies SF, ZF, AF, PF, and CF to bits 7, 6, 4, 2, and 0 of the
AH register. The contents of the remaining bits are undefined. The flags
remain unaffected.
"sahf" transfers bits 7, 6, 4, 2, and 0 from the AH register into SF, ZF,
AF, PF, and CF.
"pushf" decrements "esp" by two or four and stores the low word or
double word of flags register at the top of stack, size of stored data
depends on the current code setting. "pushfw" variant forces storing the
word and "pushfd" forces storing the double word.
"popf" transfers specific bits from the word or double word at the top
of stack, then increments "esp" by two or four, this value depends on
the current code setting. "popfw" variant forces restoring from the word
and "popfd" forces restoring from the double word.
 
 
2.1.10 Conditional operations
 
The instructions obtained by attaching the condition mnemonic (see table
2.1) to the "set" mnemonic set a byte to one if the condition is true and set
the byte to zero otherwise. The operand should be an 8-bit be general register
or the byte in memory.
 
setne al ; set al if zero flag cleared
seto byte [bx] ; set byte if overflow
 
"salc" instruction sets the all bits of AL register when the carry flag is
set and zeroes the AL register otherwise. This instruction has no arguments.
The instructions obtained by attaching the condition mnemonic to "cmov"
mnemonic transfer the word or double word from the general register or memory
to the general register only when the condition is true. The destination
operand should be general register, the source operand can be general register
or memory.
 
cmove ax,bx ; move when zero flag set
cmovnc eax,[ebx] ; move when carry flag cleared
 
"cmpxchg" compares the value in the AL, AX, or EAX register with the
destination operand. If the two values are equal, the source operand is
loaded into the destination operand. Otherwise, the destination operand is
loaded into the AL, AX, or EAX register. The destination operand may be a
general register or memory, the source operand must be a general register.
 
cmpxchg dl,bl ; compare and exchange with register
cmpxchg [bx],dx ; compare and exchange with memory
 
"cmpxchg8b" compares the 64-bit value in EDX and EAX registers with the
destination operand. If the values are equal, the 64-bit value in ECX and EBX
registers is stored in the destination operand. Otherwise, the value in the
destination operand is loaded into EDX and EAX registers. The destination
operand should be a quad word in memory.
 
cmpxchg8b [bx] ; compare and exchange 8 bytes
 
 
2.1.11 Miscellaneous instructions
 
"nop" instruction occupies one byte but affects nothing but the instruction
pointer. This instruction has no operands and doesn't perform any operation.
"ud2" instruction generates an invalid opcode exception. This instruction
is provided for software testing to explicitly generate an invalid opcode.
This is instruction has no operands.
"xlat" replaces a byte in the AL register with a byte indexed by its value
in a translation table addressed by BX or EBX. The operand should be a byte
memory addressed by BX or EBX with any segment prefix. This instruction has
also a short form "xlatb" which has no operands and uses the BX or EBX address
in the segment selected by DS depending on the current code setting.
"lds" transfers a pointer variable from the source operand to DS and the
destination register. The source operand must be a memory operand, and the
destination operand must be a general register. The DS register receives the
segment selector of the pointer while the destination register receives the
offset part of the pointer. "les", "lfs", "lgs" and "lss" operate identically
to "lds" except that rather than DS register the ES, FS, GS and SS is used
respectively.
 
lds bx,[si] ; load pointer to ds:bx
 
"lea" transfers the offset of the source operand (rather than its value)
to the destination operand. The source operand must be a memory operand, and
the destination operand must be a general register.
 
lea dx,[bx+si+1] ; load effective address to dx
 
"cpuid" returns processor identification and feature information in the
EAX, EBX, ECX, and EDX registers. The information returned is selected by
entering a value in the EAX register before the instruction is executed.
This instruction has no operands.
"pause" instruction delays the execution of the next instruction an
implementation specific amount of time. It can be used to improve the
performance of spin wait loops. This instruction has no operands.
"enter" creates a stack frame that may be used to implement the scope rules
of block-structured high-level languages. A "leave" instruction at the end of
a procedure complements an "enter" at the beginning of the procedure to
simplify stack management and to control access to variables for nested
procedures. The "enter" instruction includes two parameters. The first
parameter specifies the number of bytes of dynamic storage to be allocated on
the stack for the routine being entered. The second parameter corresponds to
the lexical nesting level of the routine, it can be in range from 0 to 31.
The specified lexical level determines how many sets of stack frame pointers
the CPU copies into the new stack frame from the preceding frame. This list
of stack frame pointers is sometimes called the display. The first word (or
double word when code is 32-bit) of the display is a pointer to the last stack
frame. This pointer enables a "leave" instruction to reverse the action of the
previous "enter" instruction by effectively discarding the last stack frame.
After "enter" creates the new display for a procedure, it allocates the
dynamic storage space for that procedure by decrementing ESP by the number of
bytes specified in the first parameter. To enable a procedure to address its
display, "enter" leaves BP (or EBP) pointing to the beginning of the new stack
frame. If the lexical level is zero, "enter" pushes BP (or EBP), copies SP to
BP (or ESP to EBP) and then subtracts the first operand from ESP. For nesting
levels greater than zero, the processor pushes additional frame pointers on
the stack before adjusting the stack pointer.
 
enter 2048,0 ; enter and allocate 2048 bytes on stack
 
 
2.1.12 System instructions
 
"lmsw" loads the operand into the machine status word (bits 0 through 15 of
CR0 register), while "smsw" stores the machine status word into the
destination operand. The operand for both those instructions can be 16-bit
general register or memory, for "smsw" it can also be 32-bit general
register.
 
lmsw ax ; load machine status from register
smsw [bx] ; store machine status to memory
 
"lgdt" and "lidt" instructions load the values in operand into the global
descriptor table register or the interrupt descriptor table register
respectively. "sgdt" and "sidt" store the contents of the global descriptor
table register or the interrupt descriptor table register in the destination
operand. The operand should be a 6 bytes in memory.
 
lgdt [ebx] ; load global descriptor table
 
"lldt" loads the operand into the segment selector field of the local
descriptor table register and "sldt" stores the segment selector from the
local descriptor table register in the operand. "ltr" loads the operand into
the segment selector field of the task register and "str" stores the segment
selector from the task register in the operand. Rules for operand are the same
as for the "lmsw" and "smsw" instructions.
"lar" loads the access rights from the segment descriptor specified by
the selector in source operand into the destination operand and sets the ZF
flag. The destination operand can be a 16-bit or 32-bit general register.
The source operand should be a 16-bit general register or memory.
 
lar ax,[bx] ; load access rights into word
lar eax,dx ; load access rights into double word
 
"lsl" loads the segment limit from the segment descriptor specified by the
selector in source operand into the destination operand and sets the ZF flag.
Rules for operand are the same as for the "lar" instruction.
"verr" and "verw" verify whether the code or data segment specified with
the operand is readable or writable from the current privilege level. The
operand should be a word, it can be general register or memory. If the segment
is accessible and readable (for "verr") or writable (for "verw") the ZF flag
is set, otherwise it's cleared. Rules for operand are the same as for the
"lldt" instruction.
"arpl" compares the RPL (requestor's privilege level) fields of two segment
selectors. The first operand contains one segment selector and the second
operand contains the other. If the RPL field of the destination operand is
less than the RPL field of the source operand, the ZF flag is set and the RPL
field of the destination operand is increased to match that of the source
operand. Otherwise, the ZF flag is cleared and no change is made to the
destination operand. The destination operand can be a word general register
or memory, the source operand must be a general register.
 
arpl bx,ax ; adjust RPL of selector in register
arpl [bx],ax ; adjust RPL of selector in memory
 
"clts" clears the TS (task switched) flag in the CR0 register. This
instruction has no operands.
"lock" prefix causes the processor's bus-lock signal to be asserted during
execution of the accompanying instruction. In a multiprocessor environment,
the bus-lock signal insures that the processor has exclusive use of any shared
memory while the signal is asserted. The "lock" prefix can be prepended only
to the following instructions and only to those forms of the instructions
where the destination operand is a memory operand: "add", "adc", "and", "btc",
"btr", "bts", "cmpxchg", "cmpxchg8b", "dec", "inc", "neg", "not", "or", "sbb",
"sub", "xor", "xadd" and "xchg". If the "lock" prefix is used with one of
these instructions and the source operand is a memory operand, an undefined
opcode exception may be generated. An undefined opcode exception will also be
generated if the "lock" prefix is used with any instruction not in the above
list. The "xchg" instruction always asserts the bus-lock signal regardless of
the presence or absence of the "lock" prefix.
"hlt" stops instruction execution and places the processor in a halted
state. An enabled interrupt, a debug exception, the BINIT, INIT or the RESET
signal will resume execution. This instruction has no operands.
"invlpg" invalidates (flushes) the TLB (translation lookaside buffer) entry
specified with the operand, which should be a memory. The processor determines
the page that contains that address and flushes the TLB entry for that page.
"rdmsr" loads the contents of a 64-bit MSR (model specific register) of the
address specified in the ECX register into registers EDX and EAX. "wrmsr"
writes the contents of registers EDX and EAX into the 64-bit MSR of the
address specified in the ECX register. "rdtsc" loads the current value of the
processor's time stamp counter from the 64-bit MSR into the EDX and EAX
registers. The processor increments the time stamp counter MSR every clock
cycle and resets it to 0 whenever the processor is reset. "rdpmc" loads the
contents of the 40-bit performance monitoring counter specified in the ECX
register into registers EDX and EAX. These instructions have no operands.
"wbinvd" writes back all modified cache lines in the processor's internal
cache to main memory and invalidates (flushes) the internal caches. The
instruction then issues a special function bus cycle that directs external
caches to also write back modified data and another bus cycle to indicate that
the external caches should be invalidated. This instruction has no operands.
"rsm" return program control from the system management mode to the program
that was interrupted when the processor received an SMM interrupt. This
instruction has no operands.
"sysenter" executes a fast call to a level 0 system procedure, "sysexit"
executes a fast return to level 3 user code. The addresses used by these
instructions are stored in MSRs. These instructions have no operands.
 
 
2.1.13 FPU instructions
 
The FPU (Floating-Point Unit) instructions operate on the floating-point
values in three formats: single precision (32-bit), double precision (64-bit)
and double extended precision (80-bit). The FPU registers form the stack and
each of them holds the double extended precision floating-point value. When
some values are pushed onto the stack or are removed from the top, the FPU
registers are shifted, so ST0 is always the value on the top of FPU stack, ST1
is the first value below the top, etc. The ST0 name has also the synonym ST.
"fld" pushes the floating-point value onto the FPU register stack. The
operand can be 32-bit, 64-bit or 80-bit memory location or the FPU register,
its value is then loaded onto the top of FPU register stack (the ST0
register) and is automatically converted into the double extended precision
format.
 
fld dword [bx] ; load single prevision value from memory
fld st2 ; push value of st2 onto register stack
 
"fld1", "fldz", "fldl2t", "fldl2e", "fldpi", "fldlg2" and "fldln2" load the
commonly used contants onto the FPU register stack. The loaded constants are
+1.0, +0.0, lb 10, lb e, pi, lg 2 and ln 2 respectively. These instructions
have no operands.
"fild" converts the signed integer source operand into double extended
precision floating-point format and pushes the result onto the FPU register
stack. The source operand can be a 16-bit, 32-bit or 64-bit memory location.
 
fild qword [bx] ; load 64-bit integer from memory
 
"fst" copies the value of ST0 register to the destination operand, which
can be 32-bit or 64-bit memory location or another FPU register. "fstp"
performs the same operation as "fst" and then pops the register stack,
getting rid of ST0. "fstp" accepts the same operands as the "fst" instruction
and can also store value in the 80-bit memory.
 
fst st3 ; copy value of st0 into st3 register
fstp tword [bx] ; store value in memory and pop stack
 
"fist" converts the value in ST0 to a signed integer and stores the result
in the destination operand. The operand can be 16-bit or 32-bit memory
location. "fistp" performs the same operation and then pops the register
stack, it accepts the same operands as the "fist" instruction and can also
store integer value in the 64-bit memory, so it has the same rules for
operands as "fild" instruction.
"fbld" converts the packed BCD integer into double extended precision
floating-point format and pushes this value onto the FPU stack. "fbstp"
converts the value in ST0 to an 18-digit packed BCD integer, stores the result
in the destination operand, and pops the register stack. The operand should be
an 80-bit memory location.
"fadd" adds the destination and source operand and stores the sum in the
destination location. The destination operand is always an FPU register, if
the source is a memory location, the destination is ST0 register and only
source operand should be specified. If both operands are FPU registers, at
least one of them should be ST0 register. An operand in memory can be a
32-bit or 64-bit value.
 
fadd qword [bx] ; add double precision value to st0
fadd st2,st0 ; add st0 to st2
 
"faddp" adds the destination and source operand, stores the sum in the
destination location and then pops the register stack. The destination operand
must be an FPU register and the source operand must be the ST0. When no
operands are specified, ST1 is used as a destination operand.
 
faddp ; add st0 to st1 and pop the stack
faddp st2,st0 ; add st0 to st2 and pop the stack
 
"fiadd" instruction converts an integer source operand into double extended
precision floating-point value and adds it to the destination operand. The
operand should be a 16-bit or 32-bit memory location.
 
fiadd word [bx] ; add word integer to st0
 
"fsub", "fsubr", "fmul", "fdiv", "fdivr" instruction are similar to "fadd",
have the same rules for operands and differ only in the perfomed computation.
"fsub" substracts the source operand from the destination operand, "fsubr"
substract the destination operand from the source operand, "fmul" multiplies
the destination and source operands, "fdiv" divides the destination operand by
the source operand and "fdivr" divides the source operand by the destination
operand. "fsubp", "fsubrp", "fmulp", "fdivp", "fdivrp" perform the same
operations and pop the register stack, the rules for operand are the same as
for the "faddp" instruction. "fisub", "fisubr", "fimul", "fidiv", "fidivr"
perform these operations after converting the integer source operand into
floating-point value, they have the same rules for operands as "fiadd"
instruction.
"fsqrt" computes the square root of the value in ST0 register, "fsin"
computes the sine of that value, "fcos" computes the cosine of that value,
"fchs" complements its sign bit, "fabs" clears its sign to create the absolute
value, "frndint" rounds it to the nearest integral value, depending on the
current rounding mode. "f2xm1" computes the exponential value of 2 to the
power of ST0 and substracts the 1.0 from it, the value of ST0 must lie in the
range -1.0 to +1.0. All these instructions store the result in ST0 and have no
operands.
"fsincos" computes both the sine and the cosine of the value in ST0
register, stores the sine in ST0 and pushes the cosine on the top of FPU
register stack. "fptan" computes the tangent of the value in ST0, stores the
result in ST0 and pushes a 1.0 onto the FPU register stack. "fpatan" computes
the arctangent of the value in ST1 divided by the value in ST0, stores the
result in ST1 and pops the FPU register stack. "fyl2x" computes the binary
logarithm of ST0, multiplies it by ST1, stores the result in ST1 and pops the
FPU register stack; "fyl2xp1" performs the same operation but it adds 1.0 to
ST0 before computing the logarithm. "fprem" computes the remainder obtained
from dividing the value in ST0 by the value in ST1, and stores the result
in ST0. "fprem1" performs the same operation as "fprem", but it computes the
remainder in the way specified by IEEE Standard 754. "fscale" truncates the
value in ST1 and increases the exponent of ST0 by this value. "fxtract"
separates the value in ST0 into its exponent and significand, stores the
exponent in ST0 and pushes the significand onto the register stack. "fnop"
performs no operation. These instructions have no operands.
"fxch" exchanges the contents of ST0 an another FPU register. The operand
should be an FPU register, if no operand is specified, the contents of ST0 and
ST1 are exchanged.
"fcom" and "fcomp" compare the contents of ST0 and the source operand and
set flags in the FPU status word according to the results. "fcomp"
additionally pops the register stack after performing the comparison. The
operand can be a single or double precision value in memory or the FPU
register. When no operand is specified, ST1 is used as a source operand.
 
fcom ; compare st0 with st1
fcomp st2 ; compare st0 with st2 and pop stack
 
"fcompp" compares the contents of ST0 and ST1, sets flags in the FPU status
word according to the results and pops the register stack twice. This
instruction has no operands.
"fucom", "fucomp" and "fucompp" performs an unordered comparison of two FPU
registers. Rules for operands are the same as for the "fcom", "fcomp" and
"fcompp", but the source operand must be an FPU register.
"ficom" and "ficomp" compare the value in ST0 with an integer source operand
and set the flags in the FPU status word according to the results. "ficomp"
additionally pops the register stack after performing the comparison. The
integer value is converted to double extended precision floating-point format
before the comparison is made. The operand should be a 16-bit or 32-bit
memory location.
 
ficom word [bx] ; compare st0 with 16-bit integer
 
"fcomi", "fcomip", "fucomi", "fucomip" perform the comparison of ST0 with
another FPU register and set the ZF, PF and CF flags according to the results.
"fcomip" and "fucomip" additionaly pop the register stack after performing the
comparison. The instructions obtained by attaching the FPU condition mnemonic
(see table 2.2) to the "fcmov" mnemonic transfer the specified FPU register
into ST0 register if the given test condition is true. These instructions
allow two different syntaxes, one with single operand specifying the source
FPU register, and one with two operands, in that case destination operand
should be ST0 register and the second operand specifies the source FPU
register.
 
fcomi st2 ; compare st0 with st2 and set flags
fcmovb st0,st2 ; transfer st2 to st0 if below
 
Table 2.2 FPU conditions
/------------------------------------------------------\
| Mnemonic | Condition tested | Description |
|==========|==================|========================|
| b | CF = 1 | below |
| e | ZF = 1 | equal |
| be | CF or ZF = 1 | below or equal |
| u | PF = 1 | unordered |
| nb | CF = 0 | not below |
| ne | ZF = 0 | not equal |
| nbe | CF and ZF = 0 | not below nor equal |
| nu | PF = 0 | not unordered |
\------------------------------------------------------/
 
"ftst" compares the value in ST0 with 0.0 and sets the flags in the FPU
status word according to the results. "fxam" examines the contents of the ST0
and sets the flags in FPU status word to indicate the class of value in the
register. These instructions have no operands.
"fstsw" and "fnstsw" store the current value of the FPU status word in the
destination location. The destination operand can be either a 16-bit memory or
the AX register. "fstsw" checks for pending unmasked FPU exceptions before
storing the status word, "fnstsw" does not.
"fstcw" and "fnstcw" store the current value of the FPU control word at the
specified destination in memory. "fstcw" checks for pending umasked FPU
exceptions before storing the control word, "fnstcw" does not. "fldcw" loads
the operand into the FPU control word. The operand should be a 16-bit memory
location.
"fstenv" and "fnstenv" store the current FPU operating environment at the
memory location specified with the destination operand, and then mask all FPU
exceptions. "fstenv" checks for pending umasked FPU exceptions before
proceeding, "fnstenv" does not. "fldenv" loads the complete operating
environment from memory into the FPU. "fsave" and "fnsave" store the current
FPU state (operating environment and register stack) at the specified
destination in memory and reinitializes the FPU. "fsave" check for pending
unmasked FPU exceptions before proceeding, "fnsave" does not. "frstor"
loads the FPU state from the specified memory location. All these instructions
need an operand being a memory location. For each of these instructions
exist two additional mnemonics that allow to precisely select the type of the
operation. The "fstenvw", "fnstenvw", "fldenvw", "fsavew", "fnsavew" and
"frstorw" mnemonics force the instruction to perform operation as in the 16-bit
mode, while "fstenvd", "fnstenvd", "fldenvd", "fsaved", "fnsaved" and "frstord"
force the operation as in 32-bit mode.
"finit" and "fninit" set the FPU operating environment into its default
state. "finit" checks for pending unmasked FPU exception before proceeding,
"fninit" does not. "fclex" and "fnclex" clear the FPU exception flags in the
FPU status word. "fclex" checks for pending unmasked FPU exception before
proceeding, "fnclex" does not. "wait" and "fwait" are synonyms for the same
instruction, which causes the processor to check for pending unmasked FPU
exceptions and handle them before proceeding. These instructions have no
operands.
"ffree" sets the tag associated with specified FPU register to empty. The
operand should be an FPU register.
"fincstp" and "fdecstp" rotate the FPU stack by one by adding or
substracting one to the pointer of the top of stack. These instructions have no
operands.
 
 
2.1.14 MMX instructions
 
The MMX instructions operate on the packed integer types and use the MMX
registers, which are the low 64-bit parts of the 80-bit FPU registers. Because
of this MMX instructions cannot be used at the same time as FPU instructions.
They can operate on packed bytes (eight 8-bit integers), packed words (four
16-bit integers) or packed double words (two 32-bit integers), use of packed
formats allows to perform operations on multiple data at one time.
"movq" copies a quad word from the source operand to the destination
operand. At least one of the operands must be a MMX register, the second one
can be also a MMX register or 64-bit memory location.
 
movq mm0,mm1 ; move quad word from register to register
movq mm2,[ebx] ; move quad word from memory to register
 
"movd" copies a double word from the source operand to the destination
operand. One of the operands must be a MMX register, the second one can be a
general register or 32-bit memory location. Only low double word of MMX
register is used.
All general MMX operations have two operands, the destination operand should
be a MMX register, the source operand can be a MMX register or 64-bit memory
location. Operation is performed on the corresponding data elements of the
source and destination operand and stored in the data elements of the
destination operand. "paddb", "paddw" and "paddd" perform the addition of
packed bytes, packed words, or packed double words. "psubb", "psubw" and
"psubd" perform the substraction of appropriate types. "paddsb", "paddsw",
"psubsb" and "psubsw" perform the addition or substraction of packed bytes
or packed words with the signed saturation. "paddusb", "paddusw", "psubusb",
"psubusw" are analoguous, but with unsigned saturation. "pmulhw" and "pmullw"
performs a signed multiplication of the packed words and store the high or low
words of the results in the destination operand. "pmaddwd" performs a multiply
of the packed words and adds the four intermediate double word products in
pairs to produce result as a packed double words. "pand", "por" and "pxor"
perform the logical operations on the quad words, "pandn" peforms also a
logical negation of the destination operand before performing the "and"
operation. "pcmpeqb", "pcmpeqw" and "pcmpeqd" compare for equality of packed
bytes, packed words or packed double words. If a pair of data elements is
equal, the corresponding data element in the destination operand is filled with
bits of value 1, otherwise it's set to 0. "pcmpgtb", "pcmpgtw" and "pcmpgtd"
perform the similar operation, but they check whether the data elements in the
destination operand are greater than the correspoding data elements in the
source operand. "packsswb" converts packed signed words into packed signed
bytes, "packssdw" converts packed signed double words into packed signed
words, using saturation to handle overflow conditions. "packuswb" converts
packed signed words into packed unsigned bytes. Converted data elements from
the source operand are stored in the low part of the destination operand,
while converted data elements from the destination operand are stored in the
high part. "punpckhbw", "punpckhwd" and "punpckhdq" interleaves the data
elements from the high parts of the source and destination operands and
stores the result into the destination operand. "punpcklbw", "punpcklwd" and
"punpckldq" perform the same operation, but the low parts of the source and
destination operand are used.
 
paddsb mm0,[esi] ; add packed bytes with signed saturation
pcmpeqw mm3,mm7 ; compare packed words for equality
 
"psllw", "pslld" and "psllq" perform logical shift left of the packed words,
packed double words or a single quad word in the destination operand by the
amount specified in the source operand. "psrlw", "psrld" and "psrlq" perform
logical shift right of the packed words, packed double words or a single quad
word. "psraw" and "psrad" perform arithmetic shift of the packed words or
double words. The destination operand should be a MMX register, while source
operand can be a MMX register, 64-bit memory location, or 8-bit immediate
value.
 
psllw mm2,mm4 ; shift words left logically
psrad mm4,[ebx] ; shift double words right arithmetically
 
"emms" makes the FPU registers usable for the FPU instructions, it must be
used before using the FPU instructions if any MMX instructions were used.
 
 
2.1.15 SSE instructions
 
The SSE extension adds more MMX instructions and also introduces the
operations on packed single precision floating point values. The 128-bit
packed single precision format consists of four single precision floating
point values. The 128-bit SSE registers are designed for the purpose of
operations on this data type.
"movaps" and "movups" transfer a double quad word operand containing packed
single precision values from source operand to destination operand. At least
one of the operands have to be a SSE register, the second one can be also a
SSE register or 128-bit memory location. Memory operands for "movaps"
instruction must be aligned on boundary of 16 bytes, operands for "movups"
instruction don't have to be aligned.
 
movups xmm0,[ebx] ; move unaligned double quad word
 
"movlps" moves packed two single precision values between the memory and the
low quad word of SSE register. "movhps" moved packed two single precision
values between the memory and the high quad word of SSE register. One of the
operands must be a SSE register, and the other operand must be a 64-bit memory
location.
 
movlps xmm0,[ebx] ; move memory to low quad word of xmm0
movhps [esi],xmm7 ; move high quad word of xmm7 to memory
 
"movlhps" moves packed two single precision values from the low quad word
of source register to the high quad word of destination register. "movhlps"
moves two packed single precision values from the high quad word of source
register to the low quad word of destination register. Both operands have to
be a SSE registers.
"movmskps" transfers the most significant bit of each of the four single
precision values in the SSE register into low four bits of a general register.
The source operand must be a SSE register, the destination operand must be a
general register.
"movss" transfers a single precision value between source and destination
operand (only the low double word is trasferred). At least one of the operands
have to be a SSE register, the second one can be also a SSE register or 32-bit
memory location.
 
movss [edi],xmm3 ; move low double word of xmm3 to memory
 
Each of the SSE arithmetic operations has two variants. When the mnemonic
ends with "ps", the source operand can be a 128-bit memory location or a SSE
register, the destination operand must be a SSE register and the operation is
performed on packed four single precision values, for each pair of the
corresponding data elements separately, the result is stored in the
destination register. When the mnemonic ends with "ss", the source operand
can be a 32-bit memory location or a SSE register, the destination operand
must be a SSE register and the operation is performed on single precision
values, only low double words of SSE registers are used in this case, the
result is stored in the low double word of destination register. "addps" and
"addss" add the values, "subps" and "subss" substract the source value from
destination value, "mulps" and "mulss" multiply the values, "divps" and
"divss" divide the destination value by the source value, "rcpps" and "rcpss"
compute the approximate reciprocal of the source value, "sqrtps" and "sqrtss"
compute the square root of the source value, "rsqrtps" and "rsqrtss" compute
the approximate reciprocal of square root of the source value, "maxps" and
"maxss" compare the source and destination values and return the greater one,
"minps" and "minss" compare the source and destination values and return the
lesser one.
 
mulss xmm0,[ebx] ; multiply single precision values
addps xmm3,xmm7 ; add packed single precision values
 
"andps", "andnps", "orps" and "xorps" perform the logical operations on
packed single precision values. The source operand can be a 128-bit memory
location or a SSE register, the destination operand must be a SSE register.
"cmpps" compares packed single precision values and returns a mask result
into the destination operand, which must be a SSE register. The source operand
can be a 128-bit memory location or SSE register, the third operand must be an
immediate operand selecting code of one of the eight compare conditions
(table 2.3). "cmpss" performs the same operation on single precision values,
only low double word of destination register is affected, in this case source
operand can be a 32-bit memory location or SSE register. These two
instructions have also variants with only two operands and the condition
encoded within mnemonic. Their mnemonics are obtained by attaching the
mnemonic from table 2.3 to the "cmp" mnemonic and then attaching the "ps" or
"ss" at the end.
 
cmpps xmm2,xmm4,0 ; compare packed single precision values
cmpltss xmm0,[ebx] ; compare single precision values
 
Table 2.3 SSE conditions
/-------------------------------------------\
| Code | Mnemonic | Description |
|======|==========|=========================|
| 0 | eq | equal |
| 1 | lt | less than |
| 2 | le | less than or equal |
| 3 | unord | unordered |
| 4 | neq | not equal |
| 5 | nlt | not less than |
| 6 | nle | not less than nor equal |
| 7 | ord | ordered |
\-------------------------------------------/
 
"comiss" and "ucomiss" compare the single precision values and set the ZF,
PF and CF flags to show the result. The destination operand must be a SSE
register, the source operand can be a 32-bit memory location or SSE register.
"shufps" moves any two of the four single precision values from the
destination operand into the low quad word of the destination operand, and any
two of the four values from the source operand into the high quad word of the
destination operand. The destination operand must be a SSE register, the
source operand can be a 128-bit memory location or SSE register, the third
operand must be an 8-bit immediate value selecting which values will be moved
into the destination operand. Bits 0 and 1 select the value to be moved from
destination operand to the low double word of the result, bits 2 and 3 select
the value to be moved from the destination operand to the second double word,
bits 4 and 5 select the value to be moved from the source operand to the third
double word, and bits 6 and 7 select the value to be moved from the source
operand to the high double word of the result.
 
shufps xmm0,xmm0,10010011b ; shuffle double words
 
"unpckhps" performs an interleaved unpack of the values from the high parts
of the source and destination operands and stores the result in the
destination operand, which must be a SSE register. The source operand can be
a 128-bit memory location or a SSE register. "unpcklps" performs an
interleaved unpack of the values from the low parts of the source and
destination operand and stores the result in the destination operand,
the rules for operands are the same.
"cvtpi2ps" converts packed two double word integers into the the packed two
single precision floating point values and stores the result in the low quad
word of the destination operand, which should be a SSE register. The source
operand can be a 64-bit memory location or MMX register.
 
cvtpi2ps xmm0,mm0 ; convert integers to single precision values
 
"cvtsi2ss" converts a double word integer into a single precision floating
point value and stores the result in the low double word of the destination
operand, which should be a SSE register. The source operand can be a 32-bit
memory location or 32-bit general register.
 
cvtsi2ss xmm0,eax ; convert integer to single precision value
 
"cvtps2pi" converts packed two single precision floating point values into
packed two double word integers and stores the result in the destination
operand, which should be a MMX register. The source operand can be a 64-bit
memory location or SSE register, only low quad word of SSE register is used.
"cvttps2pi" performs the similar operation, except that truncation is used to
round a source values to integers, rules for the operands are the same.
 
cvtps2pi mm0,xmm0 ; convert single precision values to integers
 
"cvtss2si" convert a single precision floating point value into a double
word integer and stores the result in the destination operand, which should be
a 32-bit general register. The source operand can be a 32-bit memory location
or SSE register, only low double word of SSE register is used. "cvttss2si"
performs the similar operation, except that truncation is used to round a
source value to integer, rules for the operands are the same.
 
cvtss2si eax,xmm0 ; convert single precision value to integer
 
"pextrw" copies the word in the source operand specified by the third
operand to the destination operand. The source operand must be a MMX register,
the destination operand must be a 32-bit general register (the high word of
the destination is cleared), the third operand must an 8-bit immediate value.
 
pextrw eax,mm0,1 ; extract word into eax
 
"pinsrw" inserts a word from the source operand in the destination operand
at the location specified with the third operand, which must be an 8-bit
immediate value. The destination operand must be a MMX register, the source
operand can be a 16-bit memory location or 32-bit general register (only low
word of the register is used).
 
pinsrw mm1,ebx,2 ; insert word from ebx
 
"pavgb" and "pavgw" compute average of packed bytes or words. "pmaxub"
return the maximum values of packed unsigned bytes, "pminub" returns the
minimum values of packed unsigned bytes, "pmaxsw" returns the maximum values
of packed signed words, "pminsw" returns the minimum values of packed signed
words. "pmulhuw" performs a unsigned multiplication of the packed words and
stores the high words of the results in the destination operand. "psadbw"
computes the absolute differences of packed unsigned bytes, sums the
differences, and stores the sum in the low word of destination operand. All
these instructions follow the same rules for operands as the general MMX
operations described in previous section.
"pmovmskb" creates a mask made of the most significant bit of each byte in
the source operand and stores the result in the low byte of destination
operand. The source operand must be a MMX register, the destination operand
must a 32-bit general register.
"pshufw" inserts words from the source operand in the destination operand
from the locations specified with the third operand. The destination operand
must be a MMX register, the source operand can be a 64-bit memory location or
MMX register, third operand must an 8-bit immediate value selecting which
values will be moved into destination operand, in the similar way as the third
operand of the "shufps" instruction.
"movntq" moves the quad word from the source operand to memory using a
non-temporal hint to minimize cache pollution. The source operand should be a
MMX register, the destination operand should be a 64-bit memory location.
"movntps" stores packed single precision values from the SSE register to
memory using a non-temporal hint. The source operand should be a SSE register,
the destination operand should be a 128-bit memory location. "maskmovq" stores
selected bytes from the first operand into a 64-bit memory location using a
non-temporal hint. Both operands should be a MMX registers, the second operand
selects wich bytes from the source operand are written to memory. The
memory location is pointed by DI (or EDI) register in the segment selected
by DS.
"prefetcht0", "prefetcht1", "prefetcht2" and "prefetchnta" fetch the line
of data from memory that contains byte specified with the operand to a
specified location in hierarchy. The operand should be an 8-bit memory
location.
"sfence" performs a serializing operation on all instruction storing to
memory that were issued prior to it. This instruction has no operands.
"ldmxcsr" loads the 32-bit memory operand into the MXCSR register. "stmxcsr"
stores the contents of MXCSR into a 32-bit memory operand.
"fxsave" saves the current state of the FPU, MXCSR register, and all the FPU
and SSE registers to a 512-byte memory location specified in the destination
operand. "fxrstor" reloads data previously stored with "fxsave" instruction
from the specified 512-byte memory location. The memory operand for both those
instructions must be aligned on 16 byte boundary, it should declare operand
of no specified size.
 
 
2.1.16 SSE2 instructions
 
The SSE2 extension introduces the operations on packed double precision
floating point values, extends the syntax of MMX instructions, and adds also
some new instructions.
"movapd" and "movupd" transfer a double quad word operand containing packed
double precision values from source operand to destination operand. These
instructions are analogous to "movaps" and "movups" and have the same rules
for operands.
"movlpd" moves double precision value between the memory and the low quad
word of SSE register. "movhpd" moved double precision value between the memory
and the high quad word of SSE register. These instructions are analogous to
"movlps" and "movhps" and have the same rules for operands.
"movmskpd" transfers the most significant bit of each of the two double
precision values in the SSE register into low two bits of a general register.
This instruction is analogous to "movmskps" and has the same rules for
operands.
"movsd" transfers a double precision value between source and destination
operand (only the low quad word is trasferred). At least one of the operands
have to be a SSE register, the second one can be also a SSE register or 64-bit
memory location.
Arithmetic operations on double precision values are: "addpd", "addsd",
"subpd", "subsd", "mulpd", "mulsd", "divpd", "divsd", "sqrtpd", "sqrtsd",
"maxpd", "maxsd", "minpd", "minsd", and they are analoguous to arithmetic
operations on single precision values described in previous section. When the
mnemonic ends with "pd" instead of "ps", the operation is performed on packed
two double precision values, but rules for operands are the same. When the
mnemonic ends with "sd" instead of "ss", the source operand can be a 64-bit
memory location or a SSE register, the destination operand must be a SSE
register and the operation is performed on double precision values, only low
quad words of SSE registers are used in this case.
"andpd", "andnpd", "orpd" and "xorpd" perform the logical operations on
packed double precision values. They are analoguous to SSE logical operations
on single prevision values and have the same rules for operands.
"cmppd" compares packed double precision values and returns and returns a
mask result into the destination operand. This instruction is analoguous to
"cmpps" and has the same rules for operands. "cmpsd" performs the same
operation on double precision values, only low quad word of destination
register is affected, in this case source operand can be a 64-bit memory or
SSE register. Variant with only two operands are obtained by attaching the
condition mnemonic from table 2.3 to the "cmp" mnemonic and then attaching
the "pd" or "sd" at the end.
"comisd" and "ucomisd" compare the double precision values and set the ZF,
PF and CF flags to show the result. The destination operand must be a SSE
register, the source operand can be a 128-bit memory location or SSE register.
"shufpd" moves any of the two double precision values from the destination
operand into the low quad word of the destination operand, and any of the two
values from the source operand into the high quad word of the destination
operand. This instruction is analoguous to "shufps" and has the same rules for
operand. Bit 0 of the third operand selects the value to be moved from the
destination operand, bit 1 selects the value to be moved from the source
operand, the rest of bits are reserved and must be zeroed.
"unpckhpd" performs an unpack of the high quad words from the source and
destination operands, "unpcklpd" performs an unpack of the low quad words from
the source and destination operands. They are analoguous to "unpckhps" and
"unpcklps", and have the same rules for operands.
"cvtps2pd" converts the packed two single precision floating point values to
two packed double precision floating point values, the destination operand
must be a SSE register, the source operand can be a 64-bit memory location or
SSE register. "cvtpd2ps" converts the packed two double precision floating
point values to packed two single precision floating point values, the
destination operand must be a SSE register, the source operand can be a
128-bit memory location or SSE register. "cvtss2sd" converts the single
precision floating point value to double precision floating point value, the
destination operand must be a SSE register, the source operand can be a 32-bit
memory location or SSE register. "cvtsd2ss" converts the double precision
floating point value to single precision floating point value, the destination
operand must be a SSE register, the source operand can be 64-bit memory
location or SSE register.
"cvtpi2pd" converts packed two double word integers into the the packed
double precision floating point values, the destination operand must be a SSE
register, the source operand can be a 64-bit memory location or MMX register.
"cvtsi2sd" converts a double word integer into a double precision floating
point value, the destination operand must be a SSE register, the source
operand can be a 32-bit memory location or 32-bit general register. "cvtpd2pi"
converts packed double precision floating point values into packed two double
word integers, the destination operand should be a MMX register, the source
operand can be a 128-bit memory location or SSE register. "cvttpd2pi" performs
the similar operation, except that truncation is used to round a source values
to integers, rules for operands are the same. "cvtsd2si" converts a double
precision floating point value into a double word integer, the destination
operand should be a 32-bit general register, the source operand can be a
64-bit memory location or SSE register. "cvttsd2si" performs the similar
operation, except that truncation is used to round a source value to integer,
rules for operands are the same.
"cvtps2dq" and "cvttps2dq" convert packed single precision floating point
values to packed four double word integers, storing them in the destination
operand. "cvtpd2dq" and "cvttpd2dq" convert packed double precision floating
point values to packed two double word integers, storing the result in the low
quad word of the destination operand. "cvtdq2ps" converts packed four
double word integers to packed single precision floating point values.
For all these instructions destination operand must be a SSE register, the
source operand can be a 128-bit memory location or SSE register.
"cvtdq2pd" converts packed two double word integers from the source operand to
packed double precision floating point values, the source can be a 64-bit
memory location or SSE register, destination has to be SSE register.
"movdqa" and "movdqu" transfer a double quad word operand containing packed
integers from source operand to destination operand. At least one of the
operands have to be a SSE register, the second one can be also a SSE register
or 128-bit memory location. Memory operands for "movdqa" instruction must be
aligned on boundary of 16 bytes, operands for "movdqu" instruction don't have
to be aligned.
"movq2dq" moves the contents of the MMX source register to the low quad word
of destination SSE register. "movdq2q" moves the low quad word from the source
SSE register to the destination MMX register.
 
movq2dq xmm0,mm1 ; move from MMX register to SSE register
movdq2q mm0,xmm1 ; move from SSE register to MMX register
 
All MMX instructions operating on the 64-bit packed integers (those with
mnemonics starting with "p") are extended to operate on 128-bit packed
integers located in SSE registers. Additional syntax for these instructions
needs an SSE register where MMX register was needed, and the 128-bit memory
location or SSE register where 64-bit memory location or MMX register were
needed. The exception is "pshufw" instruction, which doesn't allow extended
syntax, but has two new variants: "pshufhw" and "pshuflw", which allow only
the extended syntax, and perform the same operation as "pshufw" on the high
or low quad words of operands respectively. Also the new instruction "pshufd"
is introduced, which performs the same operation as "pshufw", but on the
double words instead of words, it allows only the extended syntax.
 
psubb xmm0,[esi] ; substract 16 packed bytes
pextrw eax,xmm0,7 ; extract highest word into eax
 
"paddq" performs the addition of packed quad words, "psubq" performs the
substraction of packed quad words, "pmuludq" performs an unsigned
multiplication of low double words from each corresponding quad words and
returns the results in packed quad words. These instructions follow the same
rules for operands as the general MMX operations described in 2.1.14.
"pslldq" and "psrldq" perform logical shift left or right of the double
quad word in the destination operand by the amount of bytes specified in the
source operand. The destination operand should be a SSE register, source
operand should be an 8-bit immediate value.
"punpckhqdq" interleaves the high quad word of the source operand and the
high quad word of the destination operand and writes them to the destination
SSE register. "punpcklqdq" interleaves the low quad word of the source operand
and the low quad word of the destination operand and writes them to the
destination SSE register. The source operand can be a 128-bit memory location
or SSE register.
"movntdq" stores packed integer data from the SSE register to memory using
non-temporal hint. The source operand should be a SSE register, the
destination operand should be a 128-bit memory location. "movntpd" stores
packed double precision values from the SSE register to memory using a
non-temporal hint. Rules for operand are the same. "movnti" stores integer
from a general register to memory using a non-temporal hint. The source
operand should be a 32-bit general register, the destination operand should
be a 32-bit memory location. "maskmovdqu" stores selected bytes from the first
operand into a 128-bit memory location using a non-temporal hint. Both
operands should be a SSE registers, the second operand selects wich bytes from
the source operand are written to memory. The memory location is pointed by DI
(or EDI) register in the segment selected by DS and does not need to be
aligned.
"clflush" writes and invalidates the cache line associated with the address
of byte specified with the operand, which should be a 8-bit memory location.
"lfence" performs a serializing operation on all instruction loading from
memory that were issued prior to it. "mfence" performs a serializing operation
on all instruction accesing memory that were issued prior to it, and so it
combines the functions of "sfence" (described in previous section) and
"lfence" instructions. These instructions have no operands.
 
 
2.1.17 SSE3 instructions
 
Prescott technology introduced some new instructions to improve the performance
of SSE and SSE2 - this extension is called SSE3.
"fisttp" behaves like the "fistp" instruction and accepts the same operands,
the only difference is that it always used truncation, irrespective of the
rounding mode.
"movshdup" loads into destination operand the 128-bit value obtained from
the source value of the same size by filling the each quad word with the two
duplicates of the value in its high double word. "movsldup" performs the same
action, except it duplicates the values of low double words. The destination
operand should be SSE register, the source operand can be SSE register or
128-bit memory location.
"movddup" loads the 64-bit source value and duplicates it into high and low
quad word of the destination operand. The destination operand should be SSE
register, the source operand can be SSE register or 64-bit memory location.
"lddqu" is functionally equivalent to "movdqu" with memory as source
operand, but it may improve performance when the source operand crosses a
cacheline boundary. The destination operand has to be SSE register, the source
operand must be 128-bit memory location.
"addsubps" performs single precision addition of second and fourth pairs and
single precision substracion of the first and third pairs of floating point
values in the operands. "addsubpd" performs double precision addition of the
second pair and double precision substraction of the first pair of floating
point values in the operand. "haddps" performs the addition of two single
precision values within the each quad word of source and destination operands,
and stores the results of such horizontal addition of values from destination
operand into low quad word of destination operand, and the results from the
source operand into high quad word of destination operand. "haddpd" performs
the addition of two double precision values within each operand, and stores
the result from destination operand into low quad word of destination operand,
and the result from source operand into high quad word of destination operand.
All these instructions need the destination operand to be SSE register, source
operand can be SSE register or 128-bit memory location.
"monitor" sets up an address range for monitoring of write-back stores. It
need its three operands to be EAX, ECX and EDX register in that order. "mwait"
waits for a write-back store to the address range set up by the "monitor"
instruction. It uses two operands with additional parameters, first being the
EAX and second the ECX register.
The functionality of SSE3 is further extended by the set of Supplemental
SSE3 instructions (SSSE3). They generally follow the same rules for operands
as all the MMX operations extended by SSE.
"phaddw" and "phaddd" perform the horizontal additional of the pairs of
adjacent values from both the source and destination operand, and stores the
sums into the destination (sums from the source operand go into lower part of
destination register). They operate on 16-bit or 32-bit chunks, respectively.
"phaddsw" performs the same operation on signed 16-bit packed values, but the
result of each addition is saturated. "phsubw" and "phsubd" analogously
perform the horizontal substraction of 16-bit or 32-bit packed value, and
"phsubsw" performs the horizontal substraction of signed 16-bit packed values
with saturation.
"pabsb", "pabsw" and "pabsd" calculate the absolute value of each signed
packed signed value in source operand and stores them into the destination
register. They operator on 8-bit, 16-bit and 32-bit elements respectively.
"pmaddubsw" multiplies signed 8-bit values from the source operand with the
corresponding unsigned 8-bit values from the destination operand to produce
intermediate 16-bit values, and every adjacent pair of those intermediate
values is then added horizontally and those 16-bit sums are stored into the
destination operand.
"pmulhrsw" multiplies corresponding 16-bit integers from the source and
destination operand to produce intermediate 32-bit values, and the 16 bits
next to the highest bit of each of those values are then rounded and packed
into the destination operand.
"pshufb" shuffles the bytes in the destination operand according to the
mask provided by source operand - each of the bytes in source operand is
an index of the target position for the corresponding byte in the destination.
"psignb", "psignw" and "psignd" perform the operation on 8-bit, 16-bit or
32-bit integers in destination operand, depending on the signs of the values
in the source. If the value in source is negative, the corresponding value in
the destination register is negated, if the value in source is positive, no
operation is performed on the corresponding value is performed, and if the
value in source is zero, the value in destination is zeroed, too.
"palignr" appends the source operand to the destination operand to form the
intermediate value of twice the size, and then extracts into the destination
register the 64 or 128 bits that are right-aligned to the byte offset
specified by the third operand, which should be an 8-bit immediate value. This
is the only SSSE3 instruction that takes three arguments.
 
 
2.1.18 AMD 3DNow! instructions
 
The 3DNow! extension adds a new MMX instructions to those described in 2.1.14,
and introduces operation on the 64-bit packed floating point values, each
consisting of two single precision floating point values.
These instructions follow the same rules as the general MMX operations, the
destination operand should be a MMX register, the source operand can be a MMX
register or 64-bit memory location. "pavgusb" computes the rounded averages
of packed unsigned bytes. "pmulhrw" performs a signed multiplication of the
packed words, round the high word of each double word results and stores them
in the destination operand. "pi2fd" converts packed double word integers into
packed floating point values. "pf2id" converts packed floating point values
into packed double word integers using truncation. "pi2fw" converts packed
word integers into packed floating point values, only low words of each
double word in source operand are used. "pf2iw" converts packed floating
point values to packed word integers, results are extended to double words
using the sign extension. "pfadd" adds packed floating point values. "pfsub"
and "pfsubr" substracts packed floating point values, the first one substracts
source values from destination values, the second one substracts destination
values from the source values. "pfmul" multiplies packed floating point
values. "pfacc" adds the low and high floating point values of the destination
operand, storing the result in the low double word of destination, and adds
the low and high floating point values of the source operand, storing the
result in the high double word of destination. "pfnacc" substracts the high
floating point value of the destination operand from the low, storing the
result in the low double word of destination, and substracts the high floating
point value of the source operand from the low, storing the result in the high
double word of destination. "pfpnacc" substracts the high floating point value
of the destination operand from the low, storing the result in the low double
word of destination, and adds the low and high floating point values of the
source operand, storing the result in the high double word of destination.
"pfmax" and "pfmin" compute the maximum and minimum of floating point values.
"pswapd" reverses the high and low double word of the source operand. "pfrcp"
returns an estimates of the reciprocals of floating point values from the
source operand, "pfrsqrt" returns an estimates of the reciprocal square
roots of floating point values from the source operand, "pfrcpit1" performs
the first step in the Newton-Raphson iteration to refine the reciprocal
approximation produced by "pfrcp" instruction, "pfrsqit1" performs the first
step in the Newton-Raphson iteration to refine the reciprocal square root
approximation produced by "pfrsqrt" instruction, "pfrcpit2" performs the
second final step in the Newton-Raphson iteration to refine the reciprocal
approximation or the reciprocal square root approximation. "pfcmpeq",
"pfcmpge" and "pfcmpgt" compare the packed floating point values and sets
all bits or zeroes all bits of the correspoding data element in the
destination operand according to the result of comparison, first checks
whether values are equal, second checks whether destination value is greater
or equal to source value, third checks whether destination value is greater
than source value.
"prefetch" and "prefetchw" load the line of data from memory that contains
byte specified with the operand into the data cache, "prefetchw" instruction
should be used when the data in the cache line is expected to be modified,
otherwise the "prefetch" instruction should be used. The operand should be an
8-bit memory location.
"femms" performs a fast clear of MMX state. This instruction has no
operands.
 
 
2.1.19 The x86-64 long mode instructions
 
The AMD64 and EM64T architectures (we will use the common name x86-64 for them
both) extend the x86 instruction set for the 64-bit processing. While legacy
and compatibility modes use the same set of registers and instructions, the
new long mode extends the x86 operations to 64 bits and introduces several new
registers. You can turn on generating the code for this mode with the "use64"
directive.
Each of the general purpose registers is extended to 64 bits and the eight
whole new general purpose registers and also eight new SSE registers are added.
See table 2.4 for the summary of new registers (only the ones that was not
listed in table 1.2). The general purpose registers of smallers sizes are the
low order portions of the larger ones. You can still access the "ah", "bh",
"ch" and "dh" registers in long mode, but you cannot use them in the same
instruction with any of the new registers.
 
Table 2.4 New registers in long mode
/--------------------------------------------------\
| Type | General | SSE | AVX |
|------|---------------------------|-------|-------|
| Bits | 8 | 16 | 32 | 64 | 128 | 256 |
|======|======|======|======|======|=======|=======|
| | | | | rax | | |
| | | | | rcx | | |
| | | | | rdx | | |
| | | | | rbx | | |
| | spl | | | rsp | | |
| | bpl | | | rbp | | |
| | sil | | | rsi | | |
| | dil | | | rdi | | |
| | r8b | r8w | r8d | r8 | xmm8 | ymm8 |
| | r9b | r9w | r9d | r9 | xmm9 | ymm9 |
| | r10b | r10w | r10d | r10 | xmm10 | ymm10 |
| | r11b | r11w | r11d | r11 | xmm11 | ymm11 |
| | r12b | r12w | r12d | r12 | xmm12 | ymm12 |
| | r13b | r13w | r13d | r13 | xmm13 | ymm13 |
| | r14b | r14w | r14d | r14 | xmm14 | ymm14 |
| | r15b | r15w | r15d | r15 | xmm15 | ymm15 |
\--------------------------------------------------/
 
In general any instruction from x86 architecture, which allowed 16-bit or
32-bit operand sizes, in long mode allows also the 64-bit operands. The 64-bit
registers should be used for addressing in long mode, the 32-bit addressing
is also allowed, but it's not possible to use the addresses based on 16-bit
registers. Below are the samples of new operations possible in long mode on the
example of "mov" instruction:
 
mov rax,r8 ; transfer 64-bit general register
mov al,[rbx] ; transfer memory addressed by 64-bit register
 
The long mode uses also the instruction pointer based addresses, you can
specify it manually with the special RIP register symbol, but such addressing
is also automatically generated by flat assembler, since there is no 64-bit
absolute addressing in long mode. You can still force the assembler to use the
32-bit absolute addressing by putting the "dword" size override for address
inside the square brackets. There is also one exception, where the 64-bit
absolute addressing is possible, it's the "mov" instruction with one of the
operand being accumulator register, and second being the memory operand.
To force the assembler to use the 64-bit absolute addressing there, use the
"qword" size operator for address inside the square brackets. When no size
operator is applied to address, assembler generates the optimal form
automatically.
 
mov [qword 0],rax ; absolute 64-bit addressing
mov [dword 0],r15d ; absolute 32-bit addressing
mov [0],rsi ; automatic RIP-relative addressing
mov [rip+3],sil ; manual RIP-relative addressing
 
Also as the immediate operands for 64-bit operations only the signed 32-bit
values are possible, with the only exception being the "mov" instruction with
destination operand being 64-bit general purpose register. Trying to force the
64-bit immediate with any other instruction will cause an error.
If any operation is performed on the 32-bit general registers in long mode,
the upper 32 bits of the 64-bit registers containing them are filled with
zeros. This is unlike the operations on 16-bit or 8-bit portions of those
registers, which preserve the upper bits.
Three new type conversion instructions are available. The "cdqe" sign
extends the double word in EAX into quad word and stores the result in RAX
register. "cqo" sign extends the quad word in RAX into double quad word and
stores the extra bits in the RDX register. These instructions have no
operands. "movsxd" sign extends the double word source operand, being either
the 32-bit register or memory, into 64-bit destination operand, which has to
be register. No analogous instruction is needed for the zero extension, since
it is done automatically by any operations on 32-bit registers, as noted in
previous paragraph. And the "movzx" and "movsx" instructions, conforming to
the general rule, can be used with 64-bit destination operand, allowing
extension of byte or word values into quad words.
All the binary arithmetic and logical instruction have been promoted to
allow 64-bit operands in long mode. The use of decimal arithmetic instructions
in long mode is prohibited.
The stack operations, like "push" and "pop" in long mode default to 64-bit
operands and it's not possible to use 32-bit operands with them. The "pusha"
and "popa" are disallowed in long mode.
The indirect near jumps and calls in long mode default to 64-bit operands
and it's not possible to use the 32-bit operands with them. On the other hand,
the indirect far jumps and calls allow any operands that were allowed by the
x86 architecture and also 80-bit memory operand is allowed (though only EM64T
seems to implement such variant), with the first eight bytes defining the
offset and two last bytes specifying the selector. The direct far jumps and
calls are not allowed in long mode.
The I/O instructions, "in", "out", "ins" and "outs" are the exceptional
instructions that are not extended to accept quad word operands in long mode.
But all other string operations are, and there are new short forms "movsq",
"cmpsq", "scasq", "lodsq" and "stosq" introduced for the variants of string
operations for 64-bit string elements. The RSI and RDI registers are used by
default to address the string elements.
The "lfs", "lgs" and "lss" instructions are extended to accept 80-bit source
memory operand with 64-bit destination register (though only EM64T seems to
implement such variant). The "lds" and "les" are disallowed in long mode.
The system instructions like "lgdt" which required the 48-bit memory operand,
in long mode require the 80-bit memory operand.
The "cmpxchg16b" is the 64-bit equivalent of "cmpxchg8b" instruction, it uses
the double quad word memory operand and 64-bit registers to perform the
analoguous operation.
The "fxsave64" and "fxrstor64" are new variants of "fxsave" and "fxrstor"
instructions, available only in long mode, which use a different format of
storage area in order to store some pointers in full 64-bit size.
"swapgs" is the new instruction, which swaps the contents of GS register and
the KernelGSbase model-specific register (MSR address 0C0000102h).
"syscall" and "sysret" is the pair of new instructions that provide the
functionality similar to "sysenter" and "sysexit" in long mode, where the
latter pair is disallowed. The "sysexitq" and "sysretq" mnemonics provide the
64-bit versions of "sysexit" and "sysret" instructions.
The "rdmsrq" and "wrmsrq" mnemonics are the 64-bit variants of the "rdmsr"
and "wrmsr" instructions.
 
 
2.1.20 SSE4 instructions
 
There are actually three different sets of instructions under the name SSE4.
Intel designed two of them, SSE4.1 and SSE4.2, with latter extending the
former into the full Intel's SSE4 set. On the other hand, the implementation
by AMD includes only a few instructions from this set, but also contains
some additional instructions, that are called the SSE4a set.
The SSE4.1 instructions mostly follow the same rules for operands, as
the basic SSE operations, so they require destination operand to be SSE
register and source operand to be 128-bit memory location or SSE register,
and some operations require a third operand, the 8-bit immediate value.
"pmulld" performs a signed multiplication of the packed double words and
stores the low double words of the results in the destination operand.
"pmuldq" performs a two signed multiplications of the corresponding double
words in the lower quad words of operands, and stores the results as
packed quad words into the destination register. "pminsb" and "pmaxsb"
return the minimum or maximum values of packed signed bytes, "pminuw" and
"pmaxuw" return the minimum and maximum values of packed unsigned words,
"pminud", "pmaxud", "pminsd" and "pmaxsd" return minimum or maximum values
of packed unsigned or signed words. These instructions complement the
instructions computing packed minimum or maximum introduced by SSE.
"ptest" sets the ZF flag to one when the result of bitwise AND of the
both operands is zero, and zeroes the ZF otherwise. It also sets CF flag
to one, when the result of bitwise AND of the destination operand with
the bitwise NOT of the source operand is zero, and zeroes the CF otherwise.
"pcmpeqq" compares packed quad words for equality, and fills the
corresponding elements of destination operand with either ones or zeros,
depending on the result of comparison.
"packusdw" converts packed signed double words from both the source and
destination operand into the unsigned words using saturation, and stores
the eight resulting word values into the destination register.
"phminposuw" finds the minimum unsigned word value in source operand and
places it into the lowest word of destination operand, setting the remaining
upper bits of destination to zero.
"roundps", "roundss", "roundpd" and "roundsd" perform the rounding of packed
or individual floating point value of single or double precision, using the
rounding mode specified by the third operand.
 
roundsd xmm0,xmm1,0011b ; round toward zero
 
"dpps" calculates dot product of packed single precision floating point
values, that is it multiplies the corresponding pairs of values from source and
destination operand and then sums the products up. The high four bits of the
8-bit immediate third operand control which products are calculated and taken
to the sum, and the low four bits control, into which elements of destination
the resulting dot product is copied (the other elements are filled with zero).
"dppd" calculates dot product of packed double precision floating point values.
The bits 4 and 5 of third operand control, which products are calculated and
added, and bits 0 and 1 of this value control, which elements in destination
register should get filled with the result. "mpsadbw" calculates multiple sums
of absolute differences of unsigned bytes. The third operand controls, with
value in bits 0-1, which of the four-byte blocks in source operand is taken to
calculate the absolute differencies, and with value in bit 2, at which of the
two first four-byte block in destination operand start calculating multiple
sums. The sum is calculated from four absolute differencies between the
corresponding unsigned bytes in the source and destination block, and each next
sum is calculated in the same way, but taking the four bytes from destination
at the position one byte after the position of previous block. The four bytes
from the source stay the same each time. This way eight sums of absolute
differencies are calculated and stored as packed word values into the
destination operand. The instructions described in this paragraph follow the
same rules for operands, as "roundps" instruction.
"blendps", "blendvps", "blendpd" and "blendvpd" conditionally copy the
values from source operand into the destination operand, depending on the bits
of the mask provided by third operand. If a mask bit is set, the corresponding
element of source is copied into the same place in destination, otherwise this
position is destination is left unchanged. The rules for the first two operands
are the same, as for general SSE instructions. "blendps" and "blendpd" need
third operand to be 8-bit immediate, and they operate on single or double
precision values, respectively. "blendvps" and "blendvpd" require third operand
to be the XMM0 register.
 
blendvps xmm3,xmm7,xmm0 ; blend according to mask
 
"pblendw" conditionally copies word elements from the source operand into the
destination, depending on the bits of mask provided by third operand, which
needs to be 8-bit immediate value. "pblendvb" conditionally copies byte
elements from the source operands into destination, depending on mask defined
by the third operand, which has to be XMM0 register. These instructions follow
the same rules for operands as "blendps" and "blendvps" instructions,
respectively.
"insertps" inserts a single precision floating point value taken from the
position in source operand specified by bits 6-7 of third operand into location
in destination register selected by bits 4-5 of third operand. Additionally,
the low four bits of third operand control, which elements in destination
register will be set to zero. The first two operands follow the same rules as
for the general SSE operation, the third operand should be 8-bit immediate.
"extractps" extracts a single precision floating point value taken from the
location in source operand specified by low two bits of third operand, and
stores it into the destination operand. The destination can be a 32-bit memory
value or general purpose register, the source operand must be SSE register,
and the third operand should be 8-bit immediate value.
 
extractps edx,xmm3,3 ; extract the highest value
 
"pinsrb", "pinsrd" and "pinsrq" copy a byte, double word or quad word from
the source operand into the location of destination operand determined by the
third operand. The destination operand has to be SSE register, the source
operand can be a memory location of appropriate size, or the 32-bit general
purpose register (but 64-bit general purpose register for "pinsrq", which is
only available in long mode), and the third operand has to be 8-bit immediate
value. These instructions complement the "pinsrw" instruction operating on SSE
register destination, which was introduced by SSE2.
 
pinsrd xmm4,eax,1 ; insert double word into second position
 
"pextrb", "pextrw", "pextrd" and "pextrq" copy a byte, word, double word or
quad word from the location in source operand specified by third operand, into
the destination. The source operand should be SSE register, the third operand
should be 8-bit immediate, and the destination operand can be memory location
of appropriate size, or the 32-bit general purpose register (but 64-bit general
purpose register for "pextrq", which is only available in long mode). The
"pextrw" instruction with SSE register as source was already introduced by
SSE2, but SSE4 extends it to allow memory operand as destination.
 
pextrw [ebx],xmm3,7 ; extract highest word into memory
 
"pmovsxbw" and "pmovzxbw" perform sign extension or zero extension of eight
byte values from the source operand into packed word values in destination
operand, which has to be SSE register. The source can be 64-bit memory or SSE
register - when it is register, only its low portion is used. "pmovsxbd" and
"pmovzxbd" perform sign extension or zero extension of the four byte values
from the source operand into packed double word values in destination operand,
the source can be 32-bit memory or SSE register. "pmovsxbq" and "pmovzxbq"
perform sign extension or zero extension of the two byte values from the
source operand into packed quad word values in destination operand, the source
can be 16-bit memory or SSE register. "pmovsxwd" and "pmovzxwd" perform sign
extension or zero extension of the four word values from the source operand
into packed double words in destination operand, the source can be 64-bit
memory or SSE register. "pmovsxwq" and "pmovzxwq" perform sign extension or
zero extension of the two word values from the source operand into packed quad
words in destination operand, the source can be 32-bit memory or SSE register.
"pmovsxdq" and "pmovzxdq" perform sign extension or zero extension of the two
double word values from the source operand into packed quad words in
destination operand, the source can be 64-bit memory or SSE register.
 
pmovzxbq xmm0,word [si] ; zero-extend bytes to quad words
pmovsxwq xmm0,xmm1 ; sign-extend words to quad words
 
"movntdqa" loads double quad word from the source operand to the destination
using a non-temporal hint. The destination operand should be SSE register,
and the source operand should be 128-bit memory location.
The SSE4.2, described below, adds not only some new operations on SSE
registers, but also introduces some completely new instructions operating on
general purpose registers only.
"pcmpistri" compares two zero-ended (implicit length) strings provided in
its source and destination operand and generates an index stored to ECX;
"pcmpistrm" performs the same comparison and generates a mask stored to XMM0.
"pcmpestri" compares two strings of explicit lengths, with length provided
in EAX for the destination operand and in EDX for the source operand, and
generates an index stored to ECX; "pcmpestrm" performs the same comparision
and generates a mask stored to XMM0. The source and destination operand follow
the same rules as for general SSE instructions, the third operand should be
8-bit immediate value determining the details of performed operation - refer to
Intel documentation for information on those details.
"pcmpgtq" compares packed quad words, and fills the corresponding elements of
destination operand with either ones or zeros, depending on whether the value
in destination is greater than the one in source, or not. This instruction
follows the same rules for operands as "pcmpeqq".
"crc32" accumulates a CRC32 value for the source operand starting with
initial value provided by destination operand, and stores the result in
destination. Unless in long mode, the destination operand should be a 32-bit
general purpose register, and the source operand can be a byte, word, or double
word register or memory location. In long mode the destination operand can
also be a 64-bit general purpose register, and the source operand in such case
can be a byte or quad word register or memory location.
 
crc32 eax,dl ; accumulate CRC32 on byte value
crc32 eax,word [ebx] ; accumulate CRC32 on word value
crc32 rax,qword [rbx] ; accumulate CRC32 on quad word value
 
"popcnt" calculates the number of bits set in the source operand, which can
be 16-bit, 32-bit, or 64-bit general purpose register or memory location,
and stores this count in the destination operand, which has to be register of
the same size as source operand. The 64-bit variant is available only in long
mode.
 
popcnt ecx,eax ; count bits set to 1
 
The SSE4a extension, which also includes the "popcnt" instruction introduced
by SSE4.2, at the same time adds the "lzcnt" instruction, which follows the
same syntax, and calculates the count of leading zero bits in source operand
(if the source operand is all zero bits, the total number of bits in source
operand is stored in destination).
"extrq" extract the sequence of bits from the low quad word of SSE register
provided as first operand and stores them at the low end of this register,
filling the remaining bits in the low quad word with zeros. The position of bit
string and its length can either be provided with two 8-bit immediate values
as second and third operand, or by SSE register as second operand (and there
is no third operand in such case), which should contain position value in bits
8-13 and length of bit string in bits 0-5.
 
extrq xmm0,8,7 ; extract 8 bits from position 7
extrq xmm0,xmm5 ; extract bits defined by register
 
"insertq" writes the sequence of bits from the low quad word of the source
operand into specified position in low quad word of the destination operand,
leaving the other bits in low quad word of destination intact. The position
where bits should be written and the length of bit string can either be
provided with two 8-bit immediate values as third and fourth operand, or by
the bit fields in source operand (and there are only two operands in such
case), which should contain position value in bits 72-77 and length of bit
string in bits 64-69.
 
insertq xmm1,xmm0,4,2 ; insert 4 bits at position 2
insertq xmm1,xmm0 ; insert bits defined by register
 
"movntss" and "movntsd" store single or double precision floating point
value from the source SSE register into 32-bit or 64-bit destination memory
location respectively, using non-temporal hint.
 
 
2.1.21 AVX instructions
 
The Advanced Vector Extensions introduce instructions that are new variants
of SSE instructions, with new scheme of encoding that allows extended syntax
having a destination operand separate from all the source operands. It also
introduces 256-bit AVX registers, which extend up the old 128-bit SSE
registers. Any AVX instruction that puts some result into SSE register, puts
zero bits into high portion of the AVX register containing it.
The AVX version of SSE instruction has the mnemonic obtained by prepending
SSE instruction name with "v". For any SSE arithmetic instruction which had a
destination operand also being used as one of the source values, the AVX
variant has a new syntax with three operands - the destination and two sources.
The destination and first source can be SSE registers, and second source can be
SSE register or memory. If the operation is performed on single pair of values,
the remaining bits of first source SSE register are copied into the the
destination register.
vsubss xmm0,xmm2,xmm3 ; substract two 32-bit floats
vmulsd xmm0,xmm7,qword [esi] ; multiply two 64-bit floats
 
In case of packed operations, each instruction can also operate on the 256-bit
data size when the AVX registers are specified instead of SSE registers, and
the size of memory operand is also doubled then.
 
vaddps ymm1,ymm5,yword [esi] ; eight sums of 32-bit float pairs
 
The instructions that operate on packed integer types (in particular the ones
that earlier had been promoted from MMX to SSE) also acquired the new syntax
with three operands, however they are only allowed to operate on 128-bit
packed types and thus cannot use the whole AVX registers.
 
vpavgw xmm3,xmm0,xmm2 ; average of 16-bit integers
vpslld xmm1,xmm0,1 ; shift double words left
If the SSE version of instruction had a syntax with three operands, the third
one being an immediate value, the AVX version of such instruction takes four
operands, with immediate remaining the last one.
 
vshufpd ymm0,ymm1,ymm2,10010011b ; shuffle 64-bit floats
vpalignr xmm0,xmm4,xmm2,3 ; extract byte aligned value
The promotion to new syntax according to the rules described above has been
applied to all the instructions from SSE extensions up to SSE4, with the
exceptions described below.
"vdppd" instruction has syntax extended to four operans, but it does not
have a 256-bit version.
The are a few instructions, namely "vsqrtpd", "vsqrtps", "vrcpps" and
"vrsqrtps", which can operate on 256-bit data size, but retained the syntax
with only two operands, because they use data from only one source:
vsqrtpd ymm1,ymm0 ; put square roots into other register
 
In a similar way "vroundpd" and "vroundps" retained the syntax with three
operands, the last one being immediate value.
 
vroundps ymm0,ymm1,0011b ; round toward zero
Also some of the operations on packed integers kept their two-operand or
three-operand syntax while being promoted to AVX version. In such case these
instructions follow exactly the same rules for operands as their SSE
counterparts (since operations on packed integers do not have 256-bit variants
in AVX extension). These include "vpcmpestri", "vpcmpestrm", "vpcmpistri",
"vpcmpistrm", "vphminposuw", "vpshufd", "vpshufhw", "vpshuflw". And there are
more instructions that in AVX versions keep exactly the same syntax for
operands as the one from SSE, without any additional options: "vcomiss",
"vcomisd", "vcvtss2si", "vcvtsd2si", "vcvttss2si", "vcvttsd2si", "vextractps",
"vpextrb", "vpextrw", "vpextrd", "vpextrq", "vmovd", "vmovq", "vmovntdqa",
"vmaskmovdqu", "vpmovmskb", "vpmovsxbw", "vpmovsxbd", "vpmovsxbq", "vpmovsxwd",
"vpmovsxwq", "vpmovsxdq", "vpmovzxbw", "vpmovzxbd", "vpmovzxbq", "vpmovzxwd",
"vpmovzxwq" and "vpmovzxdq".
The move and conversion instructions have mostly been promoted to allow
256-bit size operands in addition to the 128-bit variant with syntax identical
to that from SSE version of the same instruction. Each of the "vcvtdq2ps",
"vcvtps2dq" and "vcvttps2dq", "vmovaps", "vmovapd", "vmovups", "vmovupd",
"vmovdqa", "vmovdqu", "vlddqu", "vmovntps", "vmovntpd", "vmovntdq",
"vmovsldup", "vmovshdup", "vmovmskps" and "vmovmskpd" inherits the 128-bit
syntax from SSE without any changes, and also allows a new form with 256-bit
operands in place of 128-bit ones.
 
vmovups [edi],ymm6 ; store unaligned 256-bit data
"vmovddup" has the identical 128-bit syntax as its SSE version, and it also
has a 256-bit version, which stores the duplicates of the lowest quad word
from the source operand in the lower half of destination operand, and in the
upper half of destination the duplicates of the low quad word from the upper
half of source. Both source and destination operands need then to be 256-bit
values.
"vmovlhps" and "vmovhlps" have only 128-bit versions, and each takes three
operands, which all must be SSE registers. "vmovlhps" copies two single
precision values from the low quad word of second source register to the high
quad word of destination register, and copies the low quad word of first
source register into the low quad word of destination register. "vmovhlps"
copies two single precision values from the high quad word of second source
register to the low quad word of destination register, and copies the high
quad word of first source register into the high quad word of destination
register.
"vmovlps", "vmovhps", "vmovlpd" and "vmovhpd" have only 128-bit versions and
their syntax varies depending on whether memory operand is a destination or
source. When memory is destination, the syntax is identical to the one of
equivalent SSE instruction, and when memory is source, the instruction requires
three operands, first two being SSE registers and the third one 64-bit memory.
The value put into destination is then the value copied from first source with
either low or high quad word replaced with value from second source (the
memory operand).
 
vmovhps [esi],xmm7 ; store upper half to memory
vmovlps xmm0,xmm7,[ebx] ; low from memory, rest from register
"vmovss" and "vmovsd" have syntax identical to their SSE equivalents as long
as one of the operands is memory, while the versions that operate purely on
registers require three operands (each being SSE register). The value stored
in destination is then the value copied from first source with lowest data
element replaced with the lowest value from second source.
 
vmovss xmm3,[edi] ; low from memory, rest zeroed
vmovss xmm0,xmm1,xmm2 ; one value from xmm2, three from xmm1
"vcvtss2sd", "vcvtsd2ss", "vcvtsi2ss" and "vcvtsi2d" use the three-operand
syntax, where destination and first source are always SSE registers, and the
second source follows the same rules and the source in syntax of equivalent
SSE instruction. The value stored in destination is then the value copied from
first source with lowest data element replaced with the result of conversion.
 
vcvtsi2sd xmm4,xmm4,ecx ; 32-bit integer to 64-bit float
vcvtsi2ss xmm0,xmm0,rax ; 64-bit integer to 32-bit float
 
"vcvtdq2pd" and "vcvtps2pd" allow the same syntax as their SSE equivalents,
plus the new variants with AVX register as destination and SSE register or
128-bit memory as source. Analogously "vcvtpd2dq", "vcvttpd2dq" and
"vcvtpd2ps", in addition to variant with syntax identical to SSE version,
allow a variant with SSE register as destination and AVX register or 256-bit
memory as source.
"vinsertps", "vpinsrb", "vpinsrw", "vpinsrd", "vpinsrq" and "vpblendw" use
a syntax with four operands, where destination and first source have to be SSE
registers, and the third and fourth operand follow the same rules as second
and third operand in the syntax of equivalent SSE instruction. Value stored in
destination is the the value copied from first source with some data elements
replaced with values extracted from the second source, analogously to the
operation of corresponding SSE instruction.
vpinsrd xmm0,xmm0,eax,3 ; insert double word
 
"vblendvps", "vblendvpd" and "vpblendvb" use a new syntax with four register
operands: destination, two sources and a mask, where second source can also be
a memory operand. "vblendvps" and "vblendvpd" have 256-bit variant, where
operands are AVX registers or 256-bit memory, as well as 128-bit variant,
which has operands being SSE registers or 128-bit memory. "vpblendvb" has only
a 128-bit variant. Value stored in destination is the value copied from the
first source with some data elements replaced, according to mask, by values
from the second source.
 
vblendvps ymm3,ymm1,ymm2,ymm7 ; blend according to mask
"vptest" allows the same syntax as its SSE version and also has a 256-bit
version, with both operands doubled in size. There are also two new
instructions, "vtestps" and "vtestpd", which perform analogous tests, but only
of the sign bits of corresponding single precision or double precision values,
and set the ZF and CF accordingly. They follow the same syntax rules as
"vptest".
 
vptest ymm0,yword [ebx] ; test 256-bit values
vtestpd xmm0,xmm1 ; test sign bits of 64-bit floats
 
"vbroadcastss", "vbroadcastsd" and "vbroadcastf128" are new instructions,
which broadcast the data element defined by source operand into all elements
of corresponing size in the destination register. "vbroadcastss" needs
source to be 32-bit memory and destination to be either SSE or AVX register.
"vbroadcastsd" requires 64-bit memory as source, and AVX register as
destination. "vbroadcastf128" requires 128-bit memory as source, and AVX
register as destination.
 
vbroadcastss ymm0,dword [eax] ; get eight copies of value
 
"vinsertf128" is the new instruction, which takes four operands. The
destination and first source have to be AVX registers, second source can be
SSE register or 128-bit memory location, and fourth operand should be an
immediate value. It stores in destination the value obtained by taking
contents of first source and replacing one of its 128-bit units with value of
the second source. The lowest bit of fourth operand specifies at which
position that replacement is done (either 0 or 1).
"vextractf128" is the new instruction with three operands. The destination
needs to be SSE register or 128-bit memory location, the source must be AVX
register, and the third operand should be an immediate value. It extracts
into destination one of the 128-bit units from source. The lowest bit of third
operand specifies, which unit is extracted.
"vmaskmovps" and "vmaskmovpd" are the new instructions with three operands
that selectively store in destination the elements from second source
depending on the sign bits of corresponding elements from first source. These
instructions can operate on either 128-bit data (SSE registers) or 256-bit
data (AVX registers). Either destination or second source has to be a memory
location of appropriate size, the two other operands should be registers.
vmaskmovps [edi],xmm0,xmm5 ; conditionally store
vmaskmovpd ymm5,ymm0,[esi] ; conditionally load
 
"vpermilpd" and "vpermilps" are the new instructions with three operands
that permute the values from first source according to the control fields from
second source and put the result into destination operand. It allows to use
either three SSE registers or three AVX registers as its operands, the second
source can be a memory of size equal to the registers used. In alternative
form the second source can be immediate value and then the first source
can be a memory location of the size equal to destination register.
"vperm2f128" is the new instruction with four operands, which selects
128-bit blocks of floating point data from first and second source according
to the bit fields from fourth operand, and stores them in destination.
Destination and first source need to be AVX registers, second source can be
AVX register or 256-bit memory area, and fourth operand should be an immediate
value.
 
vperm2f128 ymm0,ymm6,ymm7,12h ; permute 128-bit blocks
 
"vzeroall" instruction sets all the AVX registers to zero. "vzeroupper" sets
the upper 128-bit portions of all AVX registers to zero, leaving the SSE
registers intact. These new instructions take no operands.
"vldmxcsr" and "vstmxcsr" are the AVX versions of "ldmxcsr" and "stmxcsr"
instructions. The rules for their operands remain unchanged.
 
2.1.22 AVX2 instructions
 
The AVX2 extension allows all the AVX instructions operating on packed integers
to use 256-bit data types, and introduces some new instructions as well.
The AVX instructions that operate on packed integers and had only a 128-bit
variants, have been supplemented with 256-bit variants, and thus their syntax
rules became analogous to AVX instructions operating on packed floating point
types.
 
vpsubb ymm0,ymm0,[esi] ; substract 32 packed bytes
vpavgw ymm3,ymm0,ymm2 ; average of 16-bit integers
 
However there are some instructions that have not been equipped with the
256-bit variants. "vpcmpestri", "vpcmpestrm", "vpcmpistri", "vpcmpistrm",
"vpextrb", "vpextrw", "vpextrd", "vpextrq", "vpinsrb", "vpinsrw", "vpinsrd",
"vpinsrq" and "vphminposuw" are not affected by AVX2 and allow only the
128-bit operands.
The packed shift instructions, which allowed the third operand specifying
amount to be SSE register or 128-bit memory location, use the same rules
for the third operand in their 256-bit variant.
 
vpsllw ymm2,ymm2,xmm4 ; shift words left
vpsrad ymm0,ymm3,xword [ebx] ; shift double words right
 
There are also new packed shift instructions with standard three-operand AVX
syntax, which shift each element from first source by the amount specified in
corresponding element of second source, and store the results in destination.
"vpsllvd" shifts 32-bit elements left, "vpsllvq" shifts 64-bit elements left,
"vpsrlvd" shifts 32-bit elements right logically, "vpsrlvq" shifts 64-bit
elements right logically and "vpsravd" shifts 32-bit elements right
arithmetically.
The sign-extend and zero-extend instructions, which in AVX versions allowed
source operand to be SSE register or a memory of specific size, in the new
256-bit variant need memory of that size doubled or SSE register as source and
AVX register as destination.
 
vpmovzxbq ymm0,dword [esi] ; bytes to quad words
Also "vmovntdqa" has been upgraded with 256-bit variant, so it allows to
transfer 256-bit value from memory to AVX register, it needs memory address
to be aligned to 32 bytes.
"vpmaskmovd" and "vpmaskmovq" are the new instructions with syntax identical
to "vmaskmovps" or "vmaskmovpd", and they performs analogous operation on
packed 32-bit or 64-bit values.
"vinserti128", "vextracti128", "vbroadcasti128" and "vperm2i128" are the new
instructions with syntax identical to "vinsertf128", "vextractf128",
"vbroadcastf128" and "vperm2f128" respectively, and they perform analogous
operations on 128-bit blocks of integer data.
"vbroadcastss" and "vbroadcastsd" instructions have been extended to allow
SSE register as a source operand (which in AVX could only be a memory).
"vpbroadcastb", "vpbroadcastw", "vpbroadcastd" and "vpbroadcastq" are the
new instructions which broadcast the byte, word, double word or quad word from
the source operand into all elements of corresponing size in the destination
register. The destination operand can be either SSE or AVX register, and the
source operand can be SSE register or memory of size equal to the size of data
element.
 
vpbroadcastb ymm0,byte [ebx] ; get 32 identical bytes
"vpermd" and "vpermps" are new three-operand instructions, which use each
32-bit element from first source as an index of element in second source which
is copied into destination at position corresponding to element containing
index. The destination and first source have to be AVX registers, and the
second source can be AVX register or 256-bit memory.
"vpermq" and "vpermpd" are new three-operand instructions, which use 2-bit
indexes from the immediate value specified as third operand to determine which
element from source store at given position in destination. The destination
has to be AVX register, source can be AVX register or 256-bit memory, and the
third operand must be 8-bit immediate value.
The family of new instructions performing "gather" operation have special
syntax, as in their memory operand they use addressing mode that is unique to
them. The base of address can be a 32-bit or 64-bit general purpose register
(the latter only in long mode), and the index (possibly multiplied by scale
value, as in standard addressing) is specified by SSE or AVX register. It is
possible to use only index without base and any numerical displacement can be
added to the address. Each of those instructions takes three operands. First
operand is the destination register, second operand is memory addressed with
a vector index, and third operand is register containing a mask. The most
significant bit of each element of mask determines whether a value will be
loaded from memory into corresponding element in destination. The address of
each element to load is determined by using the corresponding element from
index register in memory operand to calculate final address with given base
and displacement. When the index register contains less elements than the
destination and mask registers, the higher elements of destination are zeroed.
After the value is successfuly loaded, the corresponding element in mask
register is set to zero. The destination, index and mask should all be
distinct registers, it is not allowed to use the same register in two
different roles.
"vgatherdps" loads single precision floating point values addressed by
32-bit indexes. The destination, index and mask should all be registers of the
same type, either SSE or AVX. The data addressed by memory operand is 32-bit
in size.
 
vgatherdps xmm0,[eax+xmm1],xmm3 ; gather four floats
vgatherdps ymm0,[ebx+ymm7*4],ymm3 ; gather eight floats
 
"vgatherqps" loads single precision floating point values addressed by
64-bit indexes. The destination and mask should always be SSE registers, while
index register can be either SSE or AVX register. The data addressed by memory
operand is 32-bit in size.
vgatherqps xmm0,[xmm2],xmm3 ; gather two floats
vgatherqps xmm0,[ymm2+64],xmm3 ; gather four floats
"vgatherdpd" loads double precision floating point values addressed by
32-bit indexes. The index register should always be SSE register, the
destination and mask should be two registers of the same type, either SSE or
AVX. The data addressed by memory operand is 64-bit in size.
vgatherdpd xmm0,[ebp+xmm1],xmm3 ; gather two doubles
vgatherdpd ymm0,[xmm3*8],ymm5 ; gather four doubles
 
"vgatherqpd" loads double precision floating point values addressed by
64-bit indexes. The destination, index and mask should all be registers of the
same type, either SSE or AVX. The data addressed by memory operand is 64-bit
in size.
"vpgatherdd" and "vpgatherqd" load 32-bit values addressed by either 32-bit
or 64-bit indexes. They follow the same rules as "vgatherdps" and "vgatherqps"
respectively.
"vpgatherdq" and "vpgatherqq" load 64-bit values addressed by either 32-bit
or 64-bit indexes. They follow the same rules as "vgatherdpd" and "vgatherqpd"
respectively.
 
2.1.23 Auxiliary sets of computational instructions
 
There is a number of additional instruction set extensions related to
AVX. They introduce new vector instructions (and sometimes also their SSE
equivalents that use classic instruction encoding), and even some new
instructions operating on general registers that use the AVX-like encoding
allowing the extended syntax with separate destination and source operands.
The CPU support for each of these instructions sets needs to be determined
separately.
The AES extension provides a specialized set of instructions for the
purpose of cryptographic computations defined by Advanced Encryption Standard.
Each of these instructions has two versions: the AVX one and the one with
SSE-like syntax that uses classic encoding. Refer to the Intel manuals for the
details of operation of these instructions.
"aesenc" and "aesenclast" perform a single round of AES encryption on data
from first source with a round key from second source, and store result in
destination. The destination and first source are SSE registers, and the
second source can be SSE register or 128-bit memory. The AVX versions of these
instructions, "vaesenc" and "vaesenclast", use the syntax with three operands,
while the SSE-like version has only two operands, with first operand being
both the destination and first source.
"aesdec" and "aesdeclast" perform a single round of AES decryption on data
from first source with a round key from second source. The syntax rules for
them and their AVX versions are the same as for "aesenc".
"aesimc" performs the InvMixColumns transformation of source operand and
store the result in destination. Both "aesimc" and "vaesimc" use only two
operands, destination being SSE register, and source being SSE register or
128-bit memory location.
"aeskeygenassist" is a helper instruction for generating the round key.
It needs three operands: destination being SSE register, source being SSE
register or 128-bit memory, and third operand being 8-bit immediate value.
The AVX version of this instruction uses the same syntax.
The CLMUL extension introduces just one instruction, "pclmulqdq", and its
AVX version as well. This instruction performs a carryless multiplication of
two 64-bit values selected from first and second source according to the bit
fields in immediate value. The destination and first source are SSE registers,
second source is SSE register or 128-bit memory, and immediate value is
provided as last operand. "vpclmulqdq" takes four operands, while "pclmulqdq"
takes only three operands, with the first one serving both the role of
destination and first source.
The FMA (Fused Multiply-Add) extension introduces additional AVX
instructions which perform multiplication and summation as single operation.
Each one takes three operands, first one serving both the role of destination
and first source, and the following ones being the second and third source.
The mnemonic of FMA instruction is obtained by appending to "vf" prefix: first
either "m" or "nm" to select whether result of multiplication should be taken
as-is or negated, then either "add" or "sub" to select whether third value
will be added to the product or substracted from the product, then either
"132", "213" or "231" to select which source operands are multiplied and which
one is added or substracted, and finally the type of data on which the
instruction operates, either "ps", "pd", "ss" or "sd". As it was with SSE
instructions promoted to AVX, instructions operating on packed floating point
values allow 128-bit or 256-bit syntax, in former all the operands are SSE
registers, but the third one can also be a 128-bit memory, in latter the
operands are AVX registers and the third one can also be a 256-bit memory.
Instructions that compute just one floating point result need operands to be
SSE registers, and the third operand can also be a memory, either 32-bit for
single precision or 64-bit for double precision.
 
vfmsub231ps ymm1,ymm2,ymm3 ; multiply and substract
vfnmadd132sd xmm0,xmm5,[ebx] ; multiply, negate and add
 
In addition to the instructions created by the rule described above, there are
families of instructions with mnemonics starting with either "vfmaddsub" or
"vfmsubadd", followed by either "132", "213" or "231" and then either "ps" or
"pd" (the operation must always be on packed values in this case). They add
to the result of multiplication or substract from it depending on the position
of value in packed data - instructions from the "vfmaddsub" group add when the
position is odd and substract when the position is even, instructions from the
"vfmsubadd" group add when the position is even and subtstract when the
position is odd. The rules for operands are the same as for other FMA
instructions.
The FMA4 instructions are similar to FMA, but use syntax with four operands
and thus allow destination to be different than all the sources. Their
mnemonics are identical to FMA instructions with the "132", "213" or "231" cut
out, as having separate destination operand makes such selection of operands
superfluous. The multiplication is always performed on values from the first
and second source, and then the value from third source is added or
substracted. Either second or third source can be a memory operand, and the
rules for the sizes of operands are the same as for FMA instructions.
 
vfmaddpd ymm0,ymm1,[esi],ymm2 ; multiply and add
vfmsubss xmm0,xmm1,xmm2,[ebx] ; multiply and substract
The F16C extension consists of two instructions, "vcvtps2ph" and
"vcvtph2ps", which convert floating point values between single precision and
half precision (the 16-bit floating point format). "vcvtps2ph" takes three
operands: destination, source, and rounding controls. The third operand is
always an immediate, the source is either SSE or AVX register containing
single precision values, and the destination is SSE register or memory, the
size of memory is 64 bits when the source is SSE register and 128 bits when
the source is AVX register. "vcvtph2ps" takes two operands, the destination
that can be SSE or AVX register, and the source that is SSE register or memory
with size of the half of destination operand's size.
The AMD XOP extension introduces a number of new vector instructions with
encoding and syntax analogous to AVX instructions. "vfrczps", "vfrczss",
"vfrczpd" and "vfrczsd" extract fractional portions of single or double
precision values, they all take two operands. The packed operations allow
either SSE or AVX register as destination, for the other two it has to be SSE
register. Source can be register of the same type as destination, or memory
of appropriate size (256-bit for destination being AVX register, 128-bit for
packed operation with destination being SSE register, 64-bit for operation
on a solitary double precision value and 32-bit for operation on a solitary
single precision value).
 
vfrczps ymm0,[esi] ; load fractional parts
"vpcmov" copies bits from either first or second source into destination
depending on the values of corresponding bits in the fourth operand (the
selector). If the bit in selector is set, the corresponding bit from first
source is copied into the same position in destination, otherwise the bit from
second source is copied. Either second source or selector can be memory
location, 128-bit or 256-bit depending on whether SSE registers or AVX
registers are specified as the other operands.
 
vpcmov xmm0,xmm1,xmm2,[ebx] ; selector in memory
vpcmov ymm0,ymm5,[esi],ymm2 ; source in memory
 
The family of packed comparison instructions take four operands, the
destination and first source being SSE register, second source being SSE
register or 128-bit memory and the fourth operand being immediate value
defining the type of comparison. The mnemonic or instruction is created
by appending to "vpcom" prefix either "b" or "ub" to compare signed or
unsigned bytes, "w" or "uw" to compare signed or unsigned words, "d" or "ud"
to compare signed or unsigned double words, "q" or "uq" to compare signed or
unsigned quad words. The respective values from the first and second source
are compared and the corresponding data element in destination is set to
either all ones or all zeros depending on the result of comparison. The fourth
operand has to specify one of the eight comparison types (table 2.5). All
these instructions have also variants with only three operands and the type
of comparison encoded within the instruction name by inserting the comparison
mnemonic after "vpcom".
 
vpcomb xmm0,xmm1,xmm2,4 ; test for equal bytes
vpcomgew xmm0,xmm1,[ebx] ; compare signed words
 
Table 2.5 XOP comparisons
/-------------------------------------------\
| Code | Mnemonic | Description |
|======|==========|=========================|
| 0 | lt | less than |
| 1 | le | less than or equal |
| 2 | gt | greater than |
| 3 | ge | greater than or equal |
| 4 | eq | equal |
| 5 | neq | not equal |
| 6 | false | false |
| 7 | true | true |
\-------------------------------------------/
 
"vpermil2ps" and "vpermil2pd" set the elements in destination register to
zero or to a value selected from first or second source depending on the
corresponding bit fields from the fourth operand (the selector) and the
immediate value provided in fifth operand. Refer to the AMD manuals for the
detailed explanation of the operation performed by these instructions. Each
of the first four operands can be a register, and either second source or
selector can be memory location, 128-bit or 256-bit depending on whether SSE
registers or AVX registers are used for the other operands.
 
vpermil2ps ymm0,ymm3,ymm7,ymm2,0 ; permute from two sources
"vphaddbw" adds pairs of adjacent signed bytes to form 16-bit values and
stores them at the same positions in destination. "vphaddubw" does the same
but treats the bytes as unsigned. "vphaddbd" and "vphaddubd" sum all bytes
(either signed or unsigned) in each four-byte block to 32-bit results,
"vphaddbq" and "vphaddubq" sum all bytes in each eight-byte block to
64-bit results, "vphaddwd" and "vphadduwd" add pairs of words to 32-bit
results, "vphaddwq" and "vphadduwq" sum all words in each four-word block to
64-bit results, "vphadddq" and "vphaddudq" add pairs of double words to 64-bit
results. "vphsubbw" substracts in each two-byte block the byte at higher
position from the one at lower position, and stores the result as a signed
16-bit value at the corresponding position in destination, "vphsubwd"
substracts in each two-word block the word at higher position from the one at
lower position and makes signed 32-bit results, "vphsubdq" substract in each
block of two double word the one at higher position from the one at lower
position and makes signed 64-bit results. Each of these instructions takes
two operands, the destination being SSE register, and the source being SSE
register or 128-bit memory.
 
vphadduwq xmm0,xmm1 ; sum quadruplets of words
"vpmacsww" and "vpmacssww" multiply the corresponding signed 16-bit values
from the first and second source and then add the products to the parallel
values from the third source, then "vpmacsww" takes the lowest 16 bits of the
result and "vpmacssww" saturates the result down to 16-bit value, and they
store the final 16-bit results in the destination. "vpmacsdd" and "vpmacssdd"
perform the analogous operation on 32-bit values. "vpmacswd" and "vpmacsswd" do
the same calculation only on the low 16-bit values from each 32-bit block and
form the 32-bit results. "vpmacsdql" and "vpmacssdql" perform such operation
on the low 32-bit values from each 64-bit block and form the 64-bit results,
while "vpmacsdqh" and "vpmacssdqh" do the same on the high 32-bit values from
each 64-bit block, also forming the 64-bit results. "vpmadcswd" and
"vpmadcsswd" multiply the corresponding signed 16-bit value from the first
and second source, then sum all the four products and add this sum to each
16-bit element from third source, storing the truncated or saturated result
in destination. All these instructions take four operands, the second source
can be 128-bit memory or SSE register, all the other operands have to be
SSE registers.
 
vpmacsdd xmm6,xmm1,[ebx],xmm6 ; accumulate product
 
"vpperm" selects bytes from first and second source, optionally applies a
separate transformation to each of them, and stores them in the destination.
The bit fields in fourth operand (the selector) specify for each position in
destination what byte from which source is taken and what operation is applied
to it before it is stored there. Refer to the AMD manuals for the detailed
information about these bit fields. This instruction takes four operands,
either second source or selector can be a 128-bit memory (or they can be SSE
registers both), all the other operands have to be SSE registers.
"vpshlb", "vpshlw", "vpshld" and "vpshlq" shift logically bytes, words, double
words or quad words respectively. The amount of bits to shift by is specified
for each element separately by the signed byte placed at the corresponding
position in the third operand. The source containing elements to shift is
provided as second operand. Either second or third operand can be 128-bit
memory (or they can be SSE registers both) and the other operands have to be
SSE registers.
 
vpshld xmm3,xmm1,[ebx] ; shift bytes from xmm1
"vpshab", "vpshaw", "vpshad" and "vpshaq" arithmetically shift bytes, words,
double words or quad words. These instructions follow the same rules as the
logical shifts described above. "vprotb", "vprotw", "vprotd" and "vprotq"
rotate bytes, word, double words or quad words. They follow the same rules as
shifts, but additionally allow third operand to be immediate value, in which
case the same amount of rotation is specified for all the elements in source.
 
vprotb xmm0,[esi],3 ; rotate bytes to the left
 
The MOVBE extension introduces just one new instruction, "movbe", which
swaps bytes in value from source before storing it in destination, so can
be used to load and store big endian values. It takes two operands, either
the destination or source should be a 16-bit, 32-bit or 64-bit memory (the
last one being only allowed in long mode), and the other operand should be
a general register of the same size.
The BMI extension, consisting of two subsets - BMI1 and BMI2, introduces
new instructions operating on general registers, which use the same encoding
as AVX instructions and so allow the extended syntax. All these instructions
use 32-bit operands, and in long mode they also allow the forms with 64-bit
operands.
"andn" calculates the bitwise AND of second source with the inverted bits
of first source and stores the result in destination. The destination and
the first source have to be general registers, the second source can be
general register or memory.
 
andn edx,eax,[ebx] ; bit-multiply inverted eax with memory
 
"bextr" extracts from the first source the sequence of bits using an index
and length specified by bit fields in the second source operand and stores
it into destination. The lowest 8 bits of second source specify the position
of bit sequence to extract and the next 8 bits of second source specify the
length of sequence. The first source can be a general register or memory,
the other two operands have to be general registers.
 
bextr eax,[esi],ecx ; extract bit field from memory
"blsi" extracts the lowest set bit from the source, setting all the other
bits in destination to zero. The destination must be a general register,
the source can be general register or memory.
 
blsi rax,r11 ; isolate the lowest set bit
"blsmsk" sets all the bits in the destination up to the lowest set bit in
the source, including this bit. "blsr" copies all the bits from the source to
destination except for the lowest set bit, which is replaced by zero. These
instructions follow the same rules for operands as "blsi".
"tzcnt" counts the number of trailing zero bits, that is the zero bits up to
the lowest set bit of source value. This instruction is analogous to "lzcnt"
and follows the same rules for operands, so it also has a 16-bit version,
unlike the other BMI instructions.
"bzhi" is BMI2 instruction, which copies the bits from first source to
destination, zeroing all the bits up from the position specified by second
source. It follows the same rules for operands as "bextr".
"pext" uses a mask in second source operand to select bits from first
operands and puts the selected bits as a continuous sequence into destination.
"pdep" performs the reverse operation - it takes sequence of bits from the
first source and puts them consecutively at the positions where the bits in
second source are set, setting all the other bits in destination to zero.
These BMI2 instructions follow the same rules for operands as "andn".
"mulx" is a BMI2 instruction which performs an unsigned multiplication of
value from EDX or RDX register (depending on the size of specified operands)
by the value from third operand, and stores the low half of result in the
second operand, and the high half of result in the first operand, and it does
it without affecting the flags. The third operand can be general register or
memory, and both the destination operands have to be general registers.
 
mulx edx,eax,ecx ; multiply edx by ecx into edx:eax
 
"shlx", "shrx" and "sarx" are BMI2 instructions, which perform logical or
arithmetical shifts of value from first source by the amount specified by
second source, and store the result in destination without affecting the
flags. The have the same rules for operands as "bzhi" instruction.
"rorx" is a BMI2 instruction which rotates right the value from source
operand by the constant amount specified in third operand and stores the
result in destination without affecting the flags. The destination operand
has to be general register, the source operand can be general register or
memory, and the third operand has to be an immediate value.
 
rorx eax,edx,7 ; rotate without affecting flags
The TBM is an extension designed by AMD to supplement the BMI set. The
"bextr" instruction is extended with a new form, in which second source is
a 32-bit immediate value. "blsic" is a new instruction which performs the
same operation as "blsi", but with the bits of result reversed. It uses the
same rules for operands as "blsi". "blsfill" is a new instruction, which takes
the value from source, sets all the bits below the lowest set bit and store
the result in destination, it also uses the same rules for operands as "blsi".
"blci", "blcic", "blcs", "blcmsk" and "blcfill" are instructions analogous
to "blsi", "blsic", "blsr", "blsmsk" and "blsfill" respectively, but they
perform the bit-inverted versions of the same operations. They follow the
same rules for operands as the instructions they reflect.
"tzmsk" finds the lowest set bit in value from source operand, sets all bits
below it to 1 and all the rest of bits to zero, then writes the result to
destination. "t1mskc" finds the least significant zero bit in the value from
source operand, sets the bits below it to zero and all the other bits to 1,
and writes the result to destination. These instructions have the same rules
for operands as "blsi".
 
2.1.24 Other extensions of instruction set
 
There is a number of additional instruction set extensions recognized by flat
assembler, and the general syntax of the instructions introduced by those
extensions is provided here. For a detailed information on the operations
performed by them, check out the manuals from Intel (for the VMX, SMX, XSAVE,
RDRAND, FSGSBASE, INVPCID, HLE and RTM extensions) or AMD (for the SVM
extension).
The Virtual-Machine Extensions (VMX) provide a set of instructions for the
management of virtual machines. The "vmxon" instruction, which enters the VMX
operation, requires a single 64-bit memory operand, which should be a physical
address of memory region, which the logical processor may use to support VMX
operation. The "vmxoff" instruction, which leaves the VMX operation, has no
operands. The "vmlaunch" and "vmresume", which launch or resume the virtual
machines, and "vmcall", which allows guest software to call the VM monitor,
use no operands either.
The "vmptrld" loads the physical address of current Virtual Machine Control
Structure (VMCS) from its memory operand, "vmptrst" stores the pointer to
current VMCS into address specified by its memory operand, and "vmclear" sets
the launch state of the VMCS referenced by its memory operand to clear. These
three instruction all require single 64-bit memory operand.
The "vmread" reads from VCMS a field specified by the source operand and
stores it into the destination operand. The source operand should be a
general purpose register, and the destination operand can be a register of
memory. The "vmwrite" writes into a VMCS field specified by the destination
operand the value provided by source operand. The source operand can be a
general purpose register or memory, and the destination operand must be a
register. The size of operands for those instructions should be 64-bit when
in long mode, and 32-bit otherwise.
The "invept" and "invvpid" invalidate the translation lookaside buffers
(TLBs) and paging-structure caches, either derived from extended page tables
(EPT), or based on the virtual processor identifier (VPID). These instructions
require two operands, the first one being the general purpose register
specifying the type of invalidation, and the second one being a 128-bit
memory operand providing the invalidation descriptor. The first operand
should be a 64-bit register when in long mode, and 32-bit register otherwise.
The Safer Mode Extensions (SMX) provide the functionalities available
throught the "getsec" instruction. This instruction takes no operands, and
the function that is executed is determined by the contents of EAX register
upon executing this instruction.
The Secure Virtual Machine (SVM) is a variant of virtual machine extension
used by AMD. The "skinit" instruction securely reinitializes the processor
allowing the startup of trusted software, such as the virtual machine monitor
(VMM). This instruction takes a single operand, which must be EAX, and
provides a physical address of the secure loader block (SLB).
The "vmrun" instruction is used to start a guest virtual machine,
its only operand should be an accumulator register (AX, EAX or RAX, the
last one available only in long mode) providing the physical address of the
virtual machine control block (VMCB). The "vmsave" stores a subset of
processor state into VMCB specified by its operand, and "vmload" loads the
same subset of processor state from a specified VMCB. The same operand rules
as for the "vmrun" apply to those two instructions.
"vmmcall" allows the guest software to call the VMM. This instruction takes
no operands.
"stgi" set the global interrupt flag to 1, and "clgi" zeroes it. These
instructions take no operands.
"invlpga" invalidates the TLB mapping for a virtual page specified by the
first operand (which has to be accumulator register) and address space
identifier specified by the second operand (which must be ECX register).
The XSAVE set of instructions allows to save and restore processor state
components. "xsave" and "xsaveopt" store the components of processor state
defined by bit mask in EDX and EAX registers into area defined by memory
operand. "xrstor" restores from the area specified by memory operand the
components of processor state defined by mask in EDX and EAX. The "xsave64",
"xsaveopt64" and "xrstor64" are 64-bit versions of these instructions, allowed
only in long mode.
"xgetbv" read the contents of 64-bit XCR (extended control register)
specified in ECX register into EDX and EAX registers. "xsetbv" writes the
contents of EDX and EAX into the 64-bit XCR specified by ECX register. These
instructions have no operands.
The RDRAND extension introduces one new instruction, "rdrand", which loads
the hardware-generated random value into general register. It takes one
operand, which can be 16-bit, 32-bit or 64-bit register (with the last one
being allowed only in long mode).
The FSGSBASE extension adds long mode instructions that allow to read and
write the segment base registers for FS and GS segments. "rdfsbase" and
"rdgsbase" read the corresponding segment base registers into operand, while
"wrfsbase" and "wrgsbase" write the value of operand into those register.
All these instructions take one operand, which can be 32-bit or 64-bit general
register.
The INVPCID extension adds "invpcid" instruction, which invalidates mapping
in the TLBs and paging caches based on the invalidation type specified in
first operand and PCID invalidate descriptor specified in second operand.
The first operands should be 32-bit general register when not in long mode,
or 64-bit general register when in long mode. The second operand should be
128-bit memory location.
The HLE and RTM extensions provide set of instructions for the transactional
management. The "xacquire" and "xrelease" are new prefixes that can be used
with some of the instructions to start or end lock elision on the memory
address specified by prefixed instruction. The "xbegin" instruction starts
the transactional execution, its operand is the address a fallback routine
that gets executes in case of transaction abort, specified like the operand
for near jump instruction. "xend" marks the end of transcational execution
region, it takes no operands. "xabort" forces the transaction abort, it takes
an 8-bit immediate value as its only operand, this value is passed in the
highest bits of EAX to the fallback routine. "xtest" checks whether there is
transactional execution in progress, this instruction takes no operands.
 
 
2.2 Control directives
 
This section describes the directives that control the assembly process, they
are processed during the assembly and may cause some blocks of instructions
to be assembled differently or not assembled at all.
 
 
2.2.1 Numerical constants
 
The "=" directive allows to define the numerical constant. It should be
preceded by the name for the constant and followed by the numerical expression
providing the value. The value of such constants can be a number or an address,
but - unlike labels - the numerical constants are not allowed to hold the
register-based addresses. Besides this difference, in their basic variant
numerical constants behave very much like labels and you can even
forward-reference them (access their values before they actually get defined).
There is, however, a second variant of numerical constants, which is
recognized by assembler when you try to define the constant of name, under
which there already was a numerical constant defined. In such case assembler
treats that constant as an assembly-time variable and allows it to be assigned
with new value, but forbids forward-referencing it (for obvious reasons). Let's
see both the variant of numerical constants in one example:
 
dd sum
x = 1
x = x+2
sum = x
 
Here the "x" is an assembly-time variable, and every time it is accessed, the
value that was assigned to it the most recently is used. Thus if we tried to
access the "x" before it gets defined the first time, like if we wrote "dd x"
in place of the "dd sum" instruction, it would cause an error. And when it is
re-defined with the "x = x+2" directive, the previous value of "x" is used to
calculate the new one. So when the "sum" constant gets defined, the "x" has
value of 3, and this value is assigned to the "sum". Since this one is defined
only once in source, it is the standard numerical constant, and can be
forward-referenced. So the "dd sum" is assembled as "dd 3". To read more about
how the assembler is able to resolve this, see section 2.2.6.
The value of numerical constant can be preceded by size operator, which can
ensure that the value will fit in the range for the specified size, and can
affect also how some of the calculations inside the numerical expression are
performed. This example:
 
c8 = byte -1
c32 = dword -1
 
defines two different constants, the first one fits in 8 bits, the second one
fits in 32 bits.
When you need to define constant with the value of address, which may be
register-based (and thus you cannot employ numerical constant for this
purpose), you can use the extended syntax of "label" directive (already
described in section 1.2.3), like:
 
label myaddr at ebp+4
 
which declares label placed at "ebp+4" address. However remember that labels,
unlike numerical constants, cannot become assembly-time variables.
 
 
2.2.2 Conditional assembly
 
"if" directive causes some block of instructions to be assembled only under
certain condition. It should be followed by logical expression specifying the
condition, instructions in next lines will be assembled only when this
condition is met, otherwise they will be skipped. The optional "else if"
directive followed with logical expression specifying additional condition
begins the next block of instructions that will be assembled if previous
conditions were not met, and the additional condition is met. The optional
"else" directive begins the block of instructions that will be assembled if
all the conditions were not met. The "end if" directive ends the last block of
instructions.
You should note that "if" directive is processed at assembly stage and
therefore it doesn't affect any preprocessor directives, like the definitions
of symbolic constants and macroinstructions - when the assembler recognizes the
"if" directive, all the preprocessing has been already finished.
The logical expression consist of logical values and logical operators. The
logical operators are "~" for logical negation, "&" for logical and, "|" for
logical or. The negation has the highest priority. Logical value can be a
numerical expression, it will be false if it is equal to zero, otherwise it
will be true. Two numerical expression can be compared using one of the
following operators to make the logical value: "=" (equal), "<" (less),
">" (greater), "<=" (less or equal), ">=" (greater or equal),
"<>" (not equal).
The "used" operator followed by a symbol name, is the logical value that
checks whether the given symbol is used somewhere (it returns correct result
even if symbol is used only after this check). The "defined" operator can be
followed by any expression, usually just by a single symbol name; it checks
whether the given expression contains only symbols that are defined in the
source and accessible from the current position.
With "relativeto" operator it is possible to check whether values of two
expressions differ only by constant amount. The valid syntax is a numerical
expression followed by "relativeto" and then another expression (possibly
register-based). Labels that have no simple numerical value can be tested
this way to determine what kind of operations may be possible with them.
The following simple example uses the "count" constant that should be
defined somewhere in source:
 
if count>0
mov cx,count
rep movsb
end if
 
These two assembly instructions will be assembled only if the "count" constant
is greater than 0. The next sample shows more complex conditional structure:
 
if count & ~ count mod 4
mov cx,count/4
rep movsd
else if count>4
mov cx,count/4
rep movsd
mov cx,count mod 4
rep movsb
else
mov cx,count
rep movsb
end if
 
The first block of instructions gets assembled when the "count" is non zero and
divisible by four, if this condition is not met, the second logical expression,
which follows the "else if", is evaluated and if it's true, the second block
of instructions get assembled, otherwise the last block of instructions, which
follows the line containing only "else", is assembled.
There are also operators that allow comparison of values being any chains of
symbols. The "eq" compares whether two such values are exactly the same.
The "in" operator checks whether given value is a member of the list of values
following this operator, the list should be enclosed between "<" and ">"
characters, its members should be separated with commas. The symbols are
considered the same when they have the same meaning for the assembler - for
example "pword" and "fword" for assembler are the same and thus are not
distinguished by the above operators. In the same way "16 eq 10h" is the true
condition, however "16 eq 10+4" is not.
The "eqtype" operator checks whether the two compared values have the same
structure, and whether the structural elements are of the same type. The
distinguished types include numerical expressions, individual quoted strings,
floating point numbers, address expressions (the expressions enclosed in square
brackets or preceded by "ptr" operator), instruction mnemonics, registers, size
operators, jump type and code type operators. And each of the special
characters that act as a separators, like comma or colon, is the separate type
itself. For example, two values, each one consisting of register name followed
by comma and numerical expression, will be regarded as of the same type, no
matter what kind of register and how complicated numerical expression is used;
with exception for the quoted strings and floating point values, which are the
special kinds of numerical expressions and are treated as different types. Thus
"eax,16 eqtype fs,3+7" condition is true, but "eax,16 eqtype eax,1.6" is false.
 
 
2.2.3 Repeating blocks of instructions
 
"times" directive repeats one instruction specified number of times. It
should be followed by numerical expression specifying number of repeats and
the instruction to repeat (optionally colon can be used to separate number and
instruction). When special symbol "%" is used inside the instruction, it is
equal to the number of current repeat. For example "times 5 db %" will define
five bytes with values 1, 2, 3, 4, 5. Recursive use of "times" directive is
also allowed, so "times 3 times % db %" will define six bytes with values
1, 1, 2, 1, 2, 3.
"repeat" directive repeats the whole block of instructions. It should be
followed by numerical expression specifying number of repeats. Instructions
to repeat are expected in next lines, ended with the "end repeat" directive,
for example:
 
repeat 8
mov byte [bx],%
inc bx
end repeat
 
The generated code will store byte values from one to eight in the memory
addressed by BX register.
Number of repeats can be zero, in that case the instructions are not
assembled at all.
The "break" directive allows to stop repeating earlier and continue assembly
from the first line after the "end repeat". Combined with the "if" directive it
allows to stop repeating under some special condition, like:
 
s = x/2
repeat 100
if x/s = s
break
end if
s = (s+x/s)/2
end repeat
 
The "while" directive repeats the block of instructions as long as the
condition specified by the logical expression following it is true. The block
of instructions to be repeated should end with the "end while" directive.
Before each repetition the logical expression is evaluated and when its value
is false, the assembly is continued starting from the first line after the
"end while". Also in this case the "%" symbol holds the number of current
repeat. The "break" directive can be used to stop this kind of loop in the same
way as with "repeat" directive. The previous sample can be rewritten to use the
"while" instead of "repeat" this way:
 
s = x/2
while x/s <> s
s = (s+x/s)/2
if % = 100
break
end if
end while
 
The blocks defined with "if", "repeat" and "while" can be nested in any
order, however they should be closed in the same order in which they were
started. The "break" directive always stops processing the block that was
started last with either the "repeat" or "while" directive.
 
 
2.2.4 Addressing spaces
 
"org" directive sets address at which the following code is expected to
appear in memory. It should be followed by numerical expression specifying
the address. This directive begins the new addressing space, the following
code itself is not moved in any way, but all the labels defined within it
and the value of "$" symbol are affected as if it was put at the given
address. However it's the responsibility of programmer to put the code at
correct address at run-time.
The "load" directive allows to define constant with a binary value loaded
from the already assembled code. This directive should be followed by the name
of the constant, then optionally size operator, then "from" operator and a
numerical expression specifying a valid address in current addressing space.
The size operator has unusual meaning in this case - it states how many bytes
(up to 8) have to be loaded to form the binary value of constant. If no size
operator is specified, one byte is loaded (thus value is in range from 0 to
255). The loaded data cannot exceed current offset.
The "store" directive can modify the already generated code by replacing
some of the previously generated data with the value defined by given
numerical expression, which follows. The expression can be preceded by the
optional size operator to specify how large value the expression defines, and
therefore how much bytes will be stored, if there is no size operator, the
size of one byte is assumed. Then the "at" operator and the numerical
expression defining the valid address in current addressing code space, at
which the given value have to be stored should follow. This is a directive for
advanced appliances and should be used carefully.
Both "load" and "store" directives are limited to operate on places in
current addressing space. The "$$" symbol is always equal to the base address
of current addressing space, and the "$" symbol is the address of current
position in that addressing space, therefore these two values define limits
of the area, where "load" and "store" can operate.
Combining the "load" and "store" directives allows to do things like encoding
some of the already generated code. For example to encode the whole code
generated in current addressing space you can use such block of directives:
 
repeat $-$$
load a byte from $$+%-1
store byte a xor c at $$+%-1
end repeat
 
and each byte of code will be xored with the value defined by "c" constant.
"virtual" defines virtual data at specified address. This data will not be
included in the output file, but labels defined there can be used in other
parts of source. This directive can be followed by "at" operator and the
numerical expression specifying the address for virtual data, otherwise is
uses current address, the same as "virtual at $". Instructions defining data
are expected in next lines, ended with "end virtual" directive. The block of
virtual instructions itself is an independent addressing space, after it's
ended, the context of previous addressing space is restored.
The "virtual" directive can be used to create union of some variables, for
example:
 
GDTR dp ?
virtual at GDTR
GDT_limit dw ?
GDT_address dd ?
end virtual
 
It defines two labels for parts of the 48-bit variable at "GDTR" address.
It can be also used to define labels for some structures addressed by a
register, for example:
 
virtual at bx
LDT_limit dw ?
LDT_address dd ?
end virtual
 
With such definition instruction "mov ax,[LDT_limit]" will be assembled
to the same instruction as "mov ax,[bx]".
Declaring defined data values or instructions inside the virtual block would
also be useful, because the "load" directive can be used to load the values
from the virtually generated code into a constants. This directive should be
used after the code it loads but before the virtual block ends, because it can
only load the values from the same addressing space. For example:
 
virtual at 0
xor eax,eax
and edx,eax
load zeroq dword from 0
end virtual
 
The above piece of code will define the "zeroq" constant containing four bytes
of the machine code of the instructions defined inside the virtual block.
This method can be also used to load some binary value from external file.
For example this code:
 
virtual at 0
file 'a.txt':10h,1
load char from 0
end virtual
 
loads the single byte from offset 10h in file "a.txt" into the "char"
constant.
Any of the "section" directives described in 2.4 also begins a new
addressing space.
 
 
2.2.5 Other directives
 
"align" directive aligns code or data to the specified boundary. It should
be followed by a numerical expression specifying the number of bytes, to the
multiply of which the current address has to be aligned. The boundary value
has to be the power of two.
The "align" directive fills the bytes that had to be skipped to perform the
alignment with the "nop" instructions and at the same time marks this area as
uninitialized data, so if it is placed among other uninitialized data that
wouldn't take space in the output file, the alignment bytes will act the same
way. If you need to fill the alignment area with some other values, you can
combine "align" with "virtual" to get the size of alignment needed and then
create the alignment yourself, like:
 
virtual
align 16
a = $ - $$
end virtual
db a dup 0
 
The "a" constant is defined to be the difference between address after
alignment and address of the "virtual" block (see previous section), so it is
equal to the size of needed alignment space.
"display" directive displays the message at the assembly time. It should
be followed by the quoted strings or byte values, separated with commas. It
can be used to display values of some constants, for example:
 
bits = 16
display 'Current offset is 0x'
repeat bits/4
d = '0' + $ shr (bits-%*4) and 0Fh
if d > '9'
d = d + 'A'-'9'-1
end if
display d
end repeat
display 13,10
 
This block of directives calculates the four hexadecimal digits of 16-bit
value and converts them into characters for displaying. Note that this will
not work if the adresses in current addressing space are relocatable (as it
might happen with PE or object output formats), since only absolute values can
be used this way. The absolute value may be obtained by calculating the
relative address, like "$-$$", or "rva $" in case of PE format.
The "err" directive immediately terminates the assembly process when it is
encountered by assembler.
The "assert" directive tests whether the logical expression that follows it
is true, and if not, it signalizes the error.
 
 
2.2.6 Multiple passes
 
Because the assembler allows to reference some of the labels or constants
before they get actually defined, it has to predict the values of such labels
and if there is even a suspicion that prediction failed in at least one case,
it does one more pass, assembling the whole source, this time doing better
prediction based on the values the labels got in the previous pass.
The changing values of labels can cause some instructions to have encodings
of different length, and this can cause the change in values of labels again.
And since the labels and constants can also be used inside the expressions that
affect the behavior of control directives, the whole block of source can be
processed completely differently during the new pass. Thus the assembler does
more and more passes, each time trying to do better predictions to approach
the final solution, when all the values get predicted correctly. It uses
various method for predicting the values, which has been chosen to allow
finding in a few passes the solution of possibly smallest length for the most
of the programs.
Some of the errors, like the values not fitting in required boundaries, are
not signaled during those intermediate passes, since it may happen that when
some of the values are predicted better, these errors will disappear. However
if assembler meets some illegal syntax construction or unknown instruction, it
always stops immediately. Also defining some label more than once causes such
error, because it makes the predictions groundless.
Only the messages created with the "display" directive during the last
performed pass get actually displayed. In case when the assembly has been
stopped due to an error, these messages may reflect the predicted values that
are not yet resolved correctly.
The solution may sometimes not exist and in such cases the assembler will
never manage to make correct predictions - for this reason there is a limit for
a number of passes, and when assembler reaches this limit, it stops and
displays the message that it is not able to generate the correct output.
Consider the following example:
 
if ~ defined alpha
alpha:
end if
 
The "defined" operator gives the true value when the expression following it
could be calculated in this place, what in this case means that the "alpha"
label is defined somewhere. But the above block causes this label to be defined
only when the value given by "defined" operator is false, what leads to an
antynomy and makes it impossible to resolve such code. When processing the "if"
directive assembler has to predict whether the "alpha" label will be defined
somewhere (it wouldn't have to predict only if the label was already defined
earlier in this pass), and whatever the prediction is, the opposite always
happens. Thus the assembly will fail, unless the "alpha" label is defined
somewhere in source preceding the above block of instructions - in such case,
as it was already noted, the prediction is not needed and the block will just
get skipped.
The above sample might have been written as a try to define the label only
when it was not yet defined. It fails, because the "defined" operator does
check whether the label is defined anywhere, and this includes the definition
inside this conditionally processed block. However adding some additional
condition may make it possible to get it resolved:
 
if ~ defined alpha | defined @f
alpha:
@@:
end if
 
The "@f" is always the same label as the nearest "@@" symbol in the source
following it, so the above sample would mean the same if any unique name was
used instead of the anonymous label. When "alpha" is not defined in any other
place in source, the only possible solution is when this block gets defined,
and this time this doesn't lead to the antynomy, because of the anonymous
label which makes this block self-establishing. To better understand this,
look at the blocks that has nothing more than this self-establishing:
 
if defined @f
@@:
end if
 
This is an example of source that may have more than one solution, as both
cases when this block gets processed or not are equally correct. Which one of
those two solutions we get depends on the algorithm on the assembler, in case
of flat assembler - on the algorithm of predictions. Back to the previous
sample, when "alpha" is not defined anywhere else, the condition for "if" block
cannot be false, so we are left with only one possible solution, and we can
hope the assembler will arrive at it. On the other hand, when "alpha" is
defined in some other place, we've got two possible solutions again, but one of
them causes "alpha" to be defined twice, and such an error causes assembler to
abort the assembly immediately, as this is the kind of error that deeply
disturbs the process of resolving. So we can get such source either correctly
resolved or causing an error, and what we get may depend on the internal
choices made by the assembler.
However there are some facts about such choices that are certain. When
assembler has to check whether the given symbol is defined and it was already
defined in the current pass, no prediction is needed - it was already noted
above. And when the given symbol has been defined never before, including all
the already finished passes, the assembler predicts it to be not defined.
Knowing this, we can expect that the simple self-establishing block shown
above will not be assembled at all and that the previous sample will resolve
correctly when "alpha" is defined somewhere before our conditional block,
while it will itself define "alpha" when it's not already defined earlier, thus
potentially causing the error because of double definition if the "alpha" is
also defined somewhere later.
The "used" operator may be expected to behave in a similar manner in
analogous cases, however any other kinds of predictions may not be so simple and
you should never rely on them this way.
The "err" directive, usually used to stop the assembly when some condition is
met, stops the assembly immediately, regardless of whether the current pass
is final or intermediate. So even when the condition that caused this directive
to be interpreted is mispredicted and temporary, and would eventually disappear
in the later passes, the assembly is stopped anyway.
The "assert" directive signalizes the error only if its expression is false
after all the symbols have been resolved. You can use "assert 0" in place of
"err" when you do not want to have assembly stopped during the intermediate
passes.
 
 
2.3 Preprocessor directives
 
All preprocessor directives are processed before the main assembly process,
and therefore are not affected by the control directives. At this time also
all comments are stripped out.
 
 
2.3.1 Including source files
 
"include" directive includes the specified source file at the position where
it is used. It should be followed by the quoted name of file that should be
included, for example:
 
include 'macros.inc'
 
The whole included file is preprocessed before preprocessing the lines next
to the line containing the "include" directive. There are no limits to the
number of included files as long as they fit in memory.
The quoted path can contain environment variables enclosed within "%"
characters, they will be replaced with their values inside the path, both the
"\" and "/" characters are allowed as a path separators. The file is first
searched for in the directory containing file which included it and when it is
not found there, the search is continued in the directories specified in the
environment variable called INCLUDE (the multiple paths separated with
semicolons can be defined there, they will be searched in the same order as
specified). If file was not found in any of these places, preprocessor looks
for it in the directory containing the main source file (the one specified in
command line). These rules concern also paths given with the "file" directive.
 
 
2.3.2 Symbolic constants
 
The symbolic constants are different from the numerical constants, before the
assembly process they are replaced with their values everywhere in source
lines after their definitions, and anything can become their values.
The definition of symbolic constant consists of name of the constant
followed by the "equ" directive. Everything that follows this directive will
become the value of constant. If the value of symbolic constant contains
other symbolic constants, they are replaced with their values before assigning
this value to the new constant. For example:
 
d equ dword
NULL equ d 0
d equ edx
 
After these three definitions the value of "NULL" constant is "dword 0" and
the value of "d" is "edx". So, for example, "push NULL" will be assembled as
"push dword 0" and "push d" will be assembled as "push edx". And if then the
following line was put:
 
d equ d,eax
 
the "d" constant would get the new value of "edx,eax". This way the growing
lists of symbols can be defined.
"restore" directive allows to get back previous value of redefined symbolic
constant. It should be followed by one more names of symbolic constants,
separated with commas. So "restore d" after the above definitions will give
"d" constant back the value "edx", the second one will restore it to value
"dword", and one more will revert "d" to original meaning as if no such
constant was defined. If there was no constant defined of given name,
"restore" will not cause an error, it will be just ignored.
Symbolic constant can be used to adjust the syntax of assembler to personal
preferences. For example the following set of definitions provides the handy
shortcuts for all the size operators:
 
b equ byte
w equ word
d equ dword
p equ pword
f equ fword
q equ qword
t equ tword
x equ dqword
y equ qqword
 
Because symbolic constant may also have an empty value, it can be used to
allow the syntax with "offset" word before any address value:
 
offset equ
 
After this definition "mov ax,offset char" will be valid construction for
copying the offset of "char" variable into "ax" register, because "offset" is
replaced with an empty value, and therefore ignored.
The "define" directive followed by the name of constant and then the value,
is the alternative way of defining symbolic constant. The only difference
between "define" and "equ" is that "define" assigns the value as it is, it does
not replace the symbolic constants with their values inside it.
Symbolic constants can also be defined with the "fix" directive, which has
the same syntax as "equ", but defines constants of high priority - they are
replaced with their symbolic values even before processing the preprocessor
directives and macroinstructions, the only exception is "fix" directive
itself, which has the highest possible priority, so it allows redefinition of
constants defined this way.
The "fix" directive can be used for syntax adjustments related to directives
of preprocessor, what cannot be done with "equ" directive. For example:
 
incl fix include
 
defines a short name for "include" directive, while the similar definition done
with "equ" directive wouldn't give such result, as standard symbolic constants
are replaced with their values after searching the line for preprocessor
directives.
 
 
2.3.3 Macroinstructions
 
"macro" directive allows you to define your own complex instructions, called
macroinstructions, using which can greatly simplify the process of
programming. In its simplest form it's similar to symbolic constant
definition. For example the following definition defines a shortcut for the
"test al,0xFF" instruction:
 
macro tst {test al,0xFF}
 
After the "macro" directive there is a name of macroinstruction and then its
contents enclosed between the "{" and "}" characters. You can use "tst"
instruction anywhere after this definition and it will be assembled as
"test al,0xFF". Defining symbolic constant "tst" of that value would give the
similar result, but the difference is that the name of macroinstruction is
recognized only as an instruction mnemonic. Also, macroinstructions are
replaced with corresponding code even before the symbolic constants are
replaced with their values. So if you define macroinstruction and symbolic
constant of the same name, and use this name as an instruction mnemonic, it
will be replaced with the contents of macroinstruction, but it will be
replaced with value if symbolic constant if used somewhere inside the
operands.
The definition of macroinstruction can consist of many lines, because
"{" and "}" characters don't have to be in the same line as "macro" directive.
For example:
 
macro stos0
{
xor al,al
stosb
}
 
The macroinstruction "stos0" will be replaced with these two assembly
instructions anywhere it's used.
Like instructions which needs some number of operands, the macroinstruction
can be defined to need some number of arguments separated with commas. The
names of needed argument should follow the name of macroinstruction in the
line of "macro" directive and should be separated with commas if there is more
than one. Anywhere one of these names occurs in the contents of
macroinstruction, it will be replaced with corresponding value, provided when
the macroinstruction is used. Here is an example of a macroinstruction that
will do data alignment for binary output format:
 
macro align value { rb (value-1)-($+value-1) mod value }
 
When the "align 4" instruction is found after this macroinstruction is
defined, it will be replaced with contents of this macroinstruction, and the
"value" will there become 4, so the result will be "rb (4-1)-($+4-1) mod 4".
If a macroinstruction is defined that uses an instruction with the same name
inside its definition, the previous meaning of this name is used. Useful
redefinition of macroinstructions can be done in that way, for example:
 
macro mov op1,op2
{
if op1 in <ds,es,fs,gs,ss> & op2 in <cs,ds,es,fs,gs,ss>
push op2
pop op1
else
mov op1,op2
end if
}
 
This macroinstruction extends the syntax of "mov" instruction, allowing both
operands to be segment registers. For example "mov ds,es" will be assembled as
"push es" and "pop ds". In all other cases the standard "mov" instruction will
be used. The syntax of this "mov" can be extended further by defining next
macroinstruction of that name, which will use the previous macroinstruction:
 
macro mov op1,op2,op3
{
if op3 eq
mov op1,op2
else
mov op1,op2
mov op2,op3
end if
}
 
It allows "mov" instruction to have three operands, but it can still have two
operands only, because when macroinstruction is given less arguments than it
needs, the rest of arguments will have empty values. When three operands are
given, this macroinstruction will become two macroinstructions of the previous
definition, so "mov es,ds,dx" will be assembled as "push ds", "pop es" and
"mov ds,dx".
By placing the "*" after the name of argument you can mark the argument as
required - preprocessor will not allow it to have an empty value. For example
the above macroinstruction could be declared as "macro mov op1*,op2*,op3" to
make sure that first two arguments will always have to be given some non empty
values.
Alternatively, you can provide the default value for argument, by placing
the "=" followed by value after the name of argument. Then if the argument
has an empty value provided, the default value will be used instead.
When it's needed to provide macroinstruction with argument that contains
some commas, such argument should be enclosed between "<" and ">" characters.
If it contains more than one "<" character, the same number of ">" should be
used to tell that the value of argument ends.
"purge" directive allows removing the last definition of specified
macroinstruction. It should be followed by one or more names of
macroinstructions, separated with commas. If such macroinstruction has not
been defined, you will not get any error. For example after having the syntax
of "mov" extended with the macroinstructions defined above, you can disable
syntax with three operands back by using "purge mov" directive. Next
"purge mov" will disable also syntax for two operands being segment registers,
and all the next such directives will do nothing.
If after the "macro" directive you enclose some group of arguments' names in
square brackets, it will allow giving more values for this group of arguments
when using that macroinstruction. Any more argument given after the last
argument of such group will begin the new group and will become the first
argument of it. That's why after closing the square bracket no more argument
names can follow. The contents of macroinstruction will be processed for each
such group of arguments separately. The simplest example is to enclose one
argument name in square brackets:
 
macro stoschar [char]
{
mov al,char
stosb
}
 
This macroinstruction accepts unlimited number of arguments, and each one
will be processed into these two instructions separately. For example
"stoschar 1,2,3" will be assembled as the following instructions:
 
mov al,1
stosb
mov al,2
stosb
mov al,3
stosb
 
There are some special directives available only inside the definitions of
macroinstructions. "local" directive defines local names, which will be
replaced with unique values each time the macroinstruction is used. It should
be followed by names separated with commas. If the name given as parameter to
"local" directive begins with a dot or two dots, the unique labels generated
by each evaluation of macroinstruction will have the same properties.
This directive is usually needed for the constants or labels that
macroinstruction defines and uses internally. For example:
 
macro movstr
{
local move
move:
lodsb
stosb
test al,al
jnz move
}
 
Each time this macroinstruction is used, "move" will become other unique name
in its instructions, so you will not get an error you normally get when some
label is defined more than once.
"forward", "reverse" and "common" directives divide macroinstruction into
blocks, each one processed after the processing of previous is finished. They
differ in behavior only if macroinstruction allows multiple groups of
arguments. Block of instructions that follows "forward" directive is processed
for each group of arguments, from first to last - exactly like the default
block (not preceded by any of these directives). Block that follows "reverse"
directive is processed for each group of argument in reverse order - from last
to first. Block that follows "common" directive is processed only once,
commonly for all groups of arguments. Local name defined in one of the blocks
is available in all the following blocks when processing the same group of
arguments as when it was defined, and when it is defined in common block it is
available in all the following blocks not depending on which group of
arguments is processed.
Here is an example of macroinstruction that will create the table of
addresses to strings followed by these strings:
 
macro strtbl name,[string]
{
common
label name dword
forward
local label
dd label
forward
label db string,0
}
 
First argument given to this macroinstruction will become the label for table
of addresses, next arguments should be the strings. First block is processed
only once and defines the label, second block for each string declares its
local name and defines the table entry holding the address to that string.
Third block defines the data of each string with the corresponding label.
The directive starting the block in macroinstruction can be followed by the
first instruction of this block in the same line, like in the following
example:
 
macro stdcall proc,[arg]
{
reverse push arg
common call proc
}
 
This macroinstruction can be used for calling the procedures using STDCALL
convention, which has all the arguments pushed on stack in the reverse order.
For example "stdcall foo,1,2,3" will be assembled as:
 
push 3
push 2
push 1
call foo
 
If some name inside macroinstruction has multiple values (it is either one
of the arguments enclosed in square brackets or local name defined in the
block following "forward" or "reverse" directive) and is used in block
following the "common" directive, it will be replaced with all of its values,
separated with commas. For example the following macroinstruction will pass
all of the additional arguments to the previously defined "stdcall"
macroinstruction:
 
macro invoke proc,[arg]
{ common stdcall [proc],arg }
 
It can be used to call indirectly (by the pointer stored in memory) the
procedure using STDCALL convention.
Inside macroinstruction also special operator "#" can be used. This
operator causes two names to be concatenated into one name. It can be useful,
because it's done after the arguments and local names are replaced with their
values. The following macroinstruction will generate the conditional jump
according to the "cond" argument:
 
macro jif op1,cond,op2,label
{
cmp op1,op2
j#cond label
}
 
For example "jif ax,ae,10h,exit" will be assembled as "cmp ax,10h" and
"jae exit" instructions.
The "#" operator can be also used to concatenate two quoted strings into one.
Also conversion of name into a quoted string is possible, with the "`" operator,
which likewise can be used inside the macroinstruction. It converts the name
that follows it into a quoted string - but note, that when it is followed by
a macro argument which is being replaced with value containing more than one
symbol, only the first of them will be converted, as the "`" operator converts
only one symbol that immediately follows it. Here's an example of utilizing
those two features:
 
macro label name
{
label name
if ~ used name
display `name # " is defined but not used.",13,10
end if
}
 
When label defined with such macro is not used in the source, macro will warn
you with the message, informing to which label it applies.
To make macroinstruction behaving differently when some of the arguments are
of some special type, for example a quoted strings, you can use "eqtype"
comparison operator. Here's an example of utilizing it to distinguish a
quoted string from an other argument:
 
macro message arg
{
if arg eqtype ""
local str
jmp @f
str db arg,0Dh,0Ah,24h
@@:
mov dx,str
else
mov dx,arg
end if
mov ah,9
int 21h
}
 
The above macro is designed for displaying messages in DOS programs. When the
argument of this macro is some number, label, or variable, the string from
that address is displayed, but when the argument is a quoted string, the
created code will display that string followed by the carriage return and
line feed.
It is also possible to put a declaration of macroinstruction inside another
macroinstruction, so one macro can define another, but there is a problem
with such definitions caused by the fact, that "}" character cannot occur
inside the macroinstruction, as it always means the end of definition. To
overcome this problem, the escaping of symbols inside macroinstruction can be
used. This is done by placing one or more backslashes in front of any other
symbol (even the special character). Preprocessor sees such sequence as a
single symbol, but each time it meets such symbol during the macroinstruction
processing, it cuts the backslash character from the front of it. For example
"\{" is treated as single symbol, but during processing of the macroinstruction
it becomes the "{" symbol. This allows to put one definition of
macroinstruction inside another:
 
macro ext instr
{
macro instr op1,op2,op3
\{
if op3 eq
instr op1,op2
else
instr op1,op2
instr op2,op3
end if
\}
}
 
ext add
ext sub
 
The macro "ext" is defined correctly, but when it is used, the "\{" and "\}"
become the "{" and "}" symbols. So when the "ext add" is processed, the
contents of macro becomes valid definition of a macroinstruction and this way
the "add" macro becomes defined. In the same way "ext sub" defines the "sub"
macro. The use of "\{" symbol wasn't really necessary here, but is done this
way to make the definition more clear.
If some directives specific to macroinstructions, like "local" or "common"
are needed inside some macro embedded this way, they can be escaped in the same
way. Escaping the symbol with more than one backslash is also allowed, which
allows multiple levels of nesting the macroinstruction definitions.
The another technique for defining one macroinstruction by another is to
use the "fix" directive, which becomes useful when some macroinstruction only
begins the definition of another one, without closing it. For example:
 
macro tmacro [params]
{
common macro params {
}
 
MACRO fix tmacro
ENDM fix }
 
defines an alternative syntax for defining macroinstructions, which looks like:
 
MACRO stoschar char
mov al,char
stosb
ENDM
 
Note that symbol that has such customized definition must be defined with "fix"
directive, because only the prioritized symbolic constants are processed before
the preprocessor looks for the "}" character while defining the macro. This
might be a problem if one needed to perform some additional tasks one the end
of such definition, but there is one more feature which helps in such cases.
Namely it is possible to put any directive, instruction or macroinstruction
just after the "}" character that ends the macroinstruction and it will be
processed in the same way as if it was put in the next line.
 
 
2.3.4 Structures
 
"struc" directive is a special variant of "macro" directive that is used to
define data structures. Macroinstruction defined using the "struc" directive
must be preceded by a label (like the data definition directive) when it's
used. This label will be also attached at the beginning of every name starting
with dot in the contents of macroinstruction. The macroinstruction defined
using the "struc" directive can have the same name as some other
macroinstruction defined using the "macro" directive, structure
macroinstruction will not prevent the standard macroinstruction from being
processed when there is no label before it and vice versa. All the rules and
features concerning standard macroinstructions apply to structure
macroinstructions.
Here is the sample of structure macroinstruction:
 
struc point x,y
{
.x dw x
.y dw y
}
 
For example "my point 7,11" will define structure labeled "my", consisting of
two variables: "my.x" with value 7 and "my.y" with value 11.
If somewhere inside the definition of structure the name consisting of a
single dot it found, it is replaced by the name of the label for the given
instance of structure and this label will not be defined automatically in
such case, allowing to completely customize the definition. The following
example utilizes this feature to extend the data definition directive "db"
with ability to calculate the size of defined data:
 
struc db [data]
{
common
. db data
.size = $ - .
}
 
With such definition "msg db 'Hello!',13,10" will define also "msg.size"
constant, equal to the size of defined data in bytes.
Defining data structures addressed by registers or absolute values should be
done using the "virtual" directive with structure macroinstruction
(see 2.2.4).
"restruc" directive removes the last definition of the structure, just like
"purge" does with macroinstructions and "restore" with symbolic constants.
It also has the same syntax - should be followed by one or more names of
structure macroinstructions, separated with commas.
 
 
2.3.5 Repeating macroinstructions
 
The "rept" directive is a special kind of macroinstruction, which makes given
amount of duplicates of the block enclosed with braces. The basic syntax is
"rept" directive followed by number and then block of source enclosed between
the "{" and "}" characters. The simplest example:
 
rept 5 { in al,dx }
 
will make five duplicates of the "in al,dx" line. The block of instructions
is defined in the same way as for the standard macroinstruction and any
special operators and directives which can be used only inside
macroinstructions are also allowed here. When the given count is zero, the
block is simply skipped, as if you defined macroinstruction but never used
it. The number of repetitions can be followed by the name of counter symbol,
which will get replaced symbolically with the number of duplicate currently
generated. So this:
 
rept 3 counter
{
byte#counter db counter
}
 
will generate lines:
 
byte1 db 1
byte2 db 2
byte3 db 3
 
The repetition mechanism applied to "rept" blocks is the same as the one used
to process multiple groups of arguments for macroinstructions, so directives
like "forward", "common" and "reverse" can be used in their usual meaning.
Thus such macroinstruction:
 
rept 7 num { reverse display `num }
 
will display digits from 7 to 1 as text. The "local" directive behaves in the
same way as inside macroinstruction with multiple groups of arguments, so:
 
rept 21
{
local label
label: loop label
}
 
will generate unique label for each duplicate.
The counter symbol by default counts from 1, but you can declare different
base value by placing the number preceded by colon immediately after the name
of counter. For example:
 
rept 8 n:0 { pxor xmm#n,xmm#n }
 
will generate code which will clear the contents of eight SSE registers.
You can define multiple counters separated with commas, and each one can have
different base.
The number of repetitions and the base values for counters can be specified
using the numerical expressions with operator rules identical as in the case
of assembler. However each value used in such expression must either be a
directly specified number, or a symbolic constant with value also being an
expression that can be calculated by preprocessor (in such case the value
of expression associated with symbolic constant is calculated first, and then
substituted into the outer expression in place of that constant). If you need
repetitions based on values that can only be calculated at assembly time, use
one of the code repeating directives that are processed by assembler, see
section 2.2.3.
The "irp" directive iterates the single argument through the given list of
parameters. The syntax is "irp" followed by the argument name, then the comma
and then the list of parameters. The parameters are specified in the same
way like in the invocation of standard macroinstruction, so they have to be
separated with commas and each one can be enclosed with the "<" and ">"
characters. Also the name of argument may be followed by "*" to mark that it
cannot get an empty value. Such block:
 
irp value, 2,3,5
{ db value }
 
will generate lines:
 
db 2
db 3
db 5
 
The "irps" directive iterates through the given list of symbols, it should
be followed by the argument name, then the comma and then the sequence of any
symbols. Each symbol in this sequence, no matter whether it is the name
symbol, symbol character or quoted string, becomes an argument value for one
iteration. If there are no symbols following the comma, no iteration is done
at all. This example:
 
irps reg, al bx ecx
{ xor reg,reg }
 
will generate lines:
 
xor al,al
xor bx,bx
xor ecx,ecx
 
The blocks defined by the "irp" and "irps" directives are also processed in
the same way as any macroinstructions, so operators and directives specific
to macroinstructions may be freely used also in this case.
 
 
2.3.6 Conditional preprocessing
 
"match" directive causes some block of source to be preprocessed and passed
to assembler only when the given sequence of symbols matches the specified
pattern. The pattern comes first, ended with comma, then the symbols that have
to be matched with the pattern, and finally the block of source, enclosed
within braces as macroinstruction.
There are the few rules for building the expression for matching, first is
that any of symbol characters and any quoted string should be matched exactly
as is. In this example:
 
match +,+ { include 'first.inc' }
match +,- { include 'second.inc' }
 
the first file will get included, since "+" after comma matches the "+" in
pattern, and the second file will not be included, since there is no match.
To match any other symbol literally, it has to be preceded by "=" character
in the pattern. Also to match the "=" character itself, or the comma, the
"==" and "=," constructions have to be used. For example the "=a==" pattern
will match the "a=" sequence.
If some name symbol is placed in the pattern, it matches any sequence
consisting of at least one symbol and then this name is replaced with the
matched sequence everywhere inside the following block, analogously to the
parameters of macroinstruction. For instance:
 
match a-b, 0-7
{ dw a,b-a }
 
will generate the "dw 0,7-0" instruction. Each name is always matched with
as few symbols as possible, leaving the rest for the following ones, so in
this case:
 
match a b, 1+2+3 { db a }
 
the "a" name will match the "1" symbol, leaving the "+2+3" sequence to be
matched with "b". But in this case:
 
match a b, 1 { db a }
 
there will be nothing left for "b" to match, so the block will not get
processed at all.
The block of source defined by match is processed in the same way as any
macroinstruction, so any operators specific to macroinstructions can be used
also in this case.
What makes "match" directive more useful is the fact, that it replaces the
symbolic constants with their values in the matched sequence of symbols (that
is everywhere after comma up to the beginning of the source block) before
performing the match. Thanks to this it can be used for example to process
some block of source under the condition that some symbolic constant has the
given value, like:
 
match =TRUE, DEBUG { include 'debug.inc' }
 
which will include the file only when the symbolic constant "DEBUG" was
defined with value "TRUE".
 
 
2.3.7 Order of processing
 
When combining various features of the preprocessor, it's important to know
the order in which they are processed. As it was already noted, the highest
priority has the "fix" directive and the replacements defined with it. This
is done completely before doing any other preprocessing, therefore this
piece of source:
 
V fix {
macro empty
V
V fix }
V
 
becomes a valid definition of an empty macroinstruction. It can be interpreted
that the "fix" directive and prioritized symbolic constants are processed in
a separate stage, and all other preprocessing is done after on the resulting
source.
The standard preprocessing that comes after, on each line begins with
recognition of the first symbol. It starts with checking for the preprocessor
directives, and when none of them is detected, preprocessor checks whether the
first symbol is macroinstruction. If no macroinstruction is found, it moves
to the second symbol of line, and again begins with checking for directives,
which in this case is only the "equ" directive, as this is the only one that
occurs as the second symbol in line. If there is no directive, the second
symbol is checked for the case of structure macroinstruction and when none
of those checks gives the positive result, the symbolic constants are replaced
with their values and such line is passed to the assembler.
To see it on the example, assume that there is defined the macroinstruction
called "foo" and the structure macroinstruction called "bar". Those lines:
 
foo equ
foo bar
 
would be then both interpreted as invocations of macroinstruction "foo", since
the meaning of the first symbol overrides the meaning of second one.
When the macroinstruction generates the new lines from its definition block,
in every line it first scans for macroinstruction directives, and interpretes
them accordingly. All the other content in the definition block is used to
brew the new lines, replacing the macroinstruction parameters with their values
and then processing the symbol escaping and "#" and "`" operators. The
conversion operator has the higher priority than concatenation and if any of
them operates on the escaped symbol, the escaping is cancelled before finishing
the operation. After this is completed, the newly generated line goes through
the standard preprocessing, as described above.
Though the symbolic constants are usually only replaced in the lines, where
no preprocessor directives nor macroinstructions has been found, there are some
special cases where those replacements are performed in the parts of lines
containing directives. First one is the definition of symbolic constant, where
the replacements are done everywhere after the "equ" keyword and the resulting
value is then assigned to the new constant (see 2.3.2). The second such case
is the "match" directive, where the replacements are done in the symbols
following comma before matching them with pattern. These features can be used
for example to maintain the lists, like this set of definitions:
 
list equ
 
macro append item
{
match any, list \{ list equ list,item \}
match , list \{ list equ item \}
}
 
The "list" constant is here initialized with empty value, and the "append"
macroinstruction can be used to add the new items into this list, separating
them with commas. The first match in this macroinstruction occurs only when
the value of list is not empty (see 2.3.6), in such case the new value for the
list is the previous one with the comma and the new item appended at the end.
The second match happens only when the list is still empty, and in such case
the list is defined to contain just the new item. So starting with the empty
list, the "append 1" would define "list equ 1" and the "append 2" following it
would define "list equ 1,2". One might then need to use this list as the
parameters to some macroinstruction. But it cannot be done directly - if "foo"
is the macroinstruction, then "foo list" would just pass the "list" symbol
as a parameter to macro, since symbolic constants are not unrolled at this
stage. For this purpose again "match" directive comes in handy:
 
match params, list { foo params }
 
The value of "list", if it's not empty, matches the "params" keyword, which is
then replaced with matched value when generating the new lines defined by the
block enclosed with braces. So if the "list" had value "1,2", the above line
would generate the line containing "foo 1,2", which would then go through the
standard preprocessing.
The other special case is in the parameters of "rept" directive. The amount
of repetitions and the base value for counter can be specified using
numerical expressions, and if there is a symbolic constant with non-numerical
name used in such an expression, preprocessor tries to evaluate its value as
a numerical expression and if succeeds, it replaces the symbolic constant with
the result of that calculation and continues to evaluate the primary
expression. If the expression inside that symbolic constants also contains
some symbolic constants, preprocessor will try to calculate all the needed
values recursively.
This allows to perform some calculations at the time of preprocessing, as
long as all the values used are the numbers known at the preprocessing stage.
A single repetition with "rept" can be used for the sole purpose of
calculating some value, like in this example:
 
define a b+4
define b 3
rept 1 result:a*b+2 { define c result }
To compute the base value for "result" counter, preprocessor replaces the "b"
with its value and recursively calculates the value of "a", obtaining 7 as
the result, then it calculates the main expression with the result being 23.
The "c" then gets defined with the first value of counter (because the block
is processed just one time), which is the result of the computation, so the
value of "c" is simple "23" symbol. Note that if "b" is later redefined with
some other numerical value, the next time and expression containing "a" is
calculated, the value of "a" will reflect the new value of "b", because the
symbolic constant contains just the text of the expression.
There is one more special case - when preprocessor goes to checking the
second symbol in the line and it happens to be the colon character (what is
then interpreted by assembler as definition of a label), it stops in this
place and finishes the preprocessing of the first symbol (so if it's the
symbolic constant it gets unrolled) and if it still appears to be the label,
it performs the standard preprocessing starting from the place after the
label. This allows to place preprocessor directives and macroinstructions
after the labels, analogously to the instructions and directives processed
by assembler, like:
 
start: include 'start.inc'
 
However if the label becomes broken during preprocessing (for example when
it is the symbolic constant with empty value), only replacing of the symbolic
constants is continued for the rest of line.
It should be remembered, that the jobs performed by preprocessor are the
preliminary operations on the texts symbols, that are done in a simple
single pass before the main process of assembly. The text that is the
result of preprocessing is passed to assembler, and it then does its
multiple passes on it. Thus the control directives, which are recognized and
processed only by the assembler - as they are dependent on the numerical
values that may even vary between passes - are not recognized in any way by
the preprocessor and have no effect on the preprocessing. Consider this
example source:
 
if 0
a = 1
b equ 2
end if
dd b
 
When it is preprocessed, they only directive that is recognized by the
preprocessor is the "equ", which defines symbolic constant "b", so later
in the source the "b" symbol is replaced with the value "2". Except for this
replacement, the other lines are passes unchanged to the assembler. So
after preprocessing the above source becomes:
 
if 0
a = 1
end if
dd 2
 
Now when assembler processes it, the condition for the "if" is false, and
the "a" constant doesn't get defined. However symbolic constant "b" was
processed normally, even though its definition was put just next to the one
of "a". So because of the possible confusion you should be very careful
every time when mixing the features of preprocessor and assembler - in such
cases it is important to realize what the source will become after the
preprocessing, and thus what the assembler will see and do its multiple passes
on.
 
 
2.4 Formatter directives
 
These directives are actually also a kind of control directives, with the
purpose of controlling the format of generated code.
"format" directive followed by the format identifier allows to select the
output format. This directive should be put at the beginning of the source.
Default output format is a flat binary file, it can also be selected by using
"format binary" directive. This directive can be followed by the "as" keyword
and the quoted string specifying the default file extension for the output
file. Unless the output file name was specified from the command line,
assembler will use this extension when generating the output file.
"use16" and "use32" directives force the assembler to generate 16-bit or
32-bit code, omitting the default setting for selected output format. "use64"
enables generating the code for the long mode of x86-64 processors.
Below are described different output formats with the directives specific to
these formats.
 
 
2.4.1 MZ executable
 
To select the MZ output format, use "format MZ" directive. The default code
setting for this format is 16-bit.
"segment" directive defines a new segment, it should be followed by label,
which value will be the number of defined segment, optionally "use16" or
"use32" word can follow to specify whether code in this segment should be
16-bit or 32-bit. The origin of segment is aligned to paragraph (16 bytes).
All the labels defined then will have values relative to the beginning of this
segment.
"entry" directive sets the entry point for MZ executable, it should be
followed by the far address (name of segment, colon and the offset inside
segment) of desired entry point.
"stack" directive sets up the stack for MZ executable. It can be followed by
numerical expression specifying the size of stack to be created automatically
or by the far address of initial stack frame when you want to set up the stack
manually. When no stack is defined, the stack of default size 4096 bytes will
be created.
"heap" directive should be followed by a 16-bit value defining maximum size
of additional heap in paragraphs (this is heap in addition to stack and
undefined data). Use "heap 0" to always allocate only memory program really
needs. Default size of heap is 65535.
 
 
2.4.2 Portable Executable
 
To select the Portable Executable output format, use "format PE" directive, it
can be followed by additional format settings: first the target subsystem
setting, which can be "console" or "GUI" for Windows applications, "native"
for Windows drivers, "EFI", "EFIboot" or "EFIruntime" for the UEFI, it may be
followed by the minimum version of system that the executable is targeted to
(specified in form of floating-point value). Optional "DLL" and "WDM" keywords
mark the output file as a dynamic link library and WDM driver respectively,
and the "large" keyword marks the executable as able to handle addresses
larger than 2 GB.
After those settings can follow the "at" operator and a numerical expression
specifying the base of PE image and then optionally "on" operator followed by
the quoted string containing file name selects custom MZ stub for PE program
(when specified file is not a MZ executable, it is treated as a flat binary
executable file and converted into MZ format). The default code setting for
this format is 32-bit. The example of fully featured PE format declaration:
 
format PE GUI 4.0 DLL at 7000000h on 'stub.exe'
 
To create PE file for the x86-64 architecture, use "PE64" keyword instead of
"PE" in the format declaration, in such case the long mode code is generated
by default.
"section" directive defines a new section, it should be followed by quoted
string defining the name of section, then one or more section flags can
follow. Available flags are: "code", "data", "readable", "writeable",
"executable", "shareable", "discardable", "notpageable". The origin of section
is aligned to page (4096 bytes). Example declaration of PE section:
 
section '.text' code readable executable
 
Among with flags also one of the special PE data identifiers can be specified
to mark the whole section as a special data, possible identifiers are
"export", "import", "resource" and "fixups". If the section is marked to
contain fixups, they are generated automatically and no more data needs to be
defined in this section. Also resource data can be generated automatically
from the resource file, it can be achieved by writing the "from" operator and
quoted file name after the "resource" identifier. Below are the examples of
sections containing some special PE data:
 
section '.reloc' data readable discardable fixups
section '.rsrc' data readable resource from 'my.res'
 
"entry" directive sets the entry point for Portable Executable, the value of
entry point should follow.
"stack" directive sets up the size of stack for Portable Executable, value
of stack reserve size should follow, optionally value of stack commit
separated with comma can follow. When stack is not defined, it's set by
default to size of 4096 bytes.
"heap" directive chooses the size of heap for Portable Executable, value of
heap reserve size should follow, optionally value of heap commit separated
with comma can follow. When no heap is defined, it is set by default to size
of 65536 bytes, when size of heap commit is unspecified, it is by default set
to zero.
"data" directive begins the definition of special PE data, it should be
followed by one of the data identifiers ("export", "import", "resource" or
"fixups") or by the number of data entry in PE header. The data should be
defined in next lines, ended with "end data" directive. When fixups data
definition is chosen, they are generated automatically and no more data needs
to be defined there. The same applies to the resource data when the "resource"
identifier is followed by "from" operator and quoted file name - in such case
data is taken from the given resource file.
The "rva" operator can be used inside the numerical expressions to obtain
the RVA of the item addressed by the value it is applied to, that is the
offset relative to the base of PE image.
 
 
2.4.3 Common Object File Format
 
To select Common Object File Format, use "format COFF" or "format MS COFF"
directive, depending whether you want to create classic (DJGPP) or Microsoft's
variant of COFF file. The default code setting for this format is 32-bit. To
create the file in Microsoft's COFF format for the x86-64 architecture, use
"format MS64 COFF" setting, in such case long mode code is generated by
default.
"section" directive defines a new section, it should be followed by quoted
string defining the name of section, then one or more section flags can
follow. Section flags available for both COFF variants are "code" and "data",
while flags "readable", "writeable", "executable", "shareable", "discardable",
"notpageable", "linkremove" and "linkinfo" are available only with Microsoft's
COFF variant.
By default section is aligned to double word (four bytes), in case of
Microsoft COFF variant other alignment can be specified by providing the
"align" operator followed by alignment value (any power of two up to 8192)
among the section flags.
"extrn" directive defines the external symbol, it should be followed by the
name of symbol and optionally the size operator specifying the size of data
labeled by this symbol. The name of symbol can be also preceded by quoted
string containing name of the external symbol and the "as" operator.
Some example declarations of external symbols:
 
extrn exit
extrn '__imp__MessageBoxA@16' as MessageBox:dword
 
"public" directive declares the existing symbol as public, it should be
followed by the name of symbol, optionally it can be followed by the "as"
operator and the quoted string containing name under which symbol should be
available as public. Some examples of public symbols declarations:
 
public main
public start as '_start'
 
Additionally, with COFF format it's possible to specify exported symbol as
static, it's done by preceding the name of symbol with the "static" keyword.
When using the Microsoft's COFF format, the "rva" operator can be used
inside the numerical expressions to obtain the RVA of the item addressed by the
value it is applied to.
 
2.4.4 Executable and Linkable Format
 
To select ELF output format, use "format ELF" directive. The default code
setting for this format is 32-bit. To create ELF file for the x86-64
architecture, use "format ELF64" directive, in such case the long mode code is
generated by default.
"section" directive defines a new section, it should be followed by quoted
string defining the name of section, then can follow one or both of the
"executable" and "writeable" flags, optionally also "align" operator followed
by the number specifying the alignment of section (it has to be the power of
two), if no alignment is specified, the default value is used, which is 4 or 8,
depending on which format variant has been chosen.
"extrn" and "public" directives have the same meaning and syntax as when the
COFF output format is selected (described in previous section).
The "rva" operator can be used also in the case of this format (however not
when target architecture is x86-64), it converts the address into the offset
relative to the GOT table, so it may be useful to create position-independent
code. There's also a special "plt" operator, which allows to call the external
functions through the Procedure Linkage Table. You can even create an alias
for external function that will make it always be called through PLT, with
the code like:
 
extrn 'printf' as _printf
printf = PLT _printf
 
To create executable file, follow the format choice directive with the
"executable" keyword and optionally the number specifying the brand of the
target operating system (for example value 3 would mark the executable
for Linux system). With this format selected it is allowed to use "entry"
directive followed by the value to set as entry point of program. On the other
hand it makes "extrn" and "public" directives unavailable, and instead of
"section" there should be the "segment" directive used, followed by one or
more segment permission flags and optionally a marker of special ELF
executable segment, which can be "interpreter", "dynamic" or "note". The
origin of segment is aligned to page (4096 bytes), and available permission
flags are: "readable", "writeable" and "executable".
 
EOF
/programs/develop/fasm/1.71/build_en.bat
0,0 → 1,6
@erase lang.inc
@echo lang fix en >lang.inc
@fasm -m 16384 fasm.asm fasm
@erase lang.inc
@kpack fasm
@pause
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/build_ru.bat
0,0 → 1,6
@erase lang.inc
@echo lang fix ru >lang.inc
@fasm -m 16384 fasm.asm fasm
@erase lang.inc
@kpack fasm
@pause
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/license.txt
0,0 → 1,37
 
flat assembler version 1.71
Copyright (c) 1999-2013, Tomasz Grysztar.
All rights reserved.
 
This program is free for commercial and non-commercial use as long as
the following conditions are adhered to.
 
Copyright remains Tomasz Grysztar, and as such any Copyright notices
in the code are not to be removed.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
 
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
The licence and distribution terms for any publically available
version or derivative of this code cannot be changed. i.e. this code
cannot simply be copied and put under another distribution licence
(including the GNU Public Licence).
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/develop/fasm/1.71/whatsnew.txt
0,0 → 1,401
 
Visit http://flatassembler.net/ for more information.
 
 
version 1.71.16 (Oct 30, 2013)
 
[-] Fixed some bugs in the ELF executable formatter.
 
 
version 1.71.15 (Oct 26, 2013)
 
[-] Fixed some bugs inadvertently introduced in the previous release.
 
 
version 1.71.14 (Oct 25, 2013)
 
[+] Added "postpone" directive to preprocessor.
 
 
version 1.71.13 (Sep 09, 2013)
 
[-] Fixed a bug that caused the expressions containing external symbols
to overflow from time to time.
 
 
version 1.71.12 (Aug 04, 2013)
 
[-] Expressions in square brackets were incorrectly treated as valid numerical
values when used in some logical expressions.
 
[-] A previous fix to "store" directive did not apply to all the cases when it
was incorrectly leaving the data marked as uninitialized. The new fix
addresses this issue.
 
 
version 1.71.11 (Jul 09, 2013)
 
[-] Modifying a value in uninitialized data block with "store" directive will
now correctly mark this data as initialized when it is in a different
addressing space.
 
[-] Missing quote will no longer cause the symbols generator to hang or crash.
 
[-] Address range restrictions for addressing modes no longer apply to addresses
provided to assembler directives like "label", "virtual" or "load".
 
 
version 1.71.10 (Apr 03, 2013)
 
[-] Fixed a crashing "heap" directive in 64-bit PE format.
 
 
version 1.71.09 (Mar 30, 2013)
 
[-] "use16","use32" and "use64" no longer allow to put another instruction in
the same line.
 
[-] Fixed a bug in parser that caused it to hang while processing some
specific ill-structured preprocessed lines.
 
[-] Modified memory allocation algorithm on Windows machines with large RAM.
 
 
version 1.71.08 (Mar 08, 2013)
 
[-] Fixed a bug that caused "irp" to skip processing a list with one empty
element when default value for iterating variable was specified.
 
 
version 1.71.07 (Dec 23, 2012)
 
[-] Fixed a bug that was causing "used" operator to give incorrect results
in some very specific cases.
 
 
version 1.71.06 (Nov 22, 2012)
 
[-] Fixed a few bugs caused by unnecesarily strong restrictions on allowed
types of relocatable values in some places (like "label" directive).
 
 
version 1.71.05 (Oct 15, 2012)
 
[-] Fixed a bug which caused "load" and "store" directives to sometimes
fail when assembler had preallocated very large amount of memory.
 
 
version 1.71.04 (Oct 10, 2012)
 
[-] Fixed another bug in "org" directive, which was causing it to deal
incorrectly with negative addresses.
 
 
version 1.71.03 (Sep 27, 2012)
 
[-] Fixed a bug in "org" directive introduced by recent changes, which
was manifesting with bases larger than 31-bit.
 
 
version 1.71.02 (Sep 26, 2012)
 
[-] Expression calculator now allows to calculate the difference of
relocatable addresses in a reverse order (first substracting/negating
and then adding the other one).
 
 
version 1.71.01 (Sep 23, 2012)
 
[+] Added support for ADX, RDSEED and SMAP instruction sets.
 
[-] Fixed the bugs related to creating a new addressing space inside the
virtual block with "org" directive.
 
 
version 1.71.00 (Sep 21, 2012)
 
[+] Added ability to define a special kind of label identifying the
addressing space. This label can the be used with "load" or "store"
directives to allow operations on bytes in any addressing space,
not just the current one. This special label is defined by following
its name with double colon, and can only be used with "load" and
"store" directive, where address can now be specified in two parts,
first the adressing space label, then the colon and then the
address inside that addressing space.
 
 
version 1.70.03 (Jun 29, 2012)
 
[-] Allowed to freely upgrade or downgrade the relocatable addresses in
object format between the 32-bit or 64-bit size.
 
 
version 1.70.02 (May 22, 2012)
 
[-] Corrected the optimization of segment prefixes when the extended syntax
of some string instructions ("cmps", "lods", "movs" and "outs") is
used in long mode. Now it is consistent with optimizations done with
all the other instructions.
 
 
version 1.70.01 (Apr 30, 2012)
 
[-] Corrected a recently introduced bug that caused some illegal
address expressions to cause an error prematurely during the
parsing stage.
 
 
version 1.70 (Apr 17, 2012)
 
[+] Added support for AVX, AVX2, AES, CLMUL, FMA, RDRAND, FSGSBASE, F16C,
FMA4, XOP, MOVBE, BMI, TBM, INVPCID, HLE and RTM instruction sets.
 
[+] Added half-precision floating point values support.
 
[+] Extended the syntax of "rept" directive to allow numerical expressions
to be calculated by preprocessor in its arguments.
 
[+] Added "large" and "NX" settings for PE format.
 
[+] Allowed PE fixups to be resolved anywhere in the generated executable.
 
[+] Allowed to specify branding value (use 3 for Linux) after the
"format ELF executable" setting.
 
[+] Added "intepreter", "dynamic" and "note" keywords for creation of
special segments in ELF executables.
 
[-] Fixed long mode opcode generator to allow absolute addresses to be
generated with "qword" keyword inside square brackets.
 
[-] Disallowed negative immediates with "int", "enter", "ret" instructions.
 
[+] Allowed symbolic information dump file to be created even in case of error.
In such case it contains only the preprocessed source that can be extracted
with PREPSRC tool. If error occured during preprocessing, only the source up
to the point of error is provided.
 
[+] Added symbol references table to symbolic dump file.
 
[-] Corrected the "defined" and "used" flags in the symbols dump to reflect the
state from the final assembly pass.
 
[+] Added "assert" directive.
 
[-] Formatter symbols like "PE" or "readable" are now recognized only in the
context of formatter directives, and thus are no longer disallowed as
labels.
 
[+] Macroinstruction argument now can have default value, defined with "="
symbol followed by value after the argument name in definition.
 
[+] Added "relativeto" operator, which can be used in logical expressions
to test whether two values differ only by a constant and not relocatable
amount.
 
[-] Revised the expression calculator, it now is able to correctly perform
calculations in signed and unsigned ranges in full 64-bit. This fixes
a number of issues - the overflow will now be correctly detected for
64-bit values in cases, where previous versions could not distinguish
whether it was an overflow or not. The effect of these corrections is
that "dq" directive will now behave consistently with behavior of the
data directives for smaller sizes, and the same applies to all the
places where "qword" size for value is used.
 
 
version 1.68 (Jun 13, 2009)
 
[+] Added SSSE3 (Supplemental SSE3), SSE4.1, SSE4.2 and SSE4a instructions.
 
[+] Added the AMD SVM and Intel SMX instructions.
 
[+] Added "rdmsrq", "wrmsrq", "sysexitq" and "sysretq" mnemonics for the
64-bit variants of respective instructions.
 
[+] Added "fstenvw", "fstenvd", "fsavew", "fsaved", "frstorw" and "frstord"
mnemonics to allow choosing between 16-bit and 32-bit variants of
structures used by the "fstenv", "fsave" and "frstor" instructions.
 
[+] Added "plt" operator for the ELF output format.
 
[+] Allowed "rva" operator to be used in MS COFF object format, and also
added "static" keyword for the "public" directive.
 
[+] Added Intel-style aliases for the additional long mode 8-bit registers.
 
[-] The PE formatter now automatically detects whether relocatable labels
should be used, depending on whether the fixups directory is placed
somewhere into executable by programer, or not. This makes possible the
more flexible use of the addressing symbols in case of PE executable fixed
at some position.
 
[-] Added support for outputting the 32-bit address relocations in case of
64-bit object formats and PE executable. This makes some specific
instructions compilable, but it also forces linker to put such
generated code into the low 2 gigabytes of addressing space.
 
[+] Added "EFI", "EFIboot" and "EFIruntime" subsystem keywords for PE format.
 
[-] Corrected the precedence of operators of macroinstruction line maker.
The symbol escaping now has always the higher priority than symbol conversion,
and both have higher precedence than concatenation.
 
[+] Allowed to check "@b" and "@f" symbols with "defined" operator.
 
[+] Allowed "as" operator to specify the output file extension when
placed at the end of the "format" directive line.
 
[-] Definition of macro with the same name as one of the preprocessor's directives
is no longer allowed.
 
[+] Allowed single quote character to be put inside the number value,
to help improve long numbers readability.
 
[+] Added optional symbolic information output, and a set of tools that extract
various kinds of information from it.
 
[+] Added "err" directive that allows to signalize error from the source.
 
 
version 1.66 (May 7, 2006)
 
[+] Added "define" directive to preprocessor, which defines symbolic constants,
the same kind as "equ" directive, however there's an important difference
that "define" doesn't process symbolic constants in the value before
assigning it. For example:
 
a equ 1
a equ a+a
 
define b 1
define b b+b
 
defines the "a" constant with value "1+1", but the "b" is defined with
value "b+b". This directive may be useful in some advanced
macroinstructions.
 
[-] Moved part of the conditional expression processing into parser,
for slightly better performance and lesser memory usage by assembler.
The logical values defined with "eq", "eqtype" and "in" operators are now
evaluated by the parser and if they are enough to determine the condition,
the whole block is processed accordingly. Thus this block:
 
if eax eq EAX | 0/0
nop
end if
 
is parsed into just "nop" instruction, since parser is able to determine
that the condition is true, even though one of the logical values makes no
sense - but since this is none of the "eq", "eqtype" and "in" expressions,
the parser doesn't investigate.
 
[-] Also the assembler is now calculating only as many logical values as it
needs to determine the condition. So this block:
 
if defined alpha & alpha
 
end if
 
will not cause error when "alpha" is not defined, as it would with previous
versions. This is because after checking that "defined alpha" is false
condition it doesn't need to know the second logical value to determine the
value of conjunction.
 
[+] Added "short" keyword for specifying jump type, the "jmp byte" form is now
obsolete and no longer correct - use "jmp short" instead.
 
[-] The size operator applied to jump no longer applies to the size of relative
displacement - now it applies to the size of target address.
 
[-] The "ret" instruction with 0 parameter is now assembled into short form,
unless you force using the 16-bit immediate with "word" operator.
 
[+] Added missing extended registers for the 32-bit addressing in long mode.
 
[+] Added "linkremove" and "linkinfo" section flags for MS COFF output.
 
[+] Added support for GOT offsets in ELF object formatter, which can be useful
when making position-independent code for shared libraries. For any label
you can get its offset relative to GOT by preceding it with "rva" operator
(the same keyword as for PE format is used, to avoid adding a new one,
while this one has very similar meaning).
 
[-] Changed ELF executable to use "segment" directive in place of "section",
to make the distinction between the run-time segments and linkable
sections. If you had a "section" directive in your ELF executables and they
no longer assemble, replace it with "segment".
 
[-] The PE formatter now always creates the fixups directory when told to -
even when there are no fixups to be put there (in such case it creates the
directory with one empty block).
 
[-] Some of the internal structures have been extended to provide the
possibility of making extensive symbol dumps.
 
[-] Corrected "fix" directive to keep the value intact before assigning it to the
prioritized constant.
 
[+] The ` operator now works with any kind of symbol; when used with quoted
string it simply does nothing. Thus the sequence of ` operators applied to
one symbol work the same as if there was just one. In similar manner, the
sequence of # operators now works as if it was a single one - using such a
sequence instead of escaping, which was kept for some backward
compatibility, is now deprecated.
 
[-] Corrected order of identifying assembler directives ("if db eq db" was
incorrectly interpreted as data definition).
 
[-] Many other small bugs fixed.
 
 
version 1.64 (Aug 8, 2005)
 
[+] Output of PE executables for Win64 architecture (with "format PE64"
setting).
 
[+] Added "while" and "break" directives.
 
[+] Added "irp" and "irps" directives.
 
[+] The macro arguments can be marked as required with the "*" character.
 
[-] Fixed checking for overflow when multiplying 64-bit values - the result
must always fit in the range of signed 64 integer now.
 
[-] Segment prefixes were generated incorrectly in 16-bit mode when BP was used
as a second addressing register - fixed.
 
[-] The "local" directive was not creating unique labels in some cases - fixed.
 
[-] The "not encodable with long immediate" error in 64-bit mode was sometimes
wrongly signaled - fixed.
 
[-] Other minor fixes and corrections.
 
 
version 1.62 (Jun 14, 2005)
 
[+] Escaping of symbols inside macroinstructions with backslash.
 
[+] Ability of outputting the COFF object files for Win64 architecture
(with "format MS64 COFF" setting).
 
[+] New preprocessor directives: "restruc", "rept" and "match"
 
[+] VMX instructions support (not documented).
 
[+] Extended data directives to allow use of the "dup" operator.
 
[+] Extended "struc" features to allow custom definitions of main structure's
label.
 
[-] When building resources from the the .RES file that contained more
than one resource of the same string name, the separate resource
directories were created with the same names - fixed.
 
[-] Several bugs in the ELF64 object output has been fixed.
 
[-] Corrected behavior of "fix" directive to more straightforward.
 
[-] Fixed bug in "include" directive, which caused files included from within
macros to be processed the wrong way.
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property