/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/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/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 |