AMXXPawn编译器指令#emit

目录

1. 简介

#emit指令的作用:

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

需要提前了解的概念:

#emit指令的语法格式:

2. 操作码表格

操作码 操作数 说明
const.pripri=操作数
const.altalt=操作数
load.pripri=[操作数],常用于获取数据段变量的值
load.altalt=[操作数],常用于获取数据段变量的值
load.s.pripri=[frm+操作数],常用于获取栈变量的值(传引用形参的值是实参地址)
load.s.altalt=[frm+操作数],常用于获取栈变量的值(传引用形参的值是实参地址)
lref.pripri=[[操作数]]
示例:
dataVar = get_var_addr(anyVar);
#emit lref.pri dataVar // pri = anyVar
lref.altalt=[[操作数]]
示例:
dataVar = get_var_addr(anyVar);
#emit lref.alt dataVar // alt = anyVar
lref.s.pripri=[[frm+操作数]],常用于获取传引用形参所指实参的值
lref.s.altalt=[[frm+操作数]],常用于获取传引用形参所指实参的值
load.ipri=[pri]
lodb.ipri=[pri]{..操作数}
示例:
dataVar = 0x44332211
#emit const.pri dataVar // pri = get_var_addr(dataVar)
#emit lodb.i 2 // pri = 0x00002211
addr.pripri=frm+操作数,常用于获取栈变量绝对地址
addr.altalt=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
lidxpri=[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]号元素
idxaddrpri=alt+pri*cellsize
lidx.bpri=[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.bpri=alt+pri<<操作数
align.pripri^=cellsize-操作数,该结果于对齐并无帮助,意义不明
align.altalt^=cellsize-操作数,该结果于对齐并无帮助,意义不明
lctrlpri=操作数所指寄存器的值(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.pripri=alt
move.altalt=pri
xchg交换pri和alt的值
push.pristk=stk-cellsize, [stk]=pri 栈地址前进并赋值
push.altstk=stk-cellsize, [stk]=alt 栈地址前进并赋值
push.r操作数决定多次执行push.pri 栈地址连续前进并赋值
push.cstk=stk-cellsize, [stk]=操作数 栈地址前进并赋值
pushstk=stk-cellsize, [stk]=[操作数] 栈地址前进并赋值
push.sstk=stk-cellsize, [stk]=[frm+操作数] 栈地址前进并赋值
pushaddrstk=stk-cellsize, [stk]=frm+操作数 栈地址前进并赋值
pop.pripri=[stk], stk=stk+cellsize 栈地址取值并后退
pop.altalt=[stk], stk=stk+cellsize 栈地址取值并后退
stackstk=stk+操作数,栈地址后退
heaphea=hea+操作数,堆指针前进
procstk=stk-cellsize, [stk]=frm, frm=stk 定义过程的开始
ret返回
retn返回并清理参数
call调用操作数所指函数(不能是native/forward函数),经过测试,无法使用
call.pri调用pri所指函数(不能是native/forward函数)
jump向上跳转到操作数(Label标签)位置
jump.pri跳转到pri所指地址
jzerpri为0时跳转到操作数(Label标签)位置
jnzpri不为0时跳转到操作数(Label标签)位置
jeqpri==alt时跳转到操作数(Label标签)位置
jneqpri!=alt时跳转到操作数(Label标签)位置
jlesspri<alt (无符号)时跳转到操作数(Label标签)位置
jslesspri<alt时跳转到操作数(Label标签)位置
jleqpri<=alt (无符号)时跳转到操作数(Label标签)位置
jsleqpri<=alt时跳转到操作数(Label标签)位置
jgrtrpri>alt (无符号)时跳转到操作数(Label标签)位置
jsgrtrpri>alt时跳转到操作数(Label标签)位置
jgeqpri>=alt (无符号)时跳转到操作数(Label标签)位置
jsgeqpri>=alt时跳转到操作数(Label标签)位置
shlpri<<=alt
shrpri>>>=alt(无符号)
sshrpri>>=alt
shl.c.pripri<<=操作数
shl.c.altalt<<=操作数
shr.c.pripri>>>=操作数
shr.c.altalt>>>=操作数
smulpri*=alt
umulpri*=alt (无符号)
sdivtemp=pri%alt, pri/=alt, alt=temp
udivemp=pri%alt, pri/=alt, alt=temp (无符号)
sdiv.alttemp=alt%pri, pri=alt/pri, alt=temp
udiv.alttemp=alt%pri, pri=alt/pri, alt=temp (无符号)
addpri+=alt
subpri-=alt
sub.altpri=alt-pri
andpri&=alt
orpri|=alt
xorpri^=alt
notpri=!pri
negpri=-pri
invertpri=~pri
add.cpri+=操作数
smul.cpri*=操作数
zero.pripri=0
zero.altalt=0
zero[操作数]=0
zero.s[frm+操作数]=0
sign.prisign extend the byte in PRI to a cell
sign.altsign extend the byte in ALT to a cell
eqpri=pri==alt
neqpri=pri!=alt
lesspri=pri<alt (无符号)
slesspri=pri<alt
leqpri=pri<=alt (无符号)
sleqpri=pri<=alt
grtrpri=pri>alt (无符号)
sgrtrpri=pri>alt
geqpri=pri>=alt (无符号)
sgeqpri=pri>=alt
eq.c.pripri=pri==操作数
eq.c.altalt=alt==操作数
inc.pripri++
dec.pripri--
inc.altalt++
dec.altalt--
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表
casetblcase表标记
swap.pri交换pri与stk
swap.alt交换alt与stk
nop无操作

3. 代码示例

修改变量值:

示例2:获取变量地址

更多内容请参考:AMX Assembly