该指令只能在函数体内使用。
#emit 操作码 操作数
| 操作码 | 操作数 | 说明 |
|---|---|---|
| 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 | 无 | 无操作 |
public plugin_init()
{
// 所有全局/静态变量、字符串/数组/结构体字面量都是数据段变量
static dataV;
#emit const.pri 100 // pri=100
#emit stor.pri dataV // [dataV.address]=pri : dataV = 100
server_print("[AMXX]dataV : %d", dataV); // 显示dataV等于100
// 所有形参、局部new变量都是栈变量
new stackV;
#emit const.pri 200 // pri=200
#emit stor.s.pri stackV // [frm+stackV.offset]=pri : stackV = 200
server_print("[AMXX]stackV : %d", stackV); // 显示stackV等于200
}public plugin_init()
{
// 所有全局/静态变量、字符串/数组/结构体字面量都是数据段变量
static dataV;
#emit const.pri dataV // pri=dataV.address
#emit stor.pri dataV // [dataV.address]=pri
// 数据段地址比较靠近0,例如400
server_print("[AMXX]dataV.address : %d == %d", dataV, get_var_addr(dataV));
// 所有形参、局部new变量都是栈变量
new stackV;
#emit const.pri stackV // pri=stackV.offset
#emit stor.s.pri stackV // [frm+stackV.offset]=pri
// 第一个栈变量offset通常是-4,第一个形参offset应该是12
server_print("[AMXX]stackV.offset : %d", stackV);
#emit addr.pri stackV // pri=frm+stackV.offset
#emit stor.s.pri stackV // [frm+stackV.offset]=pri
// 栈地址通常破万,例如17016
server_print("[AMXX]stackV.address : %d == %d", stackV, get_var_addr(stackV));
}更多内容请参考:AMX Assembly