iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 16
1
Modern Web

謙虛,踏實的Web Assembly練習系列 第 16

[練習 15] 整理一下關於WebAssembly指令的文件

堆疊機

WebAssembly基本上是設計成一個基於堆疊的虛擬機,所以跟指令息息相關的就是堆疊的操作。這通常並不是直接用程式操作堆疊,而使每個指令的輸入與輸出,都是透過堆疊。傳參數給指令,是把值推入堆疊,然後指令根據需要從堆疊取出,最後再把結果推入堆疊。

不過,常常會碰到某個參數要先計算,某個後計算,然後才傳給指令等比較複雜的狀況,在腦袋裡直接推演目前這行程式的堆疊狀態有時會碰到困難。所以WebAssembly的文字格式,也支援S-Expression語法。S-Expression是用「前序式」的語法,括號之後接指令,指令之後接參數,先後計算的順序,可以透過括號來表達,這樣會比較清楚。

記憶體操作

載入

指令 參數 返回 說明
i32.load8_s (位址) i32 從記憶體載入1位元組資料,延伸成32位元有號整數
i32.load8_u (位址) i32 從記憶體載入1位元組資料,延伸成32位元無號整數
i32.load16_s (位址) i32 從記憶體載入2位元組資料,延伸成32位元有號整數
i32.load16_u (位址) i32 從記憶體載入2位元組資料,延伸成32位元無號整數
i32.load (位址) i32 從記憶體載入4位元組資料成為32位元整數
i64.load8_s (位址) i64 從記憶體載入1位元組資料,延伸成64位元有號整數
i64.load8_u (位址) i64 從記憶體載入1位元組資料,延伸成64位元無號整數
i64.load16_s (位址) i64 從記憶體載入2位元組資料,延伸成64位元有號整數
i64.load16_u (位址) i64 從記憶體載入2位元組資料,延伸成64位元無號整數
i64.load16_s (位址) i64 從記憶體載入4位元組資料,延伸成64位元有號整數
i64.load16_u (位址) i64 從記憶體載入4位元組資料,延伸成64位元無號整數
i64.load (位址) i64 從記憶體載入8位元組資料成為64位元整數
f32.load (位址) f32 從記憶體載入4位元資料成為32位元浮點數
f64.load (位址) f64 從記憶體載入8位元資料成為64位元浮點數

回存

指令 參數 返回 說明
i32.store8 (位址) (值) 把32位元整數包裝成1位元組存回記憶體
i32.store16 (位址) (值) 把32位元整數包裝成2位元組存回記憶體
i32.store (位址) (值) 把32位元整數包裝成4位元組存回記憶體
i64.store8 (位址) (值) 把64位元整數包裝成1位元組存回記憶體
i64.store16 (位址) (值) 把64位元整數包裝成2位元組存回記憶體
i64.store32 (位址) (值) 把64位元整數包裝成4位元組存回記憶體
i64.store (位址) (值) 把64位元整數包裝成8位元組存回記憶體
f32.store (位址) (值) 把32位元浮點數包裝成4位元組存回記憶體
f64.store (位址) (值) 把64位元浮點數包裝成8位元組存回記憶體

目前版本的WebAssembly使用i32來定址,所以能使用最大的記憶體只能到4GB。

記憶體設定與資訊

指令 參數 返回 說明
grow_memory (大小) 把記憶體大小增加指定的頁數(每頁64KB)
current_memory (頁數) 取得目前記憶體大小(單位:頁數)

變數操作

區域變數

指令 參數 返回 說明
get_local (名稱 or 索引) 變數值 取得指定變數的值
set_local (名稱 or 索引) (值) 設定變數值
tee_local (名稱 or 索引) (值) 設定的值 設定變數值並返回

整體變數

指令 參數 返回 說明
get_global (名稱 or 索引) 變數值 取得指定變數的值
set_global (名稱 or 索引) (值) 設定變數值

指定常數

指令 參數 返回 說明
i32.const (數值) 指定的數值 回傳指定數值的32位元整數常數
i64.const (數值) 指定的數值 回傳指定數值的64位元整數常數
f32.const (數值) 指定的數值 回傳指定數值的32位元浮點數常數
f64.const (數值) 指定的數值 回傳指定數值的64位元浮點數常數

運算

32位元整數

計算

指令 參數 返回 說明
i32.add (參數1) (參數2) 計算結果 計算參數1加上參數2的結果
i32.sub (參數1) (參數2) 計算結果 計算參數1減去參數2的結果
i32.mul (參數1) (參數2) 計算結果 計算參數1乘以參數2的結果
i32.div_s (參數1) (參數2) 計算結果 計算參數1除以參數2的結果(有號)
i32.div_u (參數1) (參數2) 計算結果 計算參數1除以參數2的結果(無號)
i32.rem_s (參數1) (參數2) 計算結果 計算參數1除以參數2的餘數(有號)
i32.rem_u (參數1) (參數2) 計算結果 計算參數1除以參數2的餘數(無號)

邏輯與位元運算

指令 參數 返回 說明
i32.and (參數1) (參數2) 計算結果 回傳兩個參數and運算結果
i32.or (參數1) (參數2) 計算結果 回傳兩個參數or運算結果
i32.xor (參數1) (參數2) 計算結果 回傳兩個參數xor運算結果
i32.shl (參數1) (參數2) 計算結果 回傳參數1向左移參數2所指定個位元的運算結果
i32.shr_s (參數1) (參數2) 計算結果 回傳參數1向右移參數2所指定個位元的運算結果(有號)
i32.shr_u (參數1) (參數2) 計算結果 回傳參數1向右移參數2所指定個位元的運算結果(無號)
i32.rotl (參數1) (參數2) 計算結果 回傳參數1向左旋轉參數2所指定個位元的運算結果
i32.rotr (參數1) (參數2) 計算結果 回傳參數1向右旋轉參數2所指定個位元的運算結果

比較運算

指令 參數 返回 說明
i32.eq (參數1) (參數2) 比較結果 參數1與參數2是否相等
i32.ne (參數1) (參數2) 比較結果 參數1與參數2是否不相等
i32.lt_s (參數1) (參數2) 比較結果 參數1是否小於參數2(有號)
i32.le_s (參數1) (參數2) 比較結果 參數1是否小於或等於參數2(有號)
i32.lt_u (參數1) (參數2) 比較結果 參數1是否小於參數2(無號)
i32.le_u (參數1) (參數2) 比較結果 參數1是否小於或等於參數2(無號)
i32.gt_s (參數1) (參數2) 比較結果 參數1是否大於參數2(有號)
i32.ge_s (參數1) (參數2) 比較結果 參數1是否大於或等於參數2(有號)
i32.gt_u (參數1) (參數2) 比較結果 參數1是否大於參數2(無號)
i32.ge_u (參數1) (參數2) 比較結果 參數1是否大於或等於參數2(無號)
i32.eqz (參數1) 比較結果 參數1為0時返回1,否則返回0

比較運算的結果,都是32位元整數,1代表true,0代表false

位元資訊

指令 參數 返回 說明
i32.clz (參數1) 結果 返回參數1作為二進位數字開頭的0的數目
i32.ctz (參數1) 結果 返回參數1作為二進位數字結尾的0的數目
i32.popcnt (參數1) 結果 返回參數1作為二進位數字中所有的1的數目

64位元整數

運算子跟32位元一樣。

32位元浮點數

32位元整數運算已經有的,這裡就不列出。IEEE754的浮點數是有帶號的,所以不會區分有號或無號的運算。

計算

指令 參數 返回 說明
f32.abs (參數1) 結果 將參數1改成正值
f32.neg (參數1) 結果 將參數1的符號反向(正->負,負->正)
f32.copysign (參數1) (參數2) 結果 將參數1的數值與參數2的符號合成結果
f32.ceil (參數1) 結果 將參數1無條件進位成整數
f32.floor (參數1) 結果 將參數1無條件捨味成整數
f32.trunc (參數1) 結果 將參數1的小數捨去,成為更趨近0的整數
f32.nearest (參數1) 結果 將參數1四捨五入
f32.sqrt (參數1) 結果 取得參數1的平方根
f32.min (參數1) (參數2) 結果 回傳較小的
f32.max (參數1) (參數2) 結果 回傳較大的

64位元浮點數

也都跟32位元浮點數一樣,只是是64位元運算。


整理差不多,剩下轉型用的指令,明天再看好了...


上一篇
[練習 14] global與start區段
下一篇
[練習 16] 繼續整理WebAssembly指令的文件
系列文
謙虛,踏實的Web Assembly練習20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言