Hướng dẫn入门 WebAssembly - WASM

Xin chào bạn, ngôi sao lập trình tương lai! Tôi rất vui mừng được làm hướng dẫn viên của bạn trong hành trình thú vị này vào thế giới của WebAssembly, hay简称 là WASM. Đừng lo lắng nếu bạn chưa bao giờ viết một dòng mã trước đây - chúng ta sẽ bắt đầu từ những điều cơ bản và cùng nhau học lên. Vậy, hãy lấy một ly đồ uống yêu thích của bạn, ngồi thoải mái, và cùng nhau lặn sâu vào!

WebAssembly - WASM

WebAssembly là gì?

WebAssembly giống như một ngôn ngữ bí mật mà các trình duyệt web hiểu. Nó được thiết kế để giúp các ứng dụng web chạy nhanh hơn và hiệu quả hơn. Hãy tưởng tượng bạn đang cố gắng chơi một trò chơi video phức tạp trên một trang web. Không có WebAssembly, trò chơi có thể chạy chậm và cồng kềnh. Nhưng với WebAssembly, nó có thể chạy mượt mà, gần như như bạn đang chơi trên một máy chơi game!

Lịch sử ngắn gọn

WebAssembly ra đời từ mong muốn làm cho các ứng dụng web mạnh mẽ hơn. Nó được công bố lần đầu tiên vào năm 2015, và đến năm 2017, nó đã được hỗ trợ bởi tất cả các trình duyệt web lớn. Điều này rất nhanh trong thế giới công nghệ - giống như cách nhanh chóng mà ứng dụng mạng xã hội yêu thích của bạn cập nhật với các tính năng mới!

Mô hình máy đống

Bây giờ, hãy nói về điều gì đó听起来 có vẻ kỹ thuật nhưng thực ra rất đơn giản khi bạn phá vỡ nó: mô hình máy đống. Đây là trái tim của cách WebAssembly hoạt động.

Đống là gì?

Hãy tưởng tượng một đống như một chồng đĩa. Bạn chỉ có thể thêm hoặc loại bỏ đĩa từ đỉnh của chồng. Trong thuật ngữ máy tính, chúng ta gọi việc thêm vào đống là "đẩy" và việc loại bỏ từ đống là "rút".

Cách WebAssembly sử dụng đống

WebAssembly sử dụng ý tưởng đống để thực hiện các thao tác. Nó giống như một đầu bếp rất hiệu quả trong nhà bếp, luôn biết chính xác thành phần (hoặc số, trong trường hợp của chúng ta) nào cần sử dụng tiếp theo.

Hãy xem một ví dụ đơn giản:

(module
(func $add (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add)
(export "add" (func $add))
)

Đừng hoảng hốt! Tôi biết rằng điều này trông như một ngôn ngữ ngoại星人 ngay bây giờ, nhưng hãy cùng nhau phân tích nó:

  1. (module): Điều này giống như nói " Đây là một cuốn sách công thức mới".
  2. (func $add ...): Chúng ta đang xác định một hàm mới (hoặc công thức)叫做 "add".
  3. (param $a i32) (param $b i32): Hàm của chúng ta nhận hai thành phần (tham số), cả hai đều là số nguyên 32-bit.
  4. (result i32): Kết quả cũng sẽ là một số nguyên 32-bit.
  5. local.get $a: Đặt số đầu tiên lên đỉnh của đống đĩa.
  6. local.get $b: Đặt số thứ hai lên đỉnh.
  7. i32.add: Cộng hai số ở đỉnh và thay thế chúng bằng kết quả.

Vậy, nếu chúng ta gọi hàm này với 5 và 3, đống của chúng ta sẽ trông như thế này:

  1. Bắt đầu với đống trống: []
  2. Sau local.get $a: [5]
  3. Sau local.get $b: [5, 3]
  4. Sau i32.add: [8]

Và voilà! Chúng ta đã cộng hai số bằng mô hình máy đống của WebAssembly.

Tại sao sử dụng WebAssembly?

Bạn có thể tự hỏi, "Điều này có vẻ phức tạp. Tại sao không chỉ sử dụng JavaScript?" Câu hỏi tuyệt vời! WebAssembly có một số siêu năng lực làm cho nó đặc biệt:

  1. Tốc độ: WebAssembly có thể chạy nhanh hơn JavaScript cho một số nhiệm vụ.
  2. Hiệu quả: Nó sử dụng ít bộ nhớ và năng lượng hơn.
  3. T灵活性 ngôn ngữ: Bạn có thể viết mã trong các ngôn ngữ như C++ hoặc Rust và chuyển đổi chúng thành WebAssembly.

Hãy tưởng tượng bạn đang xây dựng một lâu đài cát. JavaScript giống như việc sử dụng tay - nó linh hoạt và dễ bắt đầu. WebAssembly giống như việc có một bộ công cụ chuyên dụng - nó có thể mất một chút thời gian để thiết lập, nhưng bạn có thể xây dựng những lâu đài phức tạp và vững chắc hơn!

Chương trình WebAssembly đầu tiên của bạn

Hãy viết một chương trình đơn giản để cộng hai số. Chúng ta sẽ sử dụng một ngôn ngữ gọi là WAT (Định dạng Văn bản WebAssembly) mà là phiên bản dễ đọc của WebAssembly.

(module
(func $add (param $left i32) (param $right i32) (result i32)
local.get $left
local.get $right
i32.add)
(export "add" (func $add))
)

Điều này có thể trông quen thuộc - nó rất giống với ví dụ trước của chúng ta! Đây là những gì nó làm:

  1. Xác định một mô-đun (chương trình của chúng ta).
  2. Tạo một hàm叫做 $add nhận hai số nguyên 32-bit và trả về một số.
  3. Lấy số đầu tiên ($left) và đặt nó lên đống.
  4. Lấy số thứ hai ($right) và đặt nó lên đống trên cùng.
  5. Cộng hai số trên đống.
  6. Xuất hàm để chúng ta có thể sử dụng nó từ JavaScript.

Để sử dụng điều này trên một trang web, chúng ta cần một chút JavaScript:

fetch('add.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes))
.then(results => {
const add = results.instance.exports.add;
console.log(add(5, 3));  // Xuất: 8
});

Mã này tải mô-đun WebAssembly của chúng ta, tạo một thể hiện của nó, và sau đó gọi hàm add của chúng ta với số 5 và 3.

Kết luận

Chúc mừng! Bạn đã chính thức bước vào thế giới của WebAssembly. Chúng ta đã covered what WebAssembly is, how it uses a stack machine model, and even written our first WebAssembly program.

Remember, learning to code is like learning a new language or instrument – it takes practice and patience. Don't be discouraged if everything doesn't click right away. Keep experimenting, keep learning, and before you know it, you'll be building amazing things with WebAssembly!

In our next lesson, we'll dive deeper into more complex WebAssembly concepts and start building some really cool projects. Until then, happy coding!

WebAssembly Methods Description
local.get Retrieves a local variable or parameter
local.set Sets the value of a local variable
i32.add Adds two 32-bit integers
i32.sub Subtracts two 32-bit integers
i32.mul Multiplies two 32-bit integers
i32.div_s Signed division of two 32-bit integers
i32.rem_s Signed remainder of two 32-bit integers
i32.and Bitwise AND of two 32-bit integers
i32.or Bitwise OR of two 32-bit integers
i32.xor Bitwise XOR of two 32-bit integers
i32.shl Left shift of a 32-bit integer
i32.shr_s Signed right shift of a 32-bit integer
i32.eq Equality comparison of two 32-bit integers
i32.ne Inequality comparison of two 32-bit integers
i32.lt_s Signed less than comparison of two 32-bit integers

Credits: Image by storyset