指標(pointer)是 MSM 語法支持的一種 定址方式,得以讓程式寫作的彈性更大,功能更完整!但因為牽涉到 記憶體位址 的觀念,初次接觸的人 可能會望而生畏.其實指標並不困難,只要把它想像成 陣列的別名 就好了!例如,有一個名為 A 的陣列,型態是 DINT,我們可以用下列的方式來取用它:
LACCL @A[10] ; 將 陣列第 10 個元素 載入 ACC 中
如果用 指標 的方式來寫,必須先取得 該陣列 的 開頭位址:
LALW #A ; AL <= 用”#” 取得 變數(或陣列) 的位址
SALW @AR0 ; AR0 <= AL , AR0 得到 陣列A 的開頭位址
之後,*AR0 就等於 陣列 A,可用來 存取 陣列A 任意元素的值:
LACCL *AR0[2] ; 等於寫 LACCL @A[2]
ADDL *AR0[5] ; 等於寫 ADDL @A[5]
SACCL *AR0[7] ; 等於寫 SACCL @A[7]
是不是很簡單呢?使用 指標 的過程歸納如下:
- 利用 “#” 取得變數(或陣列)的 記憶體位址
- 存放到 指標 ARn 內,n = 0 ~ 5
- ARn 前面加上 “*” 表示 指標 指向的 變數(或陣列) 的內容
或許使用者會有疑問?既然 指標 是 陣列 的另一種表示法(別名),那就直接用 陣列 就好,何必使用 指標 呢?這是因為有些場合,陣列 的 [索引值] 比較複雜,不容易表示.使用 指標 反而較容易.例如一個 X-Y-Z 的三軸機構,需要記憶 100 個位置點,我們宣告一個 陣列 POS 來儲存 三軸的位置資料,陣列的型態是 DINT,長度(元素個數)共有 300 個(100 點 × 3 軸).其資料格式如下圖所示:
如果想寫入 第 N 點 的 X,Y,Z 位置,若用 陣列 的寫法,發現 X,Y,Z 資料對應的 索引值 分別是 3N,3N+1,3N+2.寫起來並不容易!如果用 指標 來撰寫,可以把 AR0 指向第 N 點資料的 開頭位址,就是圖中的 #POS + 3N × 2 [註 1],然後把這裡當成一個 新的陣列 開頭,如此 X,Y,Z 的索引 簡化成 [0],[1],[2],就簡單多了,程式如下:
LACCW @N ; 指定 第 N 點資料
MULW 3 ; 共 3 軸 X,Y,Z
MULW 2 ; 一個 DINT 佔 2 WORD
ADDW #POS ; POS 陣列的 開頭位址
SALW @AR0 ; 存入指標中
; 下列程式碼 將目前三軸位置,分別存入陣列中
; 相當於 位置教導 功能
LACCL_SV V00h_FB_PUU,X_AXIS ; 讀取當前 X軸 位置
SACCL *AR0[0] ; 存入 第N點 X軸資料
LACCL_SV V00h_FB_PUU,Y_AXIS ; 讀取當前 Y軸 位置
SACCL *AR0[1] ; 存入 第N點 Y軸資料
LACCL_SV V00h_FB_PUU,Z_AXIS ; 讀取當前 Z軸 位置
SACCL *AR0[2] ; 存入 第N點 Z軸資料
所以,只要給定任意的 N,就能快速的存取到3軸的資料,是不是很方便呢?
參考資料:MSM 資料型態
[註 1] 記憶體位址 一律都是以 WORD為單位,本例 陣列的 資料型態 為 DINT(佔2WORD),所以:
資料的 絕對位址 = #POS + 索引值 × 2
同理,如果 陣列的型態為 INT,則上式改為 × 1
若 陣列的型態為 Real48,則上式改為 × 3