Copyright: ISaGRAF V3.4


 IL指令集語言

IL (Instruction List，指令集語言) 是一種低階語言，它的指令一定關聯於目前結果 (或IL暫存器，IL register)。運算元顯示了目前數值與運算子之間的運算操作，而結果會再儲存在目前結果。

IL主要語法

IL運算元


IL主要語法

IL程式是一連串的指令。每一個指令必須撰寫在每一列的開始，而且必須包含一個運算元 (對於比較特別的運算必須包含修飾字)、一個或多個運算子 (以逗號 ',' 分隔開)。標籤及其冒號必須撰寫在指令前。假如指令有註解時，註解必須寫在一列的最後，而且必須啟始於 '(*'，終止於 '*)'。指令之間可以插入空的列。空的列可以加入註解。

標籤

運算元的修飾字

延遲運算

下面是指令列的範例：

標籤	運算符號	運算子	註解

Start:	LD	IX1	(* 按下按鍵 *)

ANDN	MX5	(* 指令沒有被禁止 *)

ST	QX2	(* 馬達開始運轉 *)


標籤

標籤 (label) 後必須緊接一個冒號 ':'，並且放在指令之前。標籤可以放在空的列。標籤可以當成是一些運算元的運算子，例如跳躍。標籤名稱必須遵循下面規則：

-	不能超過16個字元

-	第一個字元必須是英文字母

-	除了名稱的第一個字元之外，其他的字元必須是英文字母、阿拉伯數字或底線 ('_') 字元

相同的IL程式中，一個名稱只能給一個標籤使用。標籤和變數的名稱可以相同。


運算元的修飾字

下面列出一些運算元的修飾字 (modifier) 。有些運算元的名稱必須包含修飾字元，而且它們之間不包含空白字元：

N	運算子的布林反相

(	延遲執行

C	有條件的執行

'N' 修飾字顯示運算子的布林反相。例如，ORN IX12指令可以解釋成：result := result OR NOT (IX12)。

當指令遇見括弧 '(' 修飾字時，就會被延遲執行；直到遇見關閉的 ')' 括弧運算符號時，指令才會再繼續執行。

'C' 修飾字顯示相關的指令只有在目前結果是布林數值真 (TRUE，非布林型態時為非0數值) 時才必須執行。'C' 修飾字可以和 'N' 修飾字結合起來，表示指令只有在目前結果是布林數值假 (FALSE，非布林型態時為0) 時才必須執行。


延遲運算

因為只有一個IL暫存器 (目前結果)，所以某一些操作必須被延遲，以便執行順序或指令可以被改變。括弧可以用來顯示延遲執行：

'('	是一個修飾字	表示被延遲的操作

')'	是一個運算元	執行被延遲的操作

開啟括弧 '(' 修飾字顯示指令必須被延遲執行，直到遇見關閉括弧 ')' 運算符號時才再繼續執行。例如下面的程序：

AND(	IX12

OR	IX35

)

可以解釋為：

result := result AND ( IX12 OR IX35 )


IL運算元

下面表格集合了IL語言標準的運算元：

運算元	修飾字	運算子	描述

LD	N	變數，常數	載入運算子

ST	N	變數	儲存目前結果

S	布林變數	設定為真

R	布林變數	重置為假

CAL	C   N	功能方塊的樣例名稱	呼叫功能方塊

JMP	C   N	標籤	跳躍至標籤

RET	C   N	從副程式返回

 ) 	執行延遲運算

Function	呼叫函式或副程式

AND	N   (	布林	布林且 (boolean AND)

&	N   (	布林	布林且 (boolean AND)

OR	N   (	布林	布林或 (boolean OR)

XOR	N   (	布林	互斥或 (exclusive OR)

ADD	(	變數，常數	加

SUB	(	變數，常數	減

MUL	(	變數，常數	乘

DIV	(	變數，常數	除

GT	(	變數，常數	測試：大於 (>)

GE	(	變數，常數	測試：大於等於 (>=)

EQ	(	變數，常數	測試：等於 (=)

LE	(	變數，常數	測試：小於等於 (<=)

LT	(	變數，常數	測試：小於 (<)

NE	(	變數，常數	測試：不等於 (<>)

在下一個部分，只有IL語言的特殊運算符號會被描述，其他標準運算符號可以參考 "標準運算符號、功能方塊和函式" 部分。


LD運算元

運算：	載入一個數值給目前結果

允許的修飾字：	N

運算子：	常數形態

內部、輸入或輸出變數

範例：

(* LD運算範例 *)

LDex:	LD	false	(* 目前結果 := 假布林常數 *)

LD	true	(* 目前結果 := 真布林常數 *)

LD	123	(* 目前結果 := 整數常數 *)

LD	123.1	(* 目前結果 := 實數常數 *)

LD	t#3ms	(* 目前結果 := 時間常數 *)

LD	boo_var1	(* 目前結果 := 布林變數 *)

LD	ana_var1	(* 目前結果 := 類比變數 *)

LD	tmr_var1	(* 目前結果 := 計時器變數 *)

LDN	boo_var2	(* 目前結果 := NOT ( 布林變數 ) *)


ST運算元

運算：	將目前結果存入一個變數

此運算不會修改目前結果

允許的修飾字：	N

運算子：	內部或輸出變數

範例：

(* ST運算範例 *)

STboo:	LD	false

ST	boo_var1	(* boo_var1 := FALSE *)

STN	boo_var2	(* boo_var2 := TRUE *)

STana:	LD	123

ST	ana_var1	(* ana_var1 := 123 *)

STtmr:	LD	t#12s

ST	tmr_var1	(* tmr_var1 := t#12s *)


S運算元

運算：	假如目前結果是布林值真，就將布林值真存入一個布林變數。假如目前結果是布林值假，不會執行任何運算。此運算不會修改目前結果。

允許的修飾字：	無

運算子：	輸出或內部布林變數

範例：

(* S運算範例 *)

SETex:	LD	true	(* 目前結果 := TRUE *)

S	boo_var1	(* boo_var1 := TRUE *)

(* 目前結果不會被修改 *)

LD	false	(* 目前結果 := FALSE *)

S	boo_var1	(* 不會做任何事 - boo_var1不改變 *)


 R運算元

運算：	假如目前結果是布林值真，就將布林值假存入一個布林變數。假如目前結果是布林值假，不會執行任何運算。此運算不會修改目前結果。

允許的修飾字：	無

運算子：	輸出或內部布林變數

範例：

(* R運算範例 *)

RESETex:	LD	true	(* 目前結果 := TRUE *)

R	boo_var1	(* boo_var1 := FALSE *)

(* 目前結果不會被修改 *)

ST	boo_var2	(* boo_var2 := TRUE *)

LD	false	(* 目前結果 := FALSE *)

R	boo_var1	(* 不會做任何事 - boo_var1不改變 *)


 JMP運算元

運算：	跳躍至指定的標籤

允許的修飾字：	C   N

運算子：	標籤定義在同一個IL程式中

範例：

(* 下面的範例是用來測試類比選擇器 (0或1或2) 的數值 *)

(* 以便設定三個輸出布林值的其中之一。由JMPC運算元來決定 *)

(* 測試 "等於0" 的結果 *)

JMPex:	LD	selector	(* selector是0或1或2 *)

BOO	(* 轉換成布林型態 *)

JMPC	test1	(* if selector = 0 then *)

LD	true

ST	bo0	(* bo0 := true *)

JMP	JMPend	(* 程式結束 *)

test1:	LD 	selector

SUB	1	(* 將selector減為0或1 *)

BOO	(* 轉換成布林型態 *)

JMPC	test2	(* if selector = 0 then *)

LD	true

ST	bo1	(* bo1 := true *)

JMP	JMPend	(* 程式結束 *)

test2:	LD	true	(* 最後可能 *)

ST	bo2	(* bo2 := true *)

JMPend:	(* IL程式結束 *)


RET運算元

運算：	結束目前IL指令。假如IL程序是一個副程式，目前結果就回傳給呼叫程式。

允許的修飾字：	C   N

運算子：	無

範例：

(* 下面的範例是用來測試類比選擇器 (0或1或2) 的數值 *)

(* 以便設定三個輸出布林值的其中之一。由JMPC運算元來決定 *)

(* 測試 "等於0" 的結果 *)

JMPex:	LD	selector	(* selector是0或1或2 *)

BOO	(* 轉換成布林型態 *)

JMPC	test1	(* if selector = 0 then *)

LD	true

ST	bo0	(* bo0 := true *)

RET	(* 程式結束 - 傳回0 *)

(* 減少selector *)

test1:	LD 	selector

SUB	1	(* selector現在是0或1 *)

BOO	(* 轉換成布林型態 *)

JMPC	test2	(* if selector = 0 then *)

LD	true

ST	bo1	(* bo1 := true *)

LD	1	(* 載入實際selector值 *)

RET	(* 程式結束 - 傳回1 *)

(* 最後可能 *)

test2:	RETNC	(* 假如selector有一個有效的數值就回傳 *)

LD	true

ST	bo2	(* bo2 := true *)

LD	2	(* 載入實際selector值 *)

 	(* IL程式結束 - 傳回2 *)


")" 運算元

運算：	執行一個延遲執行。此延遲執行是以 '(' 通知的。

允許的修飾字：	無

運算子：	無

範例：

(* 下面程式插入了數個延遲執行： *)

(* res := a1 + (a2 * (a3 - a4) * a5) + a6; *)

Delayed:	LD	a1	(* 目前結果 := a1; *)

ADD(	a2	(* 延遲ADD，目前結果 := a2; *)

MUL(	a3	(* 延遲MUL，目前結果 := a3; *)

SUB	a4	(* 目前結果 := a3 - a4; *)

)	(* 執行延遲MUL，目前結果 := a2 * (a3-a4); *)

MUL	a5	(* 目前結果 := a2 * (a3 - a4) * a5; *)

)	(* 執行延遲ADD *)

(* 目前結果 := a1 + (a2 * (a3 - a4) * a5); *)

ADD	a6	(* 目前結果 := a1 + (a2 * (a3 - a4) * a5) + a6; *)

ST	res	(* 儲存目前結果到變數res *)


呼叫副程式或函式

假如在IL語言中呼叫副程式或函數 (以任何IL、ST、LD、FBD或 "C" 語言撰寫的) 時，使用副程式或函數的名稱作為運算元來使用。

運算：	執行副程式或函式 - 副程式或函式的回傳值會存入IL的目前結果

允許的修飾字：	無

運算子：	呼叫前，必須將第一個呼叫參數存入目前結果。剩下的參數被表示在運算子欄位中，並且以逗號分隔開。

範例：

(* 呼叫程式：將類比數值轉換成時間數值 *)

Main:	LD	bi0

SUBPRO	bi1,bi2	(* 呼叫副程式來得到類比數值 *)

ST	result	(* 副程式將數值傳回為目前結果 *)

GT	vmax	(* 測試數值是否溢位 *)

RETC	(* 假如溢位就回傳 *)

LD	result

MUL	1000	(* 將秒轉換成毫秒 *)

TMR	(* 轉換成時間 *)

ST	tmval	(* 儲存轉換值給計時器 *)

(* 被呼叫的副程式名稱為 'SUBPRO'：將副程式的三個布林輸入參數 *)

(* in0，in1，in2視為二元數值形態的類比數值，並且估算之*)

LD	in2

ANA	(* 目前結果 := ana (in2); *)

MUL	2	(* 目前結果 := 2*ana (in2); *)

ST	temporary	(* temporary := 目前結果 *)

LD	in1

ANA

ADD 	temporary	(* 目前結果 := 2*ana (in2) + ana (in1); *)

MUL	2	(* 目前結果 :=4*ana (in2) + 2*ana (in1); *)

ST	temporary	(* temporary := 目前結果 *)

LD	in0

ANA

ADD	temporary	(* 目前結果 := 4*ana(in2)+2*ana(in1)+ana(in0); *)

ST	SUBPRO	(* 回傳目前結果給呼叫程式 *)


呼叫功能方塊：CAL運算元

運算：	呼叫功能方塊

允許的修飾字：	C   N

運算子：	功能方塊樣例的名稱。

使用LD/ST運算程序呼叫方塊之前，方塊的輸入參數必須先指定。

假如要使用輸出參數，必須先知道參數名稱。

範例一：

(* 呼叫功能方塊SR：SR1是一個SR樣例 *)

LD	auto_mode

AND	start_cmd

ST	SR1.set1

LD	stop_cmd

ST	SR1.reset

CAL	SR1

LD	SR1.Q1

ST	command

(* FBD相等式：*)

範例二：

(* 假設R_TRIG1是一個R_TRIG方塊樣例，CTU1是一個CTU方塊樣例 *)

LD	command

ST	R_TRIG1.clk

CAL	R_TRIG1

LD	R_TRIG1.Q

ST	CTU1.cu

LDN	auto_mode

ST	CTU1.reset

LD	100

ST	CTU1.pv

CAL	CTU1

LD	CTU1.Q

ST	overflow

LD	CTU1.cv

ST	result

(* FBD相等式：*)