Nhiều máy ảo hiệu năng cao (như CPython, Lua, Dalvik) dùng mô hình thanh ghi thay vì ngăn xếp, với các lệnh số học dạng ba địa chỉ (three-address code): op dst, src1, src2 nghĩa là kết quả của phép toán trên hai thanh ghi nguồn được ghi thẳng vào thanh ghi đích, giúp giảm số lệnh di chuyển dữ liệu so với máy ảo ngăn xếp.
Xét một máy ảo thanh ghi với r thanh ghi đánh số 0,1,…,r−1 (khởi tạo giá trị 0) và một con trỏ lệnh PC (bắt đầu từ 0). Chương trình gồm n lệnh, đánh số 0,…,n−1 theo thứ tự, mỗi lệnh trên một dòng thuộc một trong các dạng sau (d, s, s1, s2 là chỉ số thanh ghi; k là hằng số nguyên):
LOADK d k: rd←k.MOVE d s: rd←rs.ADD d s1 s2 / SUB d s1 s2 / MUL d s1 s2: rd←rs1 op rs2.DIV d s1 s2: rd←rs1÷rs2 (chia lấy phần nguyên, làm tròn về 0; đảm bảo rs2=0 khi lệnh này thực thi).JMP off: PC được cộng thêm off (số nguyên, có thể âm) — tức PC ← PC + off — rồi tiếp tục (không cộng thêm 1 nữa).JZ r off: nếu rr=0 thì PC ← PC + off, ngược lại PC ← PC +1.PRINT r: in ra giá trị hiện tại của rr trên một dòng, rồi PC ← PC +1.HALT: dừng chương trình ngay lập tức.Với các lệnh không phải JMP/JZ/HALT, sau khi thực thi PC tự động tăng thêm 1. Chương trình dừng khi gặp HALT, hoặc khi PC nằm ngoài khoảng [0,n). Dữ liệu vào đảm bảo chương trình luôn dừng.
Ví dụ: chương trình LOADK 0 0, LOADK 1 5, LOADK 2 1, JZ 1 4, ADD 0 0 1, SUB 1 1 2, JMP -3, PRINT 0, HALT tính tổng 1+2+3+4+5 và in ra 15.
In ra, mỗi dòng một giá trị nguyên, kết quả của các lệnh PRINT theo đúng thứ tự được thực thi. Nếu không có lệnh PRINT nào được thực thi, không in gì.
Ví dụ:
Đầu vào:
9 3
LOADK 0 0
LOADK 1 5
LOADK 2 1
JZ 1 4
ADD 0 0 1
SUB 1 1 2
JMP -3
PRINT 0
HALT
Đầu ra:
15
Đầu vào:
4 3
LOADK 0 3
LOADK 1 4
ADD 2 0 1
PRINT 2
Đầu ra:
7
Đang tải editor...