📄 in_script.txt
字号:
space();
write_arg(0);
: 70 imm_rel:osz_old,imm_cc:8 ! o_is64,sx_yes
: 0f 80 imm_rel:osz_old,imm_cc:8 ! o_is64
# fixme -- why is this is64 ?
$ call ! ctrlxfer_yes
: e8 imm_rel:osz_old ! o_is64
# fixme -- why is this is64 ?
$ _calli ! ctrlxfer_yes
write("call");
space();
write_args();
: ff /2 mem_rm:osz ! o_is64
# check with bochs. Intel64 says _callf indirect can use 64 bit operand size, and this seems necessary, but amd64 docs do not indicate that it is allowed.
$ _callfd ! ctrlxfer_yes
write("call");
space();
write_far_imm();
: 9a imm_imm:osz,imm_imm:16 ! o_no64
$ _callfi ! ctrlxfer_yes
write("call");
space();
write_args();
: ff /3 mem_rm:osz_old.16 ! mod_mem
# should these be is64? does it even matter? see bochs. i think no because amd64 says it can be 8, 16, or 32 bits (even in 64 bit mode). is this
# accurate? is it relevant?
$ jmp ! ctrlxfer_yes
: e9 imm_rel:osz_old
: eb imm_rel:osz_old ! sx_yes
# fixme -- why is this is64 ?
$ _jmpi ! ctrlxfer_yes
write("jmp");
space();
write_args();
: ff /4 mem_rm:osz ! o_is64
# check with bochs. Intel64 says _jmpfd indirect can use 64 bit operand size, and this seems necessary, but amd64 docs do not indicate that it is allowed.
$ _jmpfd ! ctrlxfer_yes
write("jmp");
space();
write_far_imm();
: ea imm_imm:osz,imm_imm:16 ! o_no64
$ _jmpfi ! ctrlxfer_yes
write("jmp");
space();
write_args();
: ff /5 mem_rm:osz_old.16 ! mod_mem
# fixme -- why is this is64 ?
$ _retnum ! ctrlxfer_yes,size_none
write("ret");
space();
write_args();
: c2 imm_imm:16 ! o_is64
$ _ret ! ctrlxfer_yes,size_none
write("ret");
: c3 imm_implict8:16:0 ! o_is64
$ _retfnum ! ctrlxfer_yes,size_none
write("retf");
space();
write_args();
: ca imm_imm:16
$ _retf ! ctrlxfer_yes
write("retf");
: cb imm_implict8:16:0
$ _int3 ! ctrlxfer_yes
write("int3");
: cc void
$ int ! ctrlxfer_yes,size_none
: cd imm_imm:8
$ _iret ! ctrlxfer_yes
//write_size();
write("iret");
write_size_suffix(get_osz());
: cf void
# fixme -- why is this is64 ?
$ _loopnz ! ctrlxfer_yes
write("loopnz");
space();
write_arg(0);
: e0 imm_rel:osz,reg_r:asz:1 ! o_is64,sx_yes
# fixme -- why is this is64 ?
$ _loopz ! ctrlxfer_yes
write("loopz");
space();
write_arg(0);
: e1 imm_rel:osz,reg_r:asz:1 ! o_is64,sx_yes
# fixme -- why is this is64 ?
$ _loop ! ctrlxfer_yes
write("loop");
space();
write_arg(0);
: e2 imm_rel:osz,reg_r:asz:1 ! o_is64,sx_yes
# fixme -- why is this is64 ?
# Take note! address size distinguishes which opcode is used.
# Is it possible to use a REX with this and thus use ecx not rcx? find out, it matters! see bochs.
$ _jrcxz ! ctrlxfer_yes
write_size();
if(get_asz() == argsize_16)
write("jcxz");
else
if(get_asz() == argsize_32)
write("jecxz");
else
write("jrcxz");
space();
write_arg(0);
: e3 imm_rel:osz,reg_r:asz:1 ! o_is64,sx_yes
$ hlt
: f4 void
$ cli
: fa void
$ sti
: fb void
$ in ! size_none
: e4 reg_r:8:0,imm_imm:8
: e5 reg_r:osz_old:0,imm_imm:8
: ec reg_r:8:0,reg_r:16:2
: ed reg_r:osz_old:0,reg_r:16:2
$ out ! size_none
: e6 imm_imm:8,reg_r:8:0
: e7 imm_imm:8,reg_r:osz_old:0
: ee reg_r:16:2,reg_r:8:0
: ef reg_r:16:2,reg_r:osz_old:0
$ wait
: 9b void
#--------------------------------------------------------------------------------------------------
# --- 186+ things follow ---
#--------------------------------------------------------------------------------------------------
$ bsf ! size_same
: 0f bc /r reg_r:osz,mem_rm:osz
$ bsr ! size_same
: 0f bd /r reg_r:osz,mem_rm:osz
# -> bt dword [x],eax -- won't suppress 'dword'.
# -> bt dword [x],byte 3 -- won't suppress 'byte'.
$ bt
: 0f a3 /r mem_rm:osz,reg_r:osz
: 0f ba /4 mem_rm:osz,imm_imm:8
$ bts
: 0f ab /r mem_rm:osz,reg_r:osz ! fx_lockable
: 0f ba /5 mem_rm:osz,imm_imm:8 ! fx_lockable
$ btr
: 0f b3 /r mem_rm:osz,reg_r:osz ! fx_lockable
: 0f ba /6 mem_rm:osz,imm_imm:8 ! fx_lockable
$ btc
: 0f bb /r mem_rm:osz,reg_r:osz ! fx_lockable
: 0f ba /7 mem_rm:osz,imm_imm:8 ! fx_lockable
$ bswap
: 0f c8 reg_basecode:osz ! o_no16
$ cmpxchg ! size_same
: 0f b0 /r mem_rm:8,reg_r:8 ! fx_lockable
: 0f b1 /r mem_rm:osz,reg_r:osz ! fx_lockable
$ movzx
: 0f b6 /r reg_r:osz,mem_rm:8
: 0f b7 /r reg_r:osz_32,mem_rm:16
asgn(arg(0), zx$argsize_0(arg(1)));
$ movsx
: 0f be /r reg_r:osz,mem_rm:8
: 0f bf /r reg_r:osz_32,mem_rm:16
asgn(arg(0), sx$argsize_0(arg(1)));
# This instruction is valid only in protected mode.
# Not valid in 64-bit mode.
# arpl: valid only in protected mode. In real or vm86 mode it will #UD (int 6).
# arpl: in 64 bit mode this is movsxd, used with rex.w.
$ _arpl_movsxd
// This is probably not right. It's probably wired correctly for non-64-bit mode, need special code
// in the decode to make movsxd work right.
// Should abort if in 64-bit mode for now...
if(get_osz() == argsize_64)
write("movsxd");
else
write("arpl");
space();
write_args();
: 63 /r mem_rm:16,reg_r:16 ! o_sp64_movsxd
$ shld
: 0f a4 /r mem_rm:osz,reg_r:osz,imm_imm:8
: 0f a5 /r mem_rm:osz,reg_r:osz,reg_r:8:1
asgn(arg(0), _x86_shld(arg(0), arg(1), arg(2)));
asgn(x86_of, _x86_shld_of(arg(0), arg(1), arg(2)));
asgn(x86_sf, _x86_shld_sf(arg(0), arg(1), arg(2)));
asgn(x86_zf, _x86_shld_zf(arg(0), arg(1), arg(2)));
asgn(x86_af, _x86_shld_af(arg(0), arg(1), arg(2)));
asgn(x86_pf, _x86_shld_pf(arg(0), arg(1), arg(2)));
asgn(x86_cf, _x86_shld_cf(arg(0), arg(1), arg(2)));
$ shrd
: 0f ac /r mem_rm:osz,reg_r:osz,imm_imm:8
: 0f ad /r mem_rm:osz,reg_r:osz,reg_r:8:1
asgn(arg(0), _x86_shrd(arg(0), arg(1), arg(2)));
asgn(x86_of, _x86_shrd_of(arg(0), arg(1), arg(2)));
asgn(x86_sf, _x86_shrd_sf(arg(0), arg(1), arg(2)));
asgn(x86_zf, _x86_shrd_zf(arg(0), arg(1), arg(2)));
asgn(x86_af, _x86_shrd_af(arg(0), arg(1), arg(2)));
asgn(x86_pf, _x86_shrd_pf(arg(0), arg(1), arg(2)));
asgn(x86_cf, _x86_shrd_cf(arg(0), arg(1), arg(2)));
$ _cmpxchgxb ! size_none
// Is this right?
if(get_osz() == argsize_64)
write("cmpxchg16b");
else
write("cmpxchg8b");
space();
write_args();
: 0f c7 /1 mem_rm:osz_new ! fx_none_lockable,mod_mem,op66_no66
#: 66 0f c7 /1 mem_rm:osz_new ! fx_none_lockable,mod_mem,xasm_skip
# --- begin vmx instructions ---
$ vmxon
: f3 0f c7 /6 mem_rm:64 ! mod_mem,op66_no66
$ vmclear
: 66 0f c7 /6 mem_rm:64 ! fx_none,mod_mem
$ vmcall
: 0f 1 /0 void ! mod_3,rm_1
$ vmlaunch
: 0f 1 /0 void ! mod_3,rm_2
$ vmresume
: 0f 1 /0 void ! mod_3,rm_3
$ vmxoff
: 0f 1 /0 void ! mod_3,rm_4
$ vmptrld
: 0f c7 /6 mem_rm:64 ! fx_none,mod_mem,op66_no66
$ vmptrst
: 0f c7 /7 mem_rm:64 ! fx_none,mod_mem,op66_no66
$ vmread ! size_same
: 0f 78 /r mem_rm:osz_ptr,reg_r:osz_ptr ! fx_none,op66_no66
$ vmwrite ! size_same
: 0f 79 /r reg_r:osz_ptr,mem_rm:osz_ptr ! fx_none,op66_no66
# --- end vmx instructions ---
# FIXME--reportedly this is LOCKED. Fix it.
$ xadd ! size_same
: 0f c0 /r mem_rm:8,reg_r:8 ! fx_lockable
: 0f c1 /r mem_rm:osz,reg_r:osz ! fx_lockable
$ les ! size_none_dsz
: c4 /r reg_r:osz,mem_rm:osz.16 ! o_no64,mod_mem
$ lds ! size_none_dsz
: c5 /r reg_r:osz,mem_rm:osz.16 ! o_no64,mod_mem
$ lss ! size_none_dsz
: 0f b2 /r reg_r:osz_old,mem_rm:osz_old.16 ! mod_mem
$ lfs ! size_none_dsz
: 0f b4 /r reg_r:osz_old,mem_rm:osz_old.16 ! mod_mem
$ lgs ! size_none_dsz
: 0f b5 /r reg_r:osz_old,mem_rm:osz_old.16 ! mod_mem
# fixme -- why is this is64 ?
$ enter ! size_none
: c8 imm_imm:16,imm_imm:8 ! o_is64
# fixme -- why is this is64 ?
$ leave
: c9 void ! o_is64
# --- AMD says operand size prefix is always ignored.
$ sidt ! size_none_dsz
: 0f 1 /1 mem_rm:16.osz_24 ! mod_mem
$ lgdt ! size_none_dsz
: 0f 1 /2 mem_rm:16.osz_24 ! mod_mem
$ lidt ! size_none_dsz
: 0f 1 /3 mem_rm:16.osz_24 ! mod_mem
$ sldt
: 0f 0 /0 mem_rm:16 ! mod_mem
: 0f 0 /0 mem_rm:osz ! mod_3
$ smsw
: 0f 1 /4 mem_rm:16 ! mod_mem
: 0f 1 /4 mem_rm:osz ! mod_3
$ lmsw
: 0f 1 /6 mem_rm:16
# -> str word [bx+si] --- can't suppress size, here.
# -> str ax
$ str
: 0f 0 /1 mem_rm:16 ! mod_mem
: 0f 0 /1 mem_rm:osz ! mod_3
$ verr ! size_none
: 0f 0 /4 mem_rm:16
$ verw ! size_none
: 0f 0 /5 mem_rm:16
$ wbinvd
: 0f 9 void
$ wrmsr
: 0f 30 void
$ rdmsr
: 0f 32 void
$ rdpmc
: 0f 33 void
$ rdtsc
: 0f 31 void
$ clts
: 0f 6 void
$ cpuid
: 0f a2 void
$ invd
: 0f 8 void
# invlpg [x] is understood to be a byte atccess.
# --- do we really want size_none here? yes, nasm accepts e.g. invlpg [bx+si].
$ invlpg ! size_none,
: 0f 1 /7 mem_rm:8 ! mod_mem,ea_noaccess
$ lar ! size_same
: 0f 2 /r reg_r:osz,mem_rm:16
$ lldt ! size_none
: 0f 0 /2 mem_rm:16
$ lsl ! size_same
: 0f 3 /r reg_r:osz,mem_rm:osz
$ ltr ! size_none
: 0f 0 /3 mem_rm:16
$ _movcr ! size_same
write("mov");
space();
write_args();
: 0f 20 /r mem_rm:osz_ptr,reg_cr:osz_ptr ! mod_3
: 0f 22 /r reg_cr:osz_ptr,mem_rm:osz_ptr ! mod_3
$ _movdr ! size_same
write("mov");
space();
write_args();
: 0f 21 /r mem_rm:osz_ptr,reg_dr:osz_ptr ! mod_3
: 0f 23 /r reg_dr:osz_ptr,mem_rm:osz_ptr ! mod_3
$ sgdt ! size_none_dsz
: 0f 1 /0 mem_rm:16.osz_24 ! mod_mem
# take note.
# 0f 01 /0 edx is vmlaunch.
# e.g. sgdt edx/dx
# -- the multibyte nop does not alter the register and does not access memory at all. [[right??]
# 0f aa = rsm (???) [valid in smm only]
# 0f 0b = ud2
$ rsm
: 0f aa void
$ ud2
: 0f 0b void
# sysenter / sysexit ?? syscall / sysret ??
# the presence of these is indicated by certain cpuid bits which presumably we can just clear.
# also true for some form of cmpxchg i believe...
# sysenter : 0f 34
# sysexit : 0f 35
$ sysenter
: 0f 34 void
$ sysexit
: 0f 35 void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -