AMXXPawn编译器指令#emit

目录

1. 简介

#emit指令的作用:

该指令只能在函数体内使用。

需要提前了解的概念:

#emit指令的语法格式:

2. 操作码表格

操作码 操作数 说明
const.pri有pri=操作数
const.alt有alt=操作数
load.pri有pri=[操作数],常用于获取数据段变量的值
load.alt有alt=[操作数],常用于获取数据段变量的值
load.s.pri有pri=[frm+操作数],常用于获取栈变量的值(传引用形参的值是实参地址)
load.s.alt有alt=[frm+操作数],常用于获取栈变量的值(传引用形参的值是实参地址)
lref.pri有pri=[[操作数]]
示例:
dataVar = get_var_addr(anyVar);
#emit lref.pri dataVar // pri = anyVar
lref.alt有alt=[[操作数]]
示例:
dataVar = get_var_addr(anyVar);
#emit lref.alt dataVar // alt = anyVar
lref.s.pri有pri=[[frm+操作数]],常用于获取传引用形参所指实参的值
lref.s.alt有alt=[[frm+操作数]],常用于获取传引用形参所指实参的值
load.i无pri=[pri]
lodb.i有pri=[pri]{..操作数}
示例:
dataVar = 0x44332211
#emit const.pri dataVar // pri = get_var_addr(dataVar)
#emit lodb.i 2 // pri = 0x00002211
addr.pri有pri=frm+操作数,常用于获取栈变量绝对地址
addr.alt有alt=frm+操作数,常用于获取栈变量绝对地址
stor.pri有[操作数]=pri
stor.alt有[操作数]=alt
stor.s.pri有[frm+操作数]=pri,常用于对栈变量赋值
stor.s.alt有[frm+操作数]=alt,常用于对栈变量赋值
sref.pri有[[操作数]]=pri
示例:
dataVar = get_var_addr(anyVar);
#emit sref.pri dataVar // anyVar = pri
sref.alt有[[操作数]]=alt
示例:
dataVar = get_var_addr(anyVar);
#emit sref.alt dataVar // anyVar = alt
sref.s.pri有[[frm+操作数]]=pri,常用于对传引用形参所指实参赋值
sref.s.alt有[[frm+操作数]]=alt,常用于对传引用形参所指实参赋值
stor.i无[alt]=pri
strb.i有[alt]{..操作数}=pri{..操作数}
示例:
dataVar = 0x44332211;
#emit const.pri 0x88776655 // pri = 0x88776655
#emit const.alt dataVar // alt = get_var_addr(dataVar)
#emit strb.i 2 // dataVar = 0x44336655
lidx无pri=[alt+pri*cellsize]
示例:
dataArr[3] = 0xFF;
#emit const.alt dataArr // alt = get_var_addr(dataArr)
#emit const.pri 3 // pri = 3
#emit lidx // pri = 0xFF,3*cellsize等于12,指向第12个字节,也就是[3]号元素
idxaddr无pri=alt+pri*cellsize
lidx.b有pri=[alt+pri<<操作数]
示例:
dataArr[2] = 0xFF;
#emit const.alt dataArr // alt = get_var_addr(dataArr)
#emit const.pri 1 // pri = 1
#emit lidx.b 3 // pri = 0xFF,1<<3等于8,指向第8个字节,也就是[2]号元素
idxaddr.b有pri=alt+pri<<操作数
align.pri有pri^=cellsize-操作数,该结果于对齐并无帮助,意义不明
align.alt有alt^=cellsize-操作数,该结果于对齐并无帮助,意义不明
lctrl有pri=操作数所指寄存器的值(0=cod, 1=dat, 2=hea, 3=stp, 4=stk, 5=frm, 6=cip)
sctrl有操作数所指寄存器=pri(2=HEA, 4=stk, 5=frm, 6=cip)
move.pri无pri=alt
move.alt无alt=pri
xchg无交换pri和alt的值
push.pri无stk=stk-cellsize, [stk]=pri 栈地址前进并赋值
push.alt无stk=stk-cellsize, [stk]=alt 栈地址前进并赋值
push.r有操作数决定多次执行push.pri 栈地址连续前进并赋值
push.c有stk=stk-cellsize, [stk]=操作数 栈地址前进并赋值
push有stk=stk-cellsize, [stk]=[操作数] 栈地址前进并赋值
push.s有stk=stk-cellsize, [stk]=[frm+操作数] 栈地址前进并赋值
pushaddr有stk=stk-cellsize, [stk]=frm+操作数 栈地址前进并赋值
pop.pri无pri=[stk], stk=stk+cellsize 栈地址取值并后退
pop.alt无alt=[stk], stk=stk+cellsize 栈地址取值并后退
stack有stk=stk+操作数,栈地址后退
heap有hea=hea+操作数,堆指针前进
proc无stk=stk-cellsize, [stk]=frm, frm=stk 定义过程的开始
ret无返回
retn无返回并清理参数
call有调用操作数所指函数(不能是native/forward函数),经过测试,无法使用
call.pri无调用pri所指函数(不能是native/forward函数)
jump有向上跳转到操作数(Label标签)位置
jump.pri无跳转到pri所指地址
jzer有pri为0时跳转到操作数(Label标签)位置
jnz有pri不为0时跳转到操作数(Label标签)位置
jeq有pri==alt时跳转到操作数(Label标签)位置
jneq有pri!=alt时跳转到操作数(Label标签)位置
jless有pri<alt (无符号)时跳转到操作数(Label标签)位置
jsless有pri<alt时跳转到操作数(Label标签)位置
jleq有pri<=alt (无符号)时跳转到操作数(Label标签)位置
jsleq有pri<=alt时跳转到操作数(Label标签)位置
jgrtr有pri>alt (无符号)时跳转到操作数(Label标签)位置
jsgrtr有pri>alt时跳转到操作数(Label标签)位置
jgeq有pri>=alt (无符号)时跳转到操作数(Label标签)位置
jsgeq有pri>=alt时跳转到操作数(Label标签)位置
shl无pri<<=alt
shr无pri>>>=alt(无符号)
sshr无pri>>=alt
shl.c.pri有pri<<=操作数
shl.c.alt有alt<<=操作数
shr.c.pri有pri>>>=操作数
shr.c.alt有alt>>>=操作数
smul无pri*=alt
umul无pri*=alt (无符号)
sdiv无temp=pri%alt, pri/=alt, alt=temp
udiv无emp=pri%alt, pri/=alt, alt=temp (无符号)
sdiv.alt无temp=alt%pri, pri=alt/pri, alt=temp
udiv.alt无temp=alt%pri, pri=alt/pri, alt=temp (无符号)
add无pri+=alt
sub无pri-=alt
sub.alt无pri=alt-pri
and无pri&=alt
or无pri|=alt
xor无pri^=alt
not无pri=!pri
neg无pri=-pri
invert无pri=~pri
add.c有pri+=操作数
smul.c有pri*=操作数
zero.pri无pri=0
zero.alt无alt=0
zero有[操作数]=0
zero.s有[frm+操作数]=0
sign.pri无sign extend the byte in PRI to a cell
sign.alt无sign extend the byte in ALT to a cell
eq无pri=pri==alt
neq无pri=pri!=alt
less无pri=pri<alt (无符号)
sless无pri=pri<alt
leq无pri=pri<=alt (无符号)
sleq无pri=pri<=alt
grtr无pri=pri>alt (无符号)
sgrtr无pri=pri>alt
geq无pri=pri>=alt (无符号)
sgeq无pri=pri>=alt
eq.c.pri有pri=pri==操作数
eq.c.alt有alt=alt==操作数
inc.pri无pri++
dec.pri无pri--
inc.alt无alt++
dec.alt无alt--
inc有[操作数]++
dec有[操作数]--
inc.s有[frm+操作数]++
dec.s有[frm+操作数]--
inc.i无[pri]++
dec.i无[pri]--
movs有[alt]{..操作数}=[pri]{..操作数}
cmps有操作数决定在alt和pri地址连续比较多少个字节,pri储存返回值
fill有[alt..alt+操作数/4]=pri
halt有关闭游戏,据说操作数为0,据说退出码是pri
bounds有等同于:if (pri<0 || 操作数<pri) abort(AMX_ERR_BOUNDS, "")
sysreq.pri无调用pri所指native函数
sysreq.c有调用操作数所指native函数
switch有跳转到操作数所指case表
casetbl无case表标记
swap.pri无交换pri与stk
swap.alt无交换alt与stk
nop无无操作

3. 代码示例

修改变量值:

示例2:获取变量地址

更多内容请参考:AMX Assembly